如何修复此分类报告警告?



我创建了一个多类分类的模型。一切都很顺利,验证准确率为84%,但当我打印分类报告时,我收到了这个警告:

UndefinedMetricWarning: 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.
_warn_prf(average, modifier, msg_start, len(result))

分类报告:

precision    recall  f1-score   support
0       0.84      1.00      0.91     51890
1       0.67      0.04      0.08      8706
2       0.00      0.00      0.00      1605
accuracy                           0.84     62201
macro avg       0.50      0.35      0.33     62201
weighted avg       0.79      0.84      0.77     62201

源代码-

import pandas as pd
df=pd.read_csv('Crop_Agriculture_Data_2.csv')
df=df.drop('ID',axis=1)
dummies=pd.get_dummies(df[['Crop_Type', 'Soil_Type', 'Pesticide_Use_Category', 'Season']],drop_first=True)
df=df.drop(['Crop_Type', 'Soil_Type', 'Pesticide_Use_Category', 'Season'],axis=1)
df=pd.concat([df,dummies],axis=1)
df['Crop_Damage']=df['Crop_Damage'].map({'Minimal Damage':0,'Partial Damage':1,'Significant Damage':2})
x=df.drop('Crop_Damage',axis=1).values
y=df.Crop_Damage.values
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y,train_size=0.3,random_state=101)
from sklearn.preprocessing import MinMaxScaler
mms=MinMaxScaler()
x_train=mms.fit_transform(x_train)
x_test=mms.transform(x_test)
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,Flatten
model=Sequential()
model.add(Flatten())
model.add(Dense(10,activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(6,activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(3,activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
model.fit(x_train,y_train,validation_data=(x_test,y_test),epochs=13)
import numpy as np
pred=np.argmax(model.predict(x_test),axis=-1)
from sklearn.metrics import classification_report
print(classification_report(y_test,pred))

我认为这可能是因为大多数数据都在一个类别中,但我不确定。我能做些什么来解决这个问题吗?

正如desternaut所说,你有一个警告

此警告告诉您,classification_report输出受到影响,因为您的模型从未预测过其中一个标签(在您的情况下,标签为"2")。

这将产生计算Precision(除以0)的问题,因为(true positives + false positives =0)当函数处理此问题时,自动输出0。注意,这不是实际值,它应该是"未定义"。或者类似的东西,但这是他的方法。正如您所看到的,当您计算宏平均值时,您使用的是这个计算出来的0。所以误差只是提醒你宏观平均受"假"影响

0。F1-score也是如此,因为它是从Precision开始计算的。

如何解决?从技术上讲,你没有什么需要解决的因为这不是一个错误,所以你可以处理它。但是你必须意识到你的输出会受到影响。

你可以做的是,决定你对没有预测的标签的分数不感兴趣,然后显式指定你感兴趣的标签(这些标签至少被预测过一次):

print(classification_report(y_test,pred,labels=np.unique(y_pred))

请注意,这个解决方案一点也不好,因为它隐藏了你的模型和数据的问题,但在某些情况下它是有用的。

此外,正如Yefet所说,你的模型似乎在分类标签"2"因为你有一个不平衡数据。按照他的建议,如果可以的话,改进你的模型。

你不想去掉这个警告,因为它说你的类2不在预测中,因为训练集中没有样本

你有一个不平衡分类问题,类2的样本数量非常少,它只存在于测试数据中

我建议你做两件事

StratifiedKFold所以当你将训练和测试分开时,它会考虑所有的类

过采样你可能需要通过随机重新采样训练数据集来调整你的数据,以复制少数类的示例

如果你只是想摆脱警告,即使知道它隐藏的问题,你可以使用zero_division参数。

根据文档:

zero_division:"警告",0或1,默认="警告">

设置除零时返回的值。如果设置为" warn ",它充当0,但也会引发警告。

所以你可以隐藏警告而不用改变分类报告的结果:

print(classification_report(y_test,pred, zero_division=0))

我遇到了同样的问题,上面提出的解决方案起作用了:

classification_report(y_test, y_pred, labels=np.unique(y_pred))

但是在彻底检查数据之后,我得出结论,我的数据中的一些列太大,需要缩放/规范化。

因此,在代码中添加以下缩放可以提供更好的结果(至少在我的情况下)。

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

最新更新