0
$\begingroup$

I am doing classificaion using random forest classifier in python (scikit learn). I have many different databases, each one has 33 observations and the prediction is based on 600 columns. The script is iteration which run the classifier and then create confusion matrix for each.

When I run the script it works but for some databases I get the next error message:

:25: RuntimeWarning: invalid value encountered in true_divide matrix = matrix.astype('float') / matrix.sum(axis=1)[:, np.newaxis]

also the results look weird: enter image description here

I understand that this might happen if I have Null values in my data, but I have used dropna to make sure that there are no null values:

df=df.dropna(axis=0,how='any')

This is my script for the confusion matrix iteration:

for h in dfch:
    print('Hour:',h)
    print('')
    list_dates=dfch[h]['date'].unique()
#     print(h)
#     print(list_dates)
    for d in list_dates:
        print('date:',d)
        print('hour:',h)
        dfhd=dfch[h]
        dfhd=dfhd.loc[dfhd['date']==d]
        print('database size for hour',h,'date',d,'is',len(dfhd))
        X=dfhd.iloc[:, 4:]
        y=dfhd.iloc[:,2:3]
        #split the data
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
        #reshape the y_train to fit the the model
        y_train=y_train.values.ravel()
        #fit the model
        rfc.fit(X_train,y_train)
        rfc_pred=rfc.predict(X_test)
        print('')
        # Get and reshape confusion matrix data
        matrix = confusion_matrix(y_test, rfc_pred)
        matrix = matrix.astype('float') / matrix.sum(axis=1)[:, np.newaxis]
        # Build the plot
        plt.figure(figsize=(16,7))
        sns.set(font_scale=1.4)
        sns.heatmap(matrix, annot=True, annot_kws={'size':10},cmap=plt.cm.Greens, linewidths=0.2)
        # Add labels to the plot
        class_names = ['high','medium','low']
        tick_marks = np.arange(len(class_names))
        tick_marks2 = tick_marks + 0.5
        plt.xticks(tick_marks, class_names, rotation=25)
        plt.yticks(tick_marks2, class_names, rotation=0)
        plt.xlabel('Predicted label')
        plt.ylabel('True label')
        plt.title('Confusion Matrix for Random Forest Model')
        plt.show()


        score=rfc.score(X_test,y_test)

My question : How can it happen that it will be divided in 0/null? (there is no null in the databases), and how does it still display the confusion matrix if it fails due to dividing by 0? How canI solve it?

$\endgroup$

1 Answer 1

1
$\begingroup$

Most probably, sum across one of the rows is coming out as zero in this code

matrix = matrix.astype('float') / matrix.sum(axis=1)[:, np.newaxis]

It is throwing a runtime warning and only that particular cell will be np.inf. Rest all division will be fine. That's why the plot is showing some data.

You may see the same in this sample code

import numpy as np
matrix = np.array([[1, 2, 3, 0, -6],[6, 7, 8, -4, 10]]) #Sum zero for 1st row

matrix.astype('float') / matrix.sum(axis=1)[:, np.newaxis]

/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:4: RuntimeWarning: invalid value encountered in true_divide after removing the cwd from sys.path.
array([[ inf, inf, inf, nan, -inf],
[ 0.22222222, 0.25925926, 0.2962963 , -0.14814815, 0.37037037]])

As a solution, you should add a constant in the denominator.1 will be best

import numpy as np
matrix = np.array([[1, 2, 3, 0, -6],[6, 7, 8, -4, 10]]) #Sum zero for 1st row

matrix.astype('float') / (matrix.sum(axis=1)[:, np.newaxis] + 1)
$\endgroup$
2
  • $\begingroup$ thanl you for your answer, now I don't get this error, but just to understand- before I add the +1, I got the results in percentage , now I get it as count, the error was because the sum of the column was 0 ? (like it didn't predicted some values at all?) how add +1 changed it? $\endgroup$
    – Reut
    Commented Jun 24, 2020 at 11:09
  • 1
    $\begingroup$ I mainly answered the text you wrote at the end. In the confusion matrix, you don't have any data for class "100"...So the full row is zero. that "+1" approach was a work-around to catch the error. Ideally, you should place a check on the count before creating the confusion matrix. I doubt that now it is coming as count. It will be still a percentage $\endgroup$
    – 10xAI
    Commented Jun 24, 2020 at 11:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.