ML模型评估

1. 交叉验证模型

问题描述:评估生成的模型在实际应用中的表现

解决方案:创建一个流水线,对数据进行预处理、训练模型,然后用交叉验证方法评估模型的性能。

from sklearn import datasets
from sklearn import metrics
from sklearn.model_selection import KFold,cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler

#加载手写数字的数据集
digits = datasets.load_digits()
#创建特征矩阵
features = digits.data
#创建目标向量
target = digits.target
#创建标准化对象
standardizer = StandardScaler()
#创建逻辑回归对象
LR = LogisticRegression()
#创建包含数据标准化和逻辑回归的流水线
pipeline = make_pipeline(standardizer,LR)
#创建K折交叉验证对象
kf = KFold(n_splits=10,shuffle=True,random_state=1)
#执行K折交叉验证
cv_results = cross_val_score(pipeline,
                             features,
                             target,
                             cv=kf, #交叉验证方法
                             scoring="accuracy", #损失函数
                             n_jobs=-1) #使用所有CPU内核
#计算得分的平均值
cv_results.mean()
output:
0.9693916821849783

2. 创建一个基准回归模型

问题描述:需要一个简单基础回归模型,用于与算法生成的模型进行对比。

解决方案:使用sklearn的DummyRegressor创建一个简单的基准回归模型

from sklearn.datasets import load_boston
from sklearn.dummy import DummyRegressor
from sklearn.model_selection import train_test_split

# 加载数据
boston = load_boston()
#创建特征矩阵和目标向量
features,target = boston.data,boston.target
#将数据分为测试集和训练集
features_train,features_test,target_train,target_test = train_test_split(features,target,random_state=0)
#创建DummyRegressor对象
dummy = DummyRegressor(strategy='mean')
#训练回归模型
dummy.fit(features_train,target_train)
#计算R方得分
dummy.score(features_test,target_test)
output:
-0.001119359203955339
from sklearn.linear_model import LinearRegression
#训练简单线性回归模型
LR = LinearRegression()
LR.fit(features_train,target_train)
#计算R得分
LR.score(features_test,target_test)
output:
0.635463843320211

3. 创建一个基准分类模型

问题描述:需要一个简单基础分类模型,用于与算法生成的模型进行对比。

解决方案:使用sklearn的DummyClassifier创建一个简单的基准分类模型

from sklearn.datasets import load_iris
from sklearn.dummy import DummyClassifier
from sklearn.model_selection import train_test_split

# 加载数据
iris = load_iris()
#创建特征矩阵和目标向量
features,target = iris.data,iris.target
#将数据分为测试集和训练集
features_train,features_test,target_train,target_test = train_test_split(features,target,random_state=0)
#创建DummyClassifier对象
dummy = DummyClassifier(strategy='uniform',random_state = 1)
#训练回归模型
dummy.fit(features_train,target_train)
#计算R方得分
dummy.score(features_test,target_test)
output:
0.42105263157894735
from sklearn.ensemble import RandomForestClassifier
#训练简单线性回归模型
RF = RandomForestClassifier()
RF.fit(features_train,target_train)
#计算R得分
RF.score(features_test,target_test)
output:
0.9736842105263158

4. 评估二元分类器

问题描述:给定一个训练后的二元分类器,评估它的性能

解决方案:使用sklearn的cross_val_score方法进行交叉验证,同时使用Scoring参数来决定性能评估指标,可以在准确率、精确度、召回率和F1分数等多种指标中选择。

准 确 率 = T P + T N T P + T N + F P + F N 准确率={TP+TN\over TP+TN+FP+FN} =TP+TN+FP+FNTP+TN

from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification
#生成特征矩阵和目标向量
X,y = make_classification(n_samples = 10000,
                          n_features = 3,
                          n_informative = 3,
                          n_redundant = 0,
                          n_classes = 2,
                          random_state = 1)
#创建逻辑回归对象
LR = LogisticRegression()
#使用准确率对模型进行交叉验证
cross_val_score(LR,X,y,scoring = "accuracy")
output:
array([0.9555, 0.95  , 0.9585, 0.9555, 0.956 ])
  • 精确度
cross_val_score(LR,X,y,scoring="precision")
output:
array([0.95963673, 0.94820717, 0.9635996 , 0.96149949, 0.96060606])
  • 召回率
cross_val_score(LR,X,y,scoring="recall")
output:
array([0.951, 0.952, 0.953, 0.949, 0.951])
  • F1分数
