linyifeng117 2023-03-16 21:13 采纳率: 50%
浏览 64
已结题

python绘制的ROC曲线与结果不符

python进行XGBoost分析多分类问题时,采用precision、recall、f1-macro、f1-weighted和test score来评价模型并绘制ROC曲线。
结果是以上评价指标都是1,但是ROC曲线并不符合评价指标的结果,并出现了以下错误:

img


请问我要如何解决这个问题?
完整的代码如下:


```python
from xgboost import XGBClassifier
from xgboost import plot_importance
import pandas as pd
from sklearn.model_selection import KFold, cross_val_score as CVS, train_test_split 
from sklearn import metrics
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import GridSearchCV
import numpy as np
from sklearn.metrics import precision_score, recall_score, f1_score,roc_curve, auc
from sklearn.preprocessing import label_binarize


#读取数据和标签
X = pd.read_excel("C:/Users/linyifeng/Desktop/data/SVM/freq_data.xlsx",sheet_name='train_x')
y = pd.read_excel("C:/Users/linyifeng/Desktop/data/SVM/freq_data.xlsx",sheet_name='train_y')
y = y.values.ravel()
#将数据分为训练集、验证集和一部分测试集
X_trainval,X_test,y_trainval,y_test = train_test_split(X,y,test_size=0.2,random_state=777)
le = LabelEncoder()
y_trainval = le.fit_transform(y_trainval)
y_test = le.fit_transform(y_test)

XGB = XGBClassifier(
learning_rate = 0.17,
n_estimators = 90,
max_depth=3,
min_child_weight=2,
gamma=0.07,
subsample=0.8,
colsample_bytree=0.8,
objective= 'multi:softmax',
num_class=7,
seed=27)
XGB.fit(X_trainval,y_trainval)


#评估模型
XGB.fit(X_test,y_test)
y_pred = XGB.predict(X_test)#返回训练后的预测结果
print(y_test)
print(y_pred)
p = precision_score(y_test, y_pred, average='weighted')#计算精确率
print(p)
r = recall_score(y_test, y_pred, average='weighted')#计算召回率
print(r)
f1sore = f1_score(y_test, y_pred, average='macro')#计算f1_macro 分数
print(f1sore)
f1sore_weight = f1_score(y_test, y_pred, average='weighted')#计算f1_weight 分数
print(f1sore_weight)
test_score = XGB.score(X_test,y_test)#计算test score
print("Score on testing set:{:.2f}".format(test_score))

#绘制ROC曲线
import matplotlib.pyplot as plt
y_ROC = y_test
y_ROC = label_binarize(y_ROC,classes=[1,2,3,4,5])#将label二值化
y_pred = label_binarize(y_pred,classes=[1,2,3,4,5])#将label二值化
n_classes = y_ROC.shape[1]#读取二维矩阵的类数,这里为5
y_score = XGB.predict_proba(X_test)#获取每个分类的概率值

fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_ROC[:, i], y_score[:, i])#遍历五种分类的结果来计算五种分类的fpr和tpr
    roc_auc[i] = auc(fpr[i], tpr[i])#计算roc曲线面积
fpr["micro"], tpr["micro"], _ = roc_curve(y_ROC .ravel(), y_score.ravel())
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])
plt.figure()
lw = 2
plt.plot(fpr["micro"], tpr["micro"], color='darkorange',
         lw=lw, label='ROC curve (area = %0.2f)' % roc_auc["micro"])
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.ylim([0.0, 1.0])
plt.xlim([0.0, 1.0])
plt.legend(loc="lower right")
plt.title("Precision-Recall")
plt.show()

```

  • 写回答

