[英]How to fix this classification report warning?
我為多類分類創建了一個 model。 一切順利,驗證准確率為 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))
我認為這可能是因為大多數數據都屬於一個類別,但我不確定。 我能做些什么來解決這個問題嗎?
您不想擺脫此警告,因為它表示您的 class 2 不在預測中,因為訓練集中沒有樣本
您遇到了不平衡分類問題,並且 class 2 的樣本數量非常少,並且僅存在於測試數據中
我建議你兩件事
StratifiedKFold因此,當您拆分訓練和測試時,它會考慮所有類
過度采樣您可能需要通過隨機重新采樣訓練數據集來調整數據,以復制少數 class 中的示例
正如desternaut所說,你有一個警告,而不是一個錯誤。
此警告是說您的classification_report
報告 output 受到影響,因為從未為您的 model 預測標簽之一(在您的情況下,label“2”)。
這將產生計算精度(除以 0)的問題,因為( true positives + false positives =0
)。 當 function 處理這個問題時,自動 output 0。注意這不是真正的值,它應該是“未定義”或類似的東西,但這是他的方法。 如您所見,當您計算宏平均值時,您使用的是計算得出的 0。因此該錯誤只是提醒您宏平均值受到“假”0 的影響。
F1-score 也是如此,因為它是從 Precision 開始計算的。
如何解決? 好吧,從技術上講,您無需解決任何問題,因為這不是錯誤,因此您可以處理它。 但是您必須意識到您的 output 正在受到影響。
您可以做的是確定您對未預測的標簽分數不感興趣,然后明確指定您感興趣的標簽(這些標簽至少被預測過一次):
print(classification_report(y_test,pred,labels=np.unique(y_pred))
請注意,此解決方案根本不好,因為它隱藏了您的 model 和數據的問題,但在某些情況下它可能很有用。
此外,正如Yefet所說,您的 model 似乎在將 label 分類為“2”時存在問題,因為您的數據不平衡。 如果可以,請按照他的建議改進您的 model。
如果您只想擺脫警告,即使知道它隱藏了問題,您可以使用zero_division
參數。
根據文檔:
zero_division: “警告”,0或1,默認=“警告”
設置零除法時要返回的值。 如果設置為“警告”,則此值為 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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.