cross_val_score(LR,X,y,scoring="f1")
output:
array([0.95529884, 0.9500998 , 0.95827049, 0.95520886, 0.95577889])

5. 评估二元分类器的阈值

评估二元分类器的性能,并对多个可能的阈值进行评估。

解决方案:ROC曲线是评估二元分类器质量的常用方法。ROC曲线会对每一个概率阈值(即用来区分样本属于正类或负类的概率值)比较其真阳性和假阳性的比例。在scikit-learn中,可以使用roc_curve来计算每个阈值下的真阳性率(True Postive Rate)和假阳性率(False Positive Rate),然后用图绘制出来。

import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve,roc_auc_score
from sklearn.model_selection import train_test_split

#创建特征矩阵和目标向量
features,target = make_classification(n_samples=10000,
                                      n_features=10,
                                      n_classes=2,
                                      n_informative=3,
                                      random_state=3)
#将样本划分为测试集和训练集
features_train,features_test,target_train,target_test=train_test_split(features,target,test_size=0.1,random_state=1)
#创建分类器
LR = LogisticRegression()
#训练模型
LR.fit(features_train,target_train)
#获取预测的概率
target_probabilities = LR.predict_proba(features_test)[:,1]
#计算真阳性和假阳性概率
false_positive_rate,true_positive_rate,threshold = roc_curve(target_test,target_probabilities)
#画出ROC曲线
plt.title("Receiver Operating Characteristic:")
plt.plot(false_positive_rate,true_positive_rate)
plt.plot([0,1],ls="--")
plt.plot([0,0],[1,0],c="0.7"),plt.plot([1,1],c="0.7")
plt.ylabel("True Positive Rate")
plt.xlabel("False Positive Rate")
plt.show()

在这里插入图片描述
查看第一个样本的预测概率:

LR.predict_proba(features_test)[0:1]
--->
array([[0.86891533, 0.13108467]])

查看分类:

LR.classes_
--->
array([0, 1])

提高Threshold,则TPR和FPR的值都会显著下降,这是因为对样本被预测为正类的要求提高了,模型无法识别一些正类样本(TPR较小),而且被错误预测为正类的负类样本也减小了(FPR较小)。

AUC
在scikit-learn中,可以使用roc_auc_score来计算AUC值。

roc_auc_score(target_test,target_probabilities)
--->
0.9073389355742297

6. 评估多元分类器

评估一个能预测三个或更多分类的分类器性能

解决方案:使用能够处理两个以上分类的评估指标进行交叉验证

  • 样本分类均衡
    准确率是评估模型性能的简单且可解释的指标
  • 分类数据不均衡
    应该使用其他评估指标,例如:精确度、召回率和F1分数等。

7. 分类器性能的可视化

给定测试集数据的预测分类和真实分类,希望能够可视化地比较不同模型的性能。

解决方案:使用混淆矩阵(Confusion Matrix)来比较预测分类(predicted Class)和真实分类(True Class):

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix

#加载数据
iris = datasets.load_iris()
#创建特征矩阵
features = iris.data
#提取目标向量
target = iris.target
#创建目标分类的名称列表
class_names = iris.target_names
#划分测试集和训练集
features_train,features_test,target_train,target_test = train_test_split(features,target ,random_state=1)
#创建LR
LR = LogisticRegression()
#训练模型并预测
target_predicted = LR.fit(features_train,target_train).predict(features_test)
#创建混淆矩阵
matrix = confusion_matrix(target_test,target_predicted)
#创建一个DataFrame
dataframe = pd.DataFrame(matrix,index =class_names,columns = class_names)
#绘制热力图
sns.heatmap(dataframe,annot = True,cbar=None,cmap="Blues")
plt.title("Confusion Matrix"),plt.tight_layout()
plt.ylabel("True Class"),plt.xlabel("predicted Class")
plt.show()

在这里插入图片描述
矩阵的每一列表示样本的预测分类,而每一行表示样本的真实分类。
该模型成功地预测了9个真实分类为Iris virginica的样本,而错误地将1个真实分类为Iris versicolor的样本预测为Iris virginica。

8. 评估回归模型

使用均方误差:

from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score

#创建特征矩阵和目标向量
features,target = make_regression(n_samples=100,
                                  n_features=3,
                                  n_informative=3,
                                  n_targets=1,
                                  noise=50,
                                  coef=False,
                                  random_state=1)
