My model is predicting values ​for only two labels (instead of 9) how to fix it?

Viewed 48

My goal is to predict the count (variable y) based on various features (variable x). My y is most of the time (98.4%) equal to 0, so this data is inflated by 0.

Based on this premise, I thought that using the Zero Inflated Model with SVC could be an asset, given the characteristics of my data.

So I found a code on the internet and i'm trying to apply it to my problem (i'm very new to this)

from sklego.meta import ZeroInflatedRegressor

zir = ZeroInflatedRegressor(
    classifier=SVC(),
    regressor=LinearRegression()
)

zir.fit(scaled_train, y_train.values.ravel())

predictions  = zir.predict(scaled_test)

I believe my problem is exactly in this part of the code below, where I am appending only 0s and 1s. However, how do I make predictions for the other counts? This is what I'm not able to understand.

trashold = .5
preds =[]
for  val in predictions:
    if val>trashold:
        preds.append(1)
    else:
        preds.append(0)

accuracy_score(y_test,preds)
0.9976208095270875

Even in my classification_report I have an alert precisely because I don't have samples for the other labels. How to fix such a problem?

print(classification_report(y_test,preds))

Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.

              precision    recall  f1-score   support

         0.0       1.00      1.00      1.00    916493
         1.0       0.86      0.97      0.91     11398
         2.0       0.00      0.00      0.00      1498
         3.0       0.00      0.00      0.00       231
         4.0       0.00      0.00      0.00        73
         5.0       0.00      0.00      0.00        22
         6.0       0.00      0.00      0.00         5
         7.0       0.00      0.00      0.00         5
         8.0       0.00      0.00      0.00         2
         9.0       0.00      0.00      0.00         1

    accuracy                           1.00    929728
   macro avg       0.19      0.20      0.19    929728
weighted avg       1.00      1.00      1.00    929728

To illustrate my problem, I have the following image. Which shows that 0 values ​​are reasonably well predicted, but from 1 I don't have any predictions anymore.

plt.clf()
plt.hist([y_train.values, preds], log=True)
plt.legend(('orig','pred'))
plt.show()

enter image description here

Any idea how I can improve this model and have predictions for all classes? Thank you very much in advance.


EDIT 1 - Based on Alex Comments

I tried to implement Alex's suggestions on a subset of the data.

df_count = df.groupby(['count']).size().to_frame(name = 'size').reset_index()
df_count

count   size
0.0     859225
1.0     9208
2.0     1224
3.0     180
4.0     59
5.0     3
6.0     3
7.0     2
8.0     1


zir = ZeroInflatedRegressor(
    classifier=SVC(),
    regressor=LinearRegression()
)

zir.fit(scaled_train, y_train.values.ravel())

predictions  = zir.predict(scaled_test)

As indicated, I switched the assessment measure to the MSE

mean_squared_error(y_test['count'].values,predictions)
0.0033405170885248804

I made a new plot of this data subset, which demonstrates that the model has some success in predicting when there are counts of up to 3. for counts greater than 3, as the sample is very small, the model has difficulty in making predictions.

plt.clf()
plt.hist([y_test['count'].values, predictions], log=True)
plt.legend(('real','predction'))
plt.show()

enter image description here

0 Answers
Related