Int*_*777 5 python scikit-learn
我是python和机器学习的新手。根据我的要求,我正在尝试对数据集使用朴素贝叶斯算法。
我能够找出准确度,但尝试找出准确度并回想一下。但是,它引发以下错误:
"choose another average setting." % y_type)
ValueError: Target is multiclass but average='binary'. Please choose another average setting.
Run Code Online (Sandbox Code Playgroud)
谁能建议我如何进行。我曾尝试在平均值和召回率分数中使用average ='micro'。它的工作原理没有任何错误,但在准确性,准确性和召回率上却给出了相同的分数。
review,label
Colors & clarity is superb,positive
Sadly the picture is not nearly as clear or bright as my 40 inch Samsung,negative
Run Code Online (Sandbox Code Playgroud)
review,label
The picture is clear and beautiful,positive
Picture is not clear,negative
Run Code Online (Sandbox Code Playgroud)
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import BernoulliNB
from sklearn.metrics import confusion_matrix
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
def load_data(filename):
reviews = list()
labels = list()
with open(filename) as file:
file.readline()
for line in file:
line = line.strip().split(',')
labels.append(line[1])
reviews.append(line[0])
return reviews, labels
X_train, y_train = load_data('/Users/abc/Sep_10/train_data.csv')
X_test, y_test = load_data('/Users/abc/Sep_10/test_data.csv')
vec = CountVectorizer()
X_train_transformed = vec.fit_transform(X_train)
X_test_transformed = vec.transform(X_test)
clf= MultinomialNB()
clf.fit(X_train_transformed, y_train)
score = clf.score(X_test_transformed, y_test)
print("score of Naive Bayes algo is :" , score)
y_pred = clf.predict(X_test_transformed)
print(confusion_matrix(y_test,y_pred))
print("Precision Score : ",precision_score(y_test,y_pred,pos_label='positive'))
print("Recall Score :" , recall_score(y_test, y_pred, pos_label='positive') )
Run Code Online (Sandbox Code Playgroud)
您需要添加'average'参数。根据文档:
平均值:字符串,[无,“二进制”(默认),“微”,“宏”,“样本”,“加权”]
Run Code Online (Sandbox Code Playgroud)This parameter is required for multiclass/multilabel targets. If None, the scores for each class are returned. Otherwise, this determines the type of averaging performed on the data:
做这个:
print("Precision Score : ",precision_score(y_test, y_pred,
pos_label='positive'
average='micro'))
print("Precision Score : ",recall_score(y_test, y_pred,
pos_label='positive'
average='micro'))
Run Code Online (Sandbox Code Playgroud)
替换'micro'为以上任一选项'binary'。同样,在多类设置中,不需要提供,'pos_label'因为无论如何它将被忽略。
更新评论:
是的,它们可以相等。它在用户指南中给出:
请注意,对于包含所有标签的多类设置中的“微”平均,将产生相等的精度,召回率和F,而“加权”平均可能会产生不在精度和召回率之间的F分数。
这个错误是不言自明的。也就是说,对于超过 2 个类别的问题,需要某种平均规则。有效的规则是:'micro'、'macro'和(文档列出了'weighted',但它不适用于多类目标)。None'samples'
如果我们查看其源代码,在精度和召回分数计算方面,多类问题会被视为多标签问题,因为使用的底层混淆矩阵 ( multilabel_confusion_matrix) 是相同的。1此混淆矩阵创建一个 3D 数组,其中每个“子矩阵”都是 2x2 混淆矩阵,其中正值是标签之一。
使用average=None,返回每个类别的精确度/召回率分数(不进行任何平均),因此我们得到一个长度等于类别数量的分数数组。2
使用 时average='macro',会计算每个类别的精度/召回率,然后取平均值。其公式如下:
有了average='micro',所有类别的贡献就被相加来计算平均精度/召回率。其公式如下:
average='weighted'实际上是加权宏观平均值,其中权重是实际的正类。其公式如下:
让我们考虑一个例子。
import numpy as np
from sklearn import metrics
y_true, y_pred = np.random.default_rng(0).choice(list('abc'), size=(2,100), p=[.8,.1,.1])
mcm = metrics.multilabel_confusion_matrix(y_true, y_pred)
Run Code Online (Sandbox Code Playgroud)
上面计算的多标签混淆矩阵如下所示。
各自的准确率/召回率分数如下:
average='macro'准确率/召回率是:
recall_macro = (57 / (57 + 16) + 1 / (1 + 10) + 6 / (6 + 10)) / 3
precision_macro = (57 / (57 + 15) + 1 / (1 + 13) + 6 / (6 + 8)) / 3
# verify using sklearn.metrics.precision_score and sklearn.metrics.recall_score
recall_macro == metrics.recall_score(y_true, y_pred, average='macro') # True
precision_macro == metrics.precision_score(y_true, y_pred, average='macro') # True
Run Code Online (Sandbox Code Playgroud)
average='micro'准确率/召回率是:
recall_micro = (57 + 1 + 6) / (57 + 16 + 1 + 10 + 6 + 10)
precision_micro = (57 + 1 + 6) / (57 + 15 + 1 + 13 + 6 + 8)
# verify using sklearn.metrics.precision_score and sklearn.metrics.recall_score
recall_micro == metrics.recall_score(y_true, y_pred, average='micro') # True
precision_micro == metrics.precision_score(y_true, y_pred, average='micro') # True
Run Code Online (Sandbox Code Playgroud)
average='weighted'准确率/召回率是:
recall_weighted = (57 / (57 + 16) * (57 + 16) + 1 / (1 + 10) * (1 + 10) + 6 / (6 + 10) * (6 + 10)) / (57 + 16 + 1 + 10 + 6 + 10)
precision_weighted = (57 / (57 + 15) * (57 + 16) + 1 / (1 + 13) * (1 + 10) + 6 / (6 + 8) * (6 + 10)) / (57 + 16 + 1 + 10 + 6 + 10)
# verify using sklearn.metrics.precision_score and sklearn.metrics.recall_score
recall_weighted == metrics.recall_score(y_true, y_pred, average='weighted') # True
precision_weighted == metrics.precision_score(y_true, y_pred, average='weighted') # True
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这里的示例是不平衡的(类的a频率为 80%,而b和c各为 10%)。平均规则之间的主要区别在于,'macro'平均不考虑类别不平衡,但'micro'会'weighted'考虑类别不平衡。因此'macro'对类别不平衡很敏感,并且可能会根据不平衡情况导致“人为”高分或低分。
另外,从公式中很容易看出,回忆分数'micro'和'weighted'是相等的。
average='micro'?从视觉上看可能更容易理解。
如果我们看一下上面构建的多标签混淆矩阵,每个子矩阵对应一个 One vs Rest 分类问题;即在子矩阵的每个非列/行中,考虑其他两个标签。
例如,对于第一个子矩阵,有
a)b或c)b或c)对于精度/召回率的计算,只有 TP、FN 和 FP 重要。如上所述,FN 和 FP 计数可以是b或c;由于它是二进制的,因此该子矩阵本身无法说明每个子矩阵的预测数量;但是,我们可以通过简单地调用该方法来计算多类混淆矩阵,从而准确确定其中有多少个被正确分类confusion_matrix()。
mccm = metrics.confusion_matrix(y_true, y_pred)
Run Code Online (Sandbox Code Playgroud)
下图mccm使用不同的背景颜色绘制了相同的混淆矩阵 ( )(黄色背景对应于 TP,红色背景对应于第一个子矩阵中的假阴性,橙色对应于第三个子矩阵中的假阳性等)。所以这些实际上是多标签混淆矩阵中的 TP、FN 和 FP,它们被“扩展”以准确解释负类。左图的配色方案与多标签混淆矩阵中 TP 和 FN 计数的颜色(用于确定召回率)相匹配,右图的配色方案与 TP 和 FP 的颜色(用于确定精度)相匹配。
其中average='micro',黄色背景数字与左图中所有数字的比率决定召回率,黄色背景数字与右图中所有数字的比率决定精确率。如果我们仔细观察,相同的比率也决定了准确性。此外,由于f1-score是精度和召回率的调和平均值,并且假设它们相等,因此我们有关系recall == precision == accuracy == f1-score。
| 归档时间: |
|
| 查看次数: |
9416 次 |
| 最近记录: |