分类模型效果评估

分类模型效果评估

评估标准:

  • Accuracy
  • Precision
  • Recal
  • F Score
  • ROC curve

以鸢尾花数据集为例子,我们用PCA(主成分回归法)(重点展示效果评估这一块,所以暂时只用这一方法选择特征)绛维,然后进行建模,最后对模型的效果进行评估。

import pandas as pd
import numpy as np
from sklearn.decomposition import PCA
iris = pd.read_csv(r"G:\Iris_copy.csv")
iris.sample(4)
Id SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm Species
48 49 5.3 3.7 1.5 0.2 0
75 76 6.6 3.0 4.4 1.4 1
128 129 6.4 2.8 5.6 2.1 2
84 85 5.4 3.0 4.5 1.5 1
del iris["Id"]
iris.sample(3)
SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm Species
114 5.8 2.8 5.1 2.4 2
92 5.8 2.6 4.0 1.2 1
77 6.7 3.0 5.0 1.7 1
data = iris.iloc[:,:4]
data.head(3)
SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
pca = PCA()   #先保留所有成分
pca.fit(data)
print(pca.explained_variance_)
print("各个成分的方差百分比(贡献率):", pca.explained_variance_ratio_)
[ 4.22484077  0.24224357  0.07852391  0.02368303]
各个成分的方差百分比(贡献率): [ 0.92461621  0.05301557  0.01718514  0.00518309]

当选取前两个主成分时,累计贡献率已达97.76%。接下来保留两个主成分。

pca = PCA(2)  
pca.fit(data)
new_data = pca.transform(data)   #转换原始数据
new_data = pd.DataFrame(new_data)
Species = pd.DataFrame(iris.Species)
new_iris = pd.concat([new_data, Species], axis=1)    #拼接数据
print(new_iris.head())
          0         1  Species
0 -2.684207  0.326607        0
1 -2.715391 -0.169557        0
2 -2.889820 -0.137346        0
3 -2.746437 -0.311124        0
4 -2.728593  0.333925        0

下面用逻辑回归来进行建模

from sklearn.linear_model import LogisticRegression as LR
from sklearn.model_selection import train_test_split
x = new_iris.iloc[:,:2]
y = new_iris.iloc[:,-1]
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=0.3)
lr = LR()
lr.fit(x_train,y_train)
y_pred = lr.predict(x_test)

接下来介绍几种模型效果的评测标准

1.混淆矩阵

Actual = [1,1,0,0,1,0,0,0,1,1]
Model = [0,0,0,1,1,1,1,0,0,0]
from sklearn.metrics import confusion_matrix
a = confusion_matrix(Actual, Model)
b = pd.DataFrame(a,columns=["0","1"],index=["0","1"])
b.index.name = "实际"
b.columns.name = "模型"
b
模型 0 1
实际
0 2 3
1 4 1

二分类中
TP,预测是正样本实际是正样本,预测正确
FP,预测是正样本实际是负样本,预测错误
FN,预测是负样本实际是正样本,预测错误
TN,预测是负样本实际是负样本,预测正确

from sklearn.metrics import confusion_matrix
confusion_matrix(y_test,y_pred)
array([[16,  0,  0],
       [ 0, 11,  5],
       [ 0,  0, 13]], dtype=int64)

2.Accuracy (准确率)

Accuracy = (TP+TF)/(TP+FP+FN+TN)
Accuracy是对分类器整体上的正确率的评价,而Precision是分类器预测为某一个类别的正确率的评价。
Accuracy要在样本均衡时使用才有效 ,不然再高也不能代表该模型好。
例:我买了100000个玩具,其中100个是Bubblebee,其余的是海绵宝宝,现在我想把
Bubblebee全部放在客厅。我让一个小朋友帮我忙,那即使他把这100000个玩具都判定为海绵宝宝,那他的判断能力
Accuracy = (TP+TF)/(TP+FP+FN+TN)
=(0+99900)/100000
= 99.9%
这么高的Accuracy却依然没有真实反映这个小朋友的判断能力。Consequently,在实际应用中,若样本不均衡,不能仅以Accuracy为模型的评判标准。
要加以考虑下面的评判标准。

3.Precision (精准率)

Precision = TP/(TP+FP)
在所有预测为正的样本中,实际为正的样本比例 (猜对率)

4.Recall (召回率)

Recall = TP/(TP+FN)
在所有实际为正的样本中,预测为正的比例 (猜全率)