LR = LinearRegression()
#使用MSE对线性回归做交叉验证
cross_val_score(LR,features,target,scoring='neg_mean_squared_error')
--->
array([-1974.65337976, -2004.54137625, -3935.19355723, -1060.04361386,
       -1598.74104702])

另一个常用的评估回归模型的指标是决定系数(coefficient of determination,即得分)

#使用决定系数对线性回归做交叉验证
cross_val_score(LR,features,target,scoring='r2')
--->
array([0.8622399 , 0.85838075, 0.74723548, 0.91354743, 0.84469331])

MSE:

M S E = 1 n ∑ i = 1 n ( y i ^ − y i ) 2 MSE = {1\over n}\sum_{i=1}^n(\hat{y_i}-y_i)^2 MSE=n1i=1n(yi^yi)2
R 2 R^2 R2得分:
R 2 = 1 − ∑ i = 1 n ( y i − y i ^ ) 2 ∑ i = 1 n ( y i − y ‾ ) 2 R^2 = 1-{\sum_{i=1}^n(y_i-\hat{y_i})^2 \over \sum_{i=1}^n(y_i-\overline y)^2} R2=1i=1n(yiy)2i=1n(yiyi^)2
R 2 R^2 R2得分越接近1,代表模型性能越好。

9. 评估聚类模型

问题描述:使用无监督学习对数据进行聚类,需要评估聚类模型的性能

解决方案:可能无法评估聚类模型的性能,至少不会按预想的方式评估。
一种可选的方式是使用轮廓系数(silhouette coefficient)。轮廓系数可以用来衡量聚类的质量:

import numpy as np
from sklearn.metrics import silhouette_score
from sklearn import datasets
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

#创建特征矩阵和目标向量
features,_ = make_blobs(n_samples=1000,
                        n_features=10,
                        centers=2,
                        cluster_std=0.5,
                        shuffle=True,
                        random_state=1)
#使用kmeans方法对数据聚类、以预测其分类
model = KMeans(n_clusters=2,random_state=1).fit(features)
#获取预测的分类
target_predicted = model.labels_
#评估模型
silhouette_score(features,target_predicted)
--->
0.8916265564072142

好的聚类中同类样本间的距离非常小(即稠密聚类),不同类别的样本之间距离非常大(即分离得很彻底)。轮廓系数可以用一个值同时评估这两种特性。第i个样本的轮廓系数的计算公式为:

s i = b i − a i m a x ( a i , b i ) s_i={b_i-a_i \over max(a_i,b_i)} si=max(ai,bi)biai
其中, s i s_i si是样本i的轮廓系数, a i a_i ai是样本i与同类的所有样本间的平均距离, b i b_i bi是样本i与来自不同分类的最近聚类的所有样本间的平均距离。silhouette_score返回的值是所有样本的平均轮廓系数。值介于-1和1之间。

10. 创建自定义评估指标

将评估指标实现为一个函数,并使用sklearn的make_scorer将其转换为评分函数:

from sklearn.metrics import make_scorer,r2_score
from sklearn.datasets import make_regression
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split

#创建特征矩阵和目标向量
features,target = make_regression(n_samples=100,
                                  n_features=3,
                                  random_state=1)
#创建测试集和训练集
features_train,features_test,target_train,target_test=train_test_split(features,target,test_size=0.10,random_state=1)

#创建自定义指标函数
def custom_metric(target_test,target_predicted):
  #计算R方得分
  r2 = r2_score(target_test,target_predicted)
  #返回R方得分
  return r2
#创建评分函数,并且定义分数越高代表模型越好
score = make_scorer(custom_metric,greater_is_better=True)
#创建岭回归对象
classifier = Ridge()
#训练岭回归模型
model = classifier.fit(features_train,target_train)
#应用自定义评分器
score(model,features_test,target_test)
--->
0.9997906102882058

在实际情况中,可以使用任意自定义指标替换custom_metric函数。

11. 可视化训练集规模的影响

绘制学习曲线来评估训练集中观察值的数量对某个指标的影响。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import learning_curve

#加载数据
digits = load_digits()
#创建特征矩阵和目标向量
features,target = digits.data,digits.target
#使用交叉验证为不同规模的训练集计算训练和测试得分
train_sizes,train_scores,test_scores = learning_curve(RandomForestClassifier(),
                                                   features,
                                                   target,
                                                   cv=10,
                                                   scoring='accuracy',
                                                   #使用所有CPU内核
                                                   n_jobs=-1,
                                                   #50个训练集的规模
                                                   train_sizes=np.linspace(0.01,1.0,50))
