linyifeng117 2023-03-16 21:13 采纳率: 50%

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

python进行XGBoost分析多分类问题时，采用precision、recall、f1-macro、f1-weighted和test score来评价模型并绘制ROC曲线。

``````
```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

#读取数据和标签
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_)
``````

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

本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

#### 问题事件

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

#### 悬赏问题

• ¥20 对D盘进行分盘之前没有将visual studio2022卸载掉，现在该如何下载回来
• ¥15 完成虚拟机环境配置，还有安装kettle
• ¥15 2024年全国大学生数据分析大赛A题：直播带货与电商产品的大数据分析 问题5. 请设计一份优惠券的投放策略，需要考虑优惠券的数量、优惠券的金额、投放时间段和投放商品种类等因素。求具体的python代码
• ¥15 有人会搭建生鲜配送自营+平台的管理系统吗
• ¥15 用matlab写代码