**5.F1-score **

精确率和召回率是相互制约的,一般精确率低的召回率高,精确率搞得召回率低。所以出现了f1 score,它是 Precision 和 Recall 的调和平均数。
F1-score = 2 / [(1 / precision) + (1 / recall)]
Fscore里的一个检验值

6.Roc/Auc (仅针对二分类变量)

ROC 是针对不同阈值,根据对应的fpr、tpr生成ROC图,曲线下方的面积就是AUC(类似散点图跟相关系数的关系,一者以图的形式给你直观感受,一者以精确的尺度衡量大小)
横坐标fpr (tpr是模型在正样本上的预测准确率)
纵坐标tpr(fpr是模型在负样本上的预测准确率)

fpr, tpr, thresholds = metrics.roc_curve(y_test,y_pred)
import matplotlib.pyplot as plt
plt.plot(fpr, tpr)
auc_value = auc(fpr,tpr) #计算auc值
官网参考:https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_curve.html

sklearn.metrics.roc_curve(y_true, y_score, pos_label=None, sample_weight=None, drop_intermediate=True)[source]¶
仅针对二分类变量
""""""

Parameters:

y_true : array, shape = [n_samples]
实际的二分类标签. 如果标签不是 {-1, 1} 或者 {0, 1}, 那么pos_label应该被指定,表示哪个是正标签,剩下的那个就是负标签。
y_score : array, shape = [n_samples]
Target scores, 也可以是正类标签的估计概率, confidence values, or non-thresholded measure of decisions (as returned by “decision_function” on some classifiers).

pos_label : int or str, default=None
Label considered as positive and others are considered negative.

sample_weight : array-like of shape = [n_samples], optional
Sample weights.

drop_intermediate : boolean, optional (default=True)
Whether to drop some suboptimal thresholds which would not appear on a plotted ROC curve. This is useful in order to create lighter ROC curves.

New in version 0.17: parameter drop_intermediate.

Returns:
fpr : array, shape = [>2]
Increasing false positive rates such that element i is the false positive rate of predictions with score >= thresholds[i].

tpr : array, shape = [>2]
Increasing true positive rates such that element i is the true positive rate of predictions with score >= thresholds[i].

thresholds : array, shape = [n_thresholds]
Decreasing thresholds on the decision function used to compute fpr and tpr. thresholds[0] represents no instances being predicted and is arbitrarily set to max(y_score) + 1.
""""""
#后面再翻译

And then,实践:

from sklearn import metrics
print("Accuracy:",metrics.accuracy_score(y_test, y_pred))
print("Precision:",metrics.precision_score(y_test, y_pred, average='micro'))
print("Recall:",metrics.recall_score(y_test, y_pred, average='micro'))
print("f1-score:",metrics.f1_score(y_test, y_pred, average='micro'))
Accuracy: 0.888888888889
Precision: 0.888888888889
Recall: 0.888888888889
f1-score: 0.888888888889

classification_report直接把上面的指标综合成一份报告输出:

from sklearn.metrics import classification_report
print(classification_report(y_test,y_pred))
             precision    recall  f1-score   support

          0       1.00      1.00      1.00        16
          1       1.00      0.69      0.81        16
          2       0.72      1.00      0.84        13

avg / total       0.92      0.89      0.89        45

roc、AUC例子:(用random生成随机数,所以效果较差)

import numpy as np
import random
from sklearn import metrics
import matplotlib.pyplot as plt
%matplotlib inline
y_true = np.random.randint(1,3,size=100)
y_score = [np.random.random() for i in range(100)]
fpr, tpr, thresholds = metrics.roc_curve(y_true, y_score, pos_label=2)
auc_value = metrics.auc(fpr,tpr)
plt.plot(fpr, tpr, color="red", label="Roc Curve(area = %0.2f)" % auc_value)
print("Auc:",auc_value)   #计算auc
plt.plot((0,1),(0,1), color="blue", linewidth=2, linestyle='--')
plt.legend(loc="best")
plt.title("Roc Curve")
plt.xlabel("Tpr")
plt.ylabel("Fpr")
Auc: 0.548076923077
<matplotlib.text.Text at 0xe2a97f390>

png

一般而言,Auc值处于0.5-1之间,曲线越靠近左上角越好,那么面积将越接近于1,效果越好。下图展现较好效果:


posted @ 2019-01-06 14:21  喜欢吃面的猪猪  阅读(413)  评论(0编辑  收藏  举报