You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NLTK电影短评分类代码中计算混淆矩阵与ROC曲线?

没问题,我来帮你搞定混淆矩阵和ROC曲线的计算!你的现有代码已经完成了数据预处理和分类器训练,只需要补充几部分代码就能得到这两个评估指标,下面一步步来:

第一步:导入所需的库

首先需要导入sklearn的评估模块和绘图库,在代码开头加上:

from sklearn.metrics import confusion_matrix, roc_curve, auc
import matplotlib.pyplot as plt
import numpy as np

第二步:计算混淆矩阵

混淆矩阵需要真实标签和预测标签的对应数据,我们先从测试集中提取真实标签,再获取两个分类器的预测结果:

提取测试集真实标签

# 从测试集中取出所有真实标签
y_true = [category for (features, category) in testing_set]

计算朴素贝叶斯分类器的混淆矩阵

# 获取原生Naive Bayes的预测标签
y_pred_nb = [classifier.classify(features) for (features, category) in testing_set]
# 生成混淆矩阵,指定标签顺序为['pos', 'neg']确保结果对应正确
cm_nb = confusion_matrix(y_true, y_pred_nb, labels=['pos', 'neg'])
print("Naive Bayes 混淆矩阵:")
print(cm_nb)

计算MultinomialNB的混淆矩阵

# 获取MNB分类器的预测标签
y_pred_mnb = [MNB_classifier.classify(features) for (features, category) in testing_set]
cm_mnb = confusion_matrix(y_true, y_pred_mnb, labels=['pos', 'neg'])
print("\nMultinomialNB 混淆矩阵:")
print(cm_mnb)

第三步:绘制ROC曲线

ROC曲线需要分类器对正类(这里是'pos')的概率预测值,所以我们需要把标签转换成数值,并获取概率输出:

标签数值化

# 将文本标签转为数值:pos=1,neg=0,方便ROC计算
y_true_num = np.array([1 if label == 'pos' else 0 for label in y_true])

处理MultinomialNB的概率预测

因为MNB_classifier是用SklearnClassifier包装的,我们可以直接访问底层的sklearn模型来获取概率:

# 把NLTK格式的特征转换为sklearn能处理的特征矩阵
def features_to_matrix(featuresets):
    feature_matrix = []
    for (feat_dict, _) in featuresets:
        # 按照words_features的顺序提取特征值,保证和训练时一致
        feat_list = [feat_dict[word] for word in words_features]
        feature_matrix.append(feat_list)
    return np.array(feature_matrix)

# 转换测试集特征
X_test = features_to_matrix(testing_set)
# 获取MNB对正类(pos)的预测概率
y_proba_mnb = MNB_classifier._clf.predict_proba(X_test)[:, 1]

计算并绘制MNB的ROC曲线

# 计算ROC曲线参数和AUC值
fpr_mnb, tpr_mnb, thresholds_mnb = roc_curve(y_true_num, y_proba_mnb)
roc_auc_mnb = auc(fpr_mnb, tpr_mnb)

# 绘制ROC曲线
plt.figure(figsize=(8, 6))
plt.plot(fpr_mnb, tpr_mnb, color='darkorange', lw=2, 
         label=f'MultinomialNB ROC曲线 (AUC = {roc_auc_mnb:.2f})')
# 绘制随机猜测的基准线
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('假阳性率(FPR)')
plt.ylabel('真阳性率(TPR)')
plt.title('受试者工作特征曲线(ROC)')
plt.legend(loc="lower right")
plt.show()

处理原生NaiveBayes的概率预测

NLTK的原生NaiveBayesClassifier没有predict_proba,但可以用prob_classify方法获取概率分布:

# 获取原生NaiveBayes对正类的预测概率
y_proba_nb = []
for (features, _) in testing_set:
    prob_dist = classifier.prob_classify(features)
    # 取出pos类的概率
    y_proba_nb.append(prob_dist.prob('pos'))
y_proba_nb = np.array(y_proba_nb)

# 计算ROC曲线和AUC
fpr_nb, tpr_nb, thresholds_nb = roc_curve(y_true_num, y_proba_nb)
roc_auc_nb = auc(fpr_nb, tpr_nb)

# 把两个分类器的ROC画在一起对比
plt.figure(figsize=(8, 6))
plt.plot(fpr_nb, tpr_nb, color='green', lw=2, 
         label=f'Naive Bayes ROC曲线 (AUC = {roc_auc_nb:.2f})')
plt.plot(fpr_mnb, tpr_mnb, color='darkorange', lw=2, 
         label=f'MultinomialNB ROC曲线 (AUC = {roc_auc_mnb:.2f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('假阳性率(FPR)')
plt.ylabel('真阳性率(TPR)')
plt.title('受试者工作特征曲线对比')
plt.legend(loc="lower right")
plt.show()

关于投票分类器的补充

如果你的VoteClassifier支持概率输出(比如你的confidence方法返回的是正类概率),可以类似上面的方式获取y_proba_voted,然后计算它的ROC曲线。比如如果sentiment函数返回的第二个值是pos类的置信度,那可以这样:

y_proba_voted = []
for (rev, _) in documents[100:]:  # 对应测试集的原文本
    _, conf = sentiment(rev)
    y_proba_voted.append(conf)
y_proba_voted = np.array(y_proba_voted)
# 后续计算ROC的步骤和上面一致

最后提醒一下:你的训练集只取了前100个样本,这可能会导致模型效果很差,建议增大训练集的比例(比如training_set = featuresets[:int(len(featuresets)*0.8)],测试集取剩下的20%),这样评估指标会更有参考价值。

内容的提问来源于stack exchange,提问作者ASIM USMAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:59:13