#计算训练集得分的平均值和标准差
train_mean = np.mean(train_scores,axis=1)
train_std = np.std(train_scores,axis=1)
#计算测试集得分的平均值和标准差
test_mean = np.mean(test_scores,axis=1)
test_std = np.std(test_scores,axis=1)

#绘制曲线
plt.plot(train_sizes,train_mean,'--',color="#111111",label="Training score")
plt.plot(train_sizes,test_mean,color="#111111",label="Cross-validation score")
#画带状图
plt.fill_between(train_sizes,train_mean - train_std,
                 train_mean+train_std,color="#DDDDDD")
plt.fill_between(train_sizes,test_mean - test_std,
                 test_mean+test_std,color="#DDDDDD")
#创建图
plt.title("Learning Curve")
plt.ylabel("Accuracy Score")
plt.xlabel("Training Set Size")
plt.legend(loc="best")
plt.tight_layout()
plt.show()

在这里插入图片描述

学习曲线将模型在训练集上和交叉验证时的性能(例如准确率、召回率)以及与训练集样本数量之间的关系可视化地表达出来。此方法常被用来判断增加训练集数据规模能否提升模型的性能。

12. 生成对评估指标的报告

快速描述一个分类器的性能
使用sklearn的classification_report函数:

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

# 加载数据
iris = load_iris()
#创建特征矩阵和目标向量
features,target = iris.data,iris.target
#创建目标分类名的列表
class_names = iris.target_names
#将数据分为测试集和训练集
features_train,features_test,target_train,target_test = train_test_split(features,target,random_state=0)
#创建LR对象
classifier = LogisticRegression()
#训练回归模型并作出预测
model = classifier.fit(features_train,target_train)
target_predicted = model.predict(features_test)
#生成分类器的性能报告
print(classification_report(target_test,
                            target_predicted,
                            target_names=class_names))

—>

            precision  recall   f1-score   support
            
setosa        1.00      1.00      1.00        13
versicolor    1.00      0.94      0.97        16 
virginica     0.90      1.00      0.95         9

accuracy                          0.97        38
macro avg     0.97      0.98      0.97        38
weighted avg  0.98      0.97      0.97        38

classification_report提供了快速查看一些常见模型评估指标的方法,这些指标包括精确度、召回率和F1分数。输出support列是指分类中的样本数量。

13. 可视化超参数值的效果

绘制验证曲线了解超参数的变化对模型性能的影响

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import validation_curve

#加载数据
digits = load_digits()
#创建特征矩阵和目标向量
features,target = digits.data,digits.target
#创建参数的变化范围
param_range = np.arange(1,250,2)
#对区间内的参数值分别计算模型在训练集和测试集上的准确率
train_scores,test_scores = validation_curve(RandomForestClassifier(),
                                            features,
                                            target,
                                            #要查看的超参数
                                            param_name='n_estimators',
                                            #超参数值得范围
                                            param_range =param_range,
                                            #交叉验证的折数
                                            cv=3,
                                            #性能指标
                                            scoring="accuracy",
                                            #使用所有CPU
                                            n_jobs=-1)
#计算训练集得分的平均值和标准差
train_mean = np.mean(train_scores,axis=1)
train_std = np.std(train_scores,axis=1)
#计算测试集得分的平均值和标准差
test_mean = np.mean(test_scores,axis=1)
test_std = np.std(test_scores,axis=1)

#画出模型在训练集和测试集上的准确率的平均值
plt.plot(param_range,train_mean,label="Training score",color="black")
plt.plot(param_range,test_mean,label="Cross-validation score",color="dimgrey")
#画出模型在训练集和测试集上的准确率带状图
plt.fill_between(param_range,train_mean - train_std,
                 train_mean+train_std,color="gray")
plt.fill_between(param_range,test_mean - test_std,
                 test_mean+test_std,color="gainsboro")
#创建图
plt.title("Validation Curve With Random Forest")
plt.ylabel("Accuracy Score")
plt.xlabel("Number Of Trees")
plt.legend(loc="best")
plt.tight_layout()
plt.show()

在这里插入图片描述

在scikit-learn中,可以使用validation_curve计算验证曲线,包含3个重要参数:

  • param_name:需要变化的超参数的名字
  • param_range:超参数取值区间
  • scoring:模型评估指标

参考:Python机器学习手册

后续整理完所有的笔记,所有代码会放到github中!链接: https://github.com/DuoduoMoney/.

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值