使用scikit-learn来分类二元问题。获得了完美的classification_report
(全是1)。然而预测结果却只有0.36
。这是怎么回事?
我对标签不平衡的情况很熟悉。但我认为这里不是这种情况,因为f1
和其他分数列,以及混淆矩阵,都显示了完美的分数。
# 预留最后19行用于预测X1, X_Pred, y1, y_Pred = train_test_split(X, y, test_size= 19, shuffle = False, random_state=None)X_train, X_test, y_train, y_test = train_test_split(X1, y1, test_size= 0.4, stratify = y1, random_state=11)clcv = DecisionTreeClassifier()scorecv = cross_val_score(clcv, X1, y1, cv=StratifiedKFold(n_splits=4), scoring= 'f1') # 平衡精确度/召回率clcv.fit(X1, y1)y_predict = clcv.predict(X1)cm = confusion_matrix(y1, y_predict)cm_df = pd.DataFrame(cm, index = ['0','1'], columns = ['0','1'] )print(cm_df)print(classification_report( y1, y_predict ))print('Prediction score:', clcv.score(X_Pred, y_Pred)) # 未见数据
输出:
confusion: 0 10 3011 01 0 44 precision recall f1-score support False 1.00 1.00 1.00 3011 True 1.00 1.00 1.00 44 micro avg 1.00 1.00 1.00 3055 macro avg 1.00 1.00 1.00 3055weighted avg 1.00 1.00 1.00 3055Prediction score: 0.36
回答:
问题在于你出现了过拟合现象。
有很多未使用的代码,所以我们来修剪一下:
# 预留最后19行用于预测X1, X_Pred, y1, y_Pred = train_test_split(X, y, test_size= 19, shuffle = False, random_state=None)clcv = DecisionTreeClassifier()clcv.fit(X1, y1)y_predict = clcv.predict(X1)cm = confusion_matrix(y1, y_Pred)cm_df = pd.DataFrame(cm, index = ['0','1'], columns = ['0','1'] )print(cm_df)print(classification_report( y1, y_Pred ))print('Prediction score:', clcv.score(X_Pred, y_Pred)) # 未见数据
显然,这里没有进行交叉验证,低预测分数的最明显原因是决策树分类器的过拟合。
使用交叉验证的分数,你应该能直接看到问题所在。