import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import sklearn.metrics as metrics

data = pd.read_csv('../input/mobile-price-classification/train.csv')
data.head()

data.columns

"""
Explanation: Classification
So far you've predicted numeric targets. This type of modeling is called regression, hence the "Regressor" part of RandomForestRegressor.
Another common problem you'll see is making a choice between mutually exclusive outcomes. For example, spam detection is predicting whether an email is "spam" or "not spam" based on the email's content. This type of modeling is called classification.
There are two types of classification: 
- binary (choosing between two classes) and 
- multiclass (choosing between more than two classes). 
In general there are different approaches to the two types of classification, but most multiclass models will also work for binary problems.
It's straightforward to build classification models using what you already know about scikit-learn. Instead of RandomForestRegressor, you will use RandomForestClassifier. 
As an example of classification with RandomForestClassifier, we'll use a dataset of phone features to predict a phone's price range. The targets in the data have values:

0 (low cost)
1 (medium cost)
2 (high cost)
3 (very high cost)

The features are things like

battery_power: Total energy a battery can store in one time measured in mAh
blue: Has bluetooth or not
clock_speed: speed at which microprocessor executes instructions
dual_sim: Has dual sim support or not
fc: Front Camera mega pixels
four_g: Has 4G or not
....

Here is a quick overview of the data
End of explanation
"""


# Set variables for the targets and features
y = data['price_range']
X = data.drop('price_range', axis=1)

# Split the data into training and validation sets
train_X, val_X, train_y, val_y = train_test_split(X, y, random_state=7)

"""
Explanation: We create our feature and targets the same as before using train_test_split. This part looks like what you've already seen.
End of explanation
"""


# Create the classifier and fit it to our training data
model = RandomForestClassifier(random_state=7, n_estimators=100)
model.fit(train_X, train_y)

"""
Explanation: Creating and fitting the model is similar to what you've done before, except you'll use RandomForestClassifier instead of RandomForestRegressor.
End of explanation
"""


# Predict classes given the validation features
pred_y = model.predict(val_X)

# Calculate the accuracy as our performance metric
accuracy = metrics.accuracy_score(val_y, pred_y)
print("Accuracy: ", accuracy)

"""
Explanation: The simplest metric for classification models is the accuracy, the fraction predictions that are correct. Scikit-learn provides metrics.accuracy_score to calculate this.
End of explanation
"""


# Calculate the confusion matrix itself
confusion = metrics.confusion_matrix(val_y, pred_y)
print(f"Confusion matrix:\n{confusion}")


# Normalizing by the true label counts to get rates
print(f"\nNormalized confusion matrix:")
for row in confusion:
    print(row / row.sum())

"""
Explanation: Confusion Matrix
Our model did pretty well, correctly predicting around 86% of the price ranges in the validation data. It's often useful to look at where the model is failing with a confusion matrix which shows us how our model classified the inputs.
End of explanation
"""


probs = model.predict_proba(val_X)
print(probs)

"""
Explanation: It's a little easier to understand as a nice little figure like so:
<img src="https://i.imgur.com/idD0k8y.png" alt="example confusion matrix" width=400px>
The rows of the confusion matrix are the true class and the columns are the predicted class. The diagonal tells us how many of each class the model predicted correctly. The off-diagonals show where the model is making wrong predictions, where it is "confused."
For example, looking at the first column and second row, we classified four phones that were actually medium cost (true label: 1) as low cost (predicted label: 0). We see for classes 0 and 3, the low cost and highest cost phones, our model works really well, above 90% accurate. However, our model is weaker for medium and high cost phones. Note that incorrect predictions are only between adjacent classes. The model doesn't confuse low cost and very high cost phones.
Class probabilities
Classification models actually calculate a probability distribution over the classes. Using model.predict simply returns the class with the highest probability. This might not be ideal based on how the decision affects your metrics or downstream measures. To get the probabilities themselves, use the .predict_proba method.
End of explanation
"""