9条回答 默认 最新

  • m0_73340666 2023-03-16 21:22
    关注

    该回答引用chatGpt
    根据您提供的信息,所有评价指标都为1,但是ROC曲线不符合预期,这表明评价指标的结果可能不正确。有以下几个问题需要检查和调整:

    对于多类别问题,需要使用label_binarize函数将真实标签和预测标签二值化。您已经使用了该函数,但它在二值化标签时指定的类别不正确。在您的代码中,使用了classes=[1,2,3,4,5],但您的类别应该为7。您可以修改以下两行代码,将classes参数更改为[0,1,2,3,4,5,6]:

    y_ROC = label_binarize(y_ROC,classes=[0,1,2,3,4,5,6])#将label二值化
    y_pred = label_binarize(y_pred,classes=[0,1,2,3,4,5,6])#将label二值化
    

    您的模型是用X_trainval和y_trainval进行训练的,但在评估模型时,您使用了X_test和y_test,这意味着您的模型可能会过度拟合测试集。您可以使用X_trainval和y_trainval来评估模型,并在测试集上进行最终评估,如下所示:

    # 评估模型
    y_pred = XGB.predict(X_trainval) # 返回训练后的预测结果
    p = precision_score(y_trainval, y_pred, average='weighted') # 计算精确率
    print(p)
    r = recall_score(y_trainval, y_pred, average='weighted') # 计算召回率
    print(r)
    f1sore = f1_score(y_trainval, y_pred, average='macro') # 计算f1_macro 分数
    print(f1sore)
    f1sore_weight = f1_score(y_trainval, y_pred, average='weighted') # 计算f1_weight 分数
    print(f1sore_weight)
    test_score = XGB.score(X_test, y_test) # 计算test score
    print("Score on testing set:{:.2f}".format(test_score))
    
    # 绘制ROC曲线
    y_ROC = y_trainval
    y_ROC = label_binarize(y_ROC, classes=[0,1,2,3,4,5,6]) # 将label二值化
    y_pred = label_binarize(y_pred, classes=[0,1,2,3,4,5,6]) # 将label二值化
    n_classes = y_ROC.shape[1] # 读取二维矩阵的类数,这里为7
    y_score = XGB.predict_proba(X_trainval) # 获取每个分类的概率值
    
    fpr = dict()
    tpr = dict()
    roc_auc = dict()
    for i in range(n_classes):
        fpr[i], tpr[i], _ = roc_curve(y_ROC[:, i], y_score[:, i]) # 遍历七种分类的结果来计算七种分类的fpr和tpr
        roc_auc[i] = auc(fpr[i], tpr[i]) # 计算roc曲线面积
    fpr["micro"], tpr["micro"], _ = roc_curve(y_ROC.ravel(), y_score.ravel())
    roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])
    plt.figure()
    lw = 2
    plt.plot(fpr["micro"], tpr["micro"], color='darkorange',
             lw=lw, label='ROC curve (area = %0.2f)' % roc_auc["micro"])
    for i in range(n_classes):
        plt.plot(fpr[i], tpr[i], lw=lw,
                 label='ROC curve of class %d (area = %0.2f)' % (i, roc_auc[i]))
    plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
    plt.xlabel('FPR')
    plt.ylabel('TPR')
    plt.ylim([0.0, 1.0])
    plt.xlim([0.0, 1.0])
    plt.legend(loc="lower right")
    plt.title("ROC Curve")
    plt.show()
    

    您可以尝试使用网格搜索(Grid Search)来调整模型的参数,以改善模型的性能和泛化能力。例如,您可以使用以下代码:

    # 网格搜索
    param_grid = {'learning_rate': [0.1, 0.17],
                  'n_estimators': [50, 90],
                  'max_depth': [3, 5],
                  'min_child_weight': [1, 2],
                  'gamma': [0, 0.07],
                  'subsample': [0.8, 1],
                  'colsample_bytree': [0.8, 1]}
    grid_search = GridSearchCV(estimator=XGB, param_grid=param_grid, cv=5, n_jobs=-1)
    grid_search.fit(X_trainval, y_trainval)
    print("Best parameters: ", grid_search.best_params_)
    print("Best score: ", grid_search.best_score_)
    

    希望这些建议能帮助您解决问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(8条)

报告相同问题?

问题事件

  • 系统已结题 3月24日
  • 已采纳回答 3月16日
  • 赞助了问题酬金15元 3月16日
  • 创建了问题 3月16日

悬赏问题

  • ¥15 Python语言实验
  • ¥15 SAP HANA SQL 增加合计行
  • ¥20 用C#语言解决一个英文打字练习器,有偿
  • ¥15 srs-sip外部服务 webrtc支持H265格式
  • ¥15 在使用abaqus软件中,继承到assembly里的surfaces怎么使用python批量调动
  • ¥15 大一C语言期末考试,求帮助🙏🙏
  • ¥15 ch340驱动未分配COM
  • ¥15 Converting circular structure to JSON
  • ¥30 Hyper-v虚拟机相关问题,求解答。
  • ¥15 TSM320F2808PZA芯片 Bootloader