And*_*y G 5 python metrics scikit-learn
我认为 Scikit 中多类的 f1_macro 将使用以下方法计算:
2 * Macro_precision * Macro_recall / (Macro_precision + Macro_recall)
Run Code Online (Sandbox Code Playgroud)
但手动检查显示并非如此,该值略高于 scikit 计算的值。我浏览了文档,但找不到公式。
例如,鸢尾花数据集产生以下结果:
from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
data=pd.DataFrame({
'sepal length':iris.data[:,0],
'sepal width':iris.data[:,1],
'petal length':iris.data[:,2],
'petal width':iris.data[:,3],
'species':iris.target
})
X=data[['sepal length', 'sepal width', 'petal length', 'petal width']]
y=data['species']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
clf=RandomForestClassifier(n_estimators=100)
clf.fit(X_train,y_train)
y_pred=clf.predict(X_test)
#Compute metrics using scikit
from sklearn import metrics
print(metrics.confusion_matrix(y_test, y_pred))
print(metrics.classification_report(y_test, y_pred))
pre_macro = metrics.precision_score(y_test, y_pred, average="macro")
recall_macro = metrics.recall_score(y_test, y_pred, average="macro")
f1_macro_scikit = metrics.f1_score(y_test, y_pred, average="macro")
print ("Prec_macro_scikit:", pre_macro)
print ("Rec_macro_scikit:", recall_macro)
print ("f1_macro_scikit:", f1_macro_scikit)
Run Code Online (Sandbox Code Playgroud)
输出:
Prec_macro_scikit: 0.9555555555555556
Rec_macro_scikit: 0.9666666666666667
f1_macro_scikit: 0.9586466165413534
Run Code Online (Sandbox Code Playgroud)
然而,手动计算使用:
f1_macro_manual = 2 * pre_macro * recall_macro / (pre_macro + recall_macro )
Run Code Online (Sandbox Code Playgroud)
产量:
f1_macro_manual: 0.9610789980732178
Run Code Online (Sandbox Code Playgroud)
我正在努力找出差距。
宏观平均并不是这样工作的。宏观平均 f1 分数不是根据宏观平均精度和召回值计算的。
宏观平均计算每个类别的指标值并返回各个值的未加权平均值。因此,计算f1_score可以average='macro'计算每个类别的 f1 分数并返回这些分数的平均值。
如果您想自己计算宏平均值,请指定average=None获取每个类别的二进制 f1 分数数组,然后获取mean()该数组的 :
binary_scores = metrics.f1_score(y_test, y_pred, average=None)
manual_f1_macro = binary_scores.mean()
Run Code Online (Sandbox Code Playgroud)
可运行的演示在这里。