赞
踩
问题描述:评估生成的模型在实际应用中的表现
解决方案:创建一个流水线,对数据进行预处理、训练模型,然后用交叉验证方法评估模型的性能。
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
问题描述:需要一个简单基础回归模型,用于与算法生成的模型进行对比。
解决方案:使用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
问题描述:需要一个简单基础分类模型,用于与算法生成的模型进行对比。
解决方案:使用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
问题描述:给定一个训练后的二元分类器,评估它的性能
解决方案:使用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])
cross_val_score(LR,X,y,scoring="f1")
output:
array([0.95529884, 0.9500998 , 0.95827049, 0.95520886, 0.95577889])
评估二元分类器的性能,并对多个可能的阈值进行评估。
解决方案: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
评估一个能预测三个或更多分类的分类器性能
解决方案:使用能够处理两个以上分类的评估指标进行交叉验证
给定测试集数据的预测分类和真实分类,希望能够可视化地比较不同模型的性能。
解决方案:使用混淆矩阵(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。
使用均方误差:
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=1∑n(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=1−∑i=1n(yi−y)2∑i=1n(yi−yi^)2
R
2
R^2
R2得分越接近1,代表模型性能越好。
问题描述:使用无监督学习对数据进行聚类,需要评估聚类模型的性能
解决方案:可能无法评估聚类模型的性能,至少不会按预想的方式评估。
一种可选的方式是使用轮廓系数(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)bi−ai
其中,
s
i
s_i
si是样本i的轮廓系数,
a
i
a_i
ai是样本i与同类的所有样本间的平均距离,
b
i
b_i
bi是样本i与来自不同分类的最近聚类的所有样本间的平均距离。silhouette_score返回的值是所有样本的平均轮廓系数。值介于-1和1之间。
将评估指标实现为一个函数,并使用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函数。
绘制学习曲线来评估训练集中观察值的数量对某个指标的影响。
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()
学习曲线将模型在训练集上和交叉验证时的性能(例如准确率、召回率)以及与训练集样本数量之间的关系可视化地表达出来。此方法常被用来判断增加训练集数据规模能否提升模型的性能。
快速描述一个分类器的性能
使用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列是指分类中的样本数量。
绘制验证曲线了解超参数的变化对模型性能的影响
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个重要参数:
参考:Python机器学习手册
后续整理完所有的笔记,所有代码会放到github中!链接: https://github.com/DuoduoMoney/.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。