模型选择及模型评估
01模型选择
1.1留出法
对于一个机器学习问题,我们通常有数据集D(用于训练模型),但我们还需要评估模型,因此不能把整个D用于训练,因为拿训练过的数据再去评估必然无效。那么最基本的方法就是留出法。
划分时一般不宜随机划分,因为如果T中正好只取到某一种特殊类型数据,从而带来了额外的误差。此时处理方法要视具体情况而定,如当数据明显的分为有限类时,可以采用分层抽样方式选择测试数据,保证数据分布比例的平衡。
划分比例:7:3左右
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JX8x8qaS-1589287054521)(E:\八维\平时工作内容\专高工作进度\进度任务\模型选择及模型评估\图片1.png)]
API讲解
X_train,X_test, y_train, y_test =cross_validation.train_test_split(train_data,train_target,test_size=0.3, random_state=0)
参数释义
train_data:被划分的样本特征集
train_target:被划分的样本标签
test_size:如果是浮点数,在0-1之间,表示样本占比;如果是整数的话就是样本的数量
random_state:是随机数的种子。
返回值
x训练集,x测试集,y训练集,y测试集
代码演示
from sklearn.model_selection import train_test_split
import numpy as np
data = np.array([
[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9], [0, 0]
])
x = data[:, 0]
y = data[:, 1]
# 对数据进行随机洗牌处理,生成
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
print('x训练集\n', x_train)
print('y训练集\n', y_train)
print('x测试集\n', x_test)
print('y测试集\n', y_test)
结果输出
x训练集
[6 2 3 8 7 9 4]
y训练集
[6 2 3 8 7 9 4]
x测试集
[5 0 1]
y测试集
[5 0 1]
1.2交叉验证法
交叉验证法(k-fold cross validation):划分为k个互斥子集,用k-1作为训练集,剩下一个为测试集,最终每一个子集都会作为测试集,其余子集作为训练集,共进行k次建模,最终得到测试结果的均值。
K取值一般为10
随机取k个互斥子集,进行p次,最后对p个k-fold cv进行取平均,叫作p次k折交叉验证
网格搜索交叉验证
Grid Search 是一种穷举的调参方法。通过循环遍历的方式,把每一种候选的参数组合,全部调试一遍。最后表现效果最好的参数就是最终的结果。
嵌套循环方式实现:(每次调参时,数据集要保持一致性)。为了避免test data既用于检验模型参数,又用于测试模型好坏,会提高模型结果的评分。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IrbEXsFr-1589287054523)(E:\八维\平时工作内容\专高工作进度\进度任务\模型选择及模型评估\图片2.png)]
API讲解
sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, n_jobs=None, iid='deprecated', refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', error_score=nan, return_train_score=False)
参数释义
estimator:要处理的模型
param_grid:以参数名称(字符串)作为键的Dictionary和尝试作为值的参数设置列表,或此类Dictionary的列表,在这种情况下,将探索列表中每个Dictionary跨越的网格。这允许在任何参数设置序列上进行搜索。
scoring:使用哪一种得分评测模型
n_jobs:确定并行数量
pre_dispatch:控制在并行执行期间分派的作业的数量
cv:使用几折交叉验证
属性
best_estimator_:由搜索选择的估计量,即在被遗漏的数据上给出最高分(或指定最小损失)的估计量。
best_score_:成员提供优化过程期间观察到的最好的评分
best_params_:描述了已取得最佳结果的参数的组合
best_index_:对应于最佳候选参数设置的索引(cv_results_数组的索引)
函数
fit(X, y=None)
训练模型
predict(X)
用找到的最佳参数调用预估器。(直接预测每个样本属于哪一个类别)
predict_proba(X)
用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分情况,如果是分类问题)
score(X, y=None)
返回给定数据上的得分,如果预估器已经选出最优的分类器。
分类的得分是准确率,回归的得分是R方
代码演示
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
import warnings
warnings.filterwarnings('ignore')
data = load_iris()
x = data.data
y = data.target
dt = DecisionTreeClassifier()
# 设置决策树参数
pg={
'max_depth': [1, 2, 3]
}
# 创建网格搜索交叉验证
model = GridSearchCV(dt, param_grid=pg, cv=3)
model.fit(x, y)
print('模型最优参数:', model.best_params_)
print('模型最优得分:', model.best_score_)
print('预测结果\n', model.predict(x))
结果输出
模型最优参数: {'max_depth': 3}
模型最优得分: 0.96
预测结果
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1
1 1 1 2 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 1 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
1.3留一法
一种交叉验证方法就是留一法(Leave-One-Out,简称LOO),顾名思义,就是使k等于数据集中数据的个数,每次只使用一个作为测试集,剩下的全部作为训练集,这种方法得出的结果与训练整个测试集的期望值最为接近,但是成本过于庞大。
1.4自助法
对D中的m个数据随机取样,接着将数据放回原数据集继续取样,重复m次,产生一个新的数据集D’。最后用未取到的数据作为测试集。
未取到的数据占比36.8%
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ix76Xzqa-1589287054525)(E:\八维\平时工作内容\专高工作进度\进度任务\模型选择及模型评估\图片3.png)]
02回归模型评估指标
2.1均方误差(mean square error)
均方误差是衡量“平均误差”的一种较方便的方法,可以评价数据的变化程度。从类别来看属于预测评价与预测组合;从字面上看来,“均”指的是平均,即求其平均值,“方差”即是在概率论中用来衡量随机变量和其估计值(其平均值)之间的偏离程度的度量值,“误”可以理解为测定值与真实值之间的误差。
均方误差是最常用的公式形式
m
s
e
=
1
n
∑
i
=
1
n
(
y
i
^
−
y
i
)
2
mse = \dfrac{1}{n} \sum^n_{i=1}\left(\hat{y_i}-y_i \right)^2
mse=n1i=1∑n(yi^−yi)2
代码演示
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
data = load_boston()
x = data.data
y = data.target
model = LinearRegression()
model.fit(x, y)
y_ = model.predict(x)
# 显示实际值,接着是预测值
print('均方误差:', mean_squared_error(y, y_))
结果输出
均方误差: 21.894831181729206
2.2均方误差根(root mean square error)
均方根误差是均方误差的算术平方根
r
m
s
e
=
1
n
∑
i
=
1
n
(
y
i
^
−
y
i
)
2
rmse = \sqrt{ \dfrac{1}{n} \sum^n_{i=1}\left(\hat{y_i}-y_i\right)^2}
rmse=n1i=1∑n(yi^−yi)2
2.3均绝对值误差(mean absolute error)
平均绝对离差,是所有单个观测值与算术平均值的偏差的绝对值的平均。平均绝对误差可以避免误差相互抵消的问题,因而可以准确反映实际预测误差的大小。平均绝对误差是绝对误差的平均值,平均绝对误差能更好地反映预测值误差的实际情况。
m
a
e
=
1
n
∑
i
=
1
n
∣
y
i
^
−
y
i
∣
mae=\dfrac{1}{n}\sum_{i=1}^{n}|\hat{y_i}-y_i|
mae=n1i=1∑n∣yi^−yi∣
代码演示
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error
data = load_boston()
x = data.data
y = data.target
model = LinearRegression()
model.fit(x, y)
y_ = model.predict(x)
print('均绝对值误差:', mean_absolute_error(y, y_))
结果输出
均方误差: 21.894831181729206
2.4R方
上面的集中评估指标中,不能够将评估的结果值规定到一个范围之间,mse等评估指标没有上限。所以,在评测模型效果的时候,使用mse等信息不能够很好的评估模型的效果,这个时候我们需要一个能够量化的指标,这就是R方(取值范围在0-1之间)。
如果没有回归模型,一般都是使用均值作为预测效果的。所以,我们在这里就认为回归的模型效果要不均值预测的效果要好,所以我们使用均值和模型预测值进行对比,选用的方式就是使用mse和方差值进行对比,如果mse足够小,经过公式处理以后的结果值就会越接近于1,反之就会越接近0
R
2
=
1
−
m
s
e
v
a
r
=
1
−
1
n
∑
i
=
1
n
(
y
i
^
−
y
i
)
2
1
n
∑
i
=
1
n
(
y
i
ˉ
−
y
i
)
2
R^2=1-\dfrac{mse}{var}=1-\dfrac{\dfrac{1}{n}\sum_{i=1}^n(\hat{y_i}-y_i)^2}{\dfrac{1}{n}\sum_{i=1}^n(\bar {y_i} - y_i)^2}
R2=1−varmse=1−n1∑i=1n(yiˉ−yi)2n1∑i=1n(yi^−yi)2
代码演示
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
data = load_boston()
x = data.data
y = data.target
model = LinearRegression()
model.fit(x, y)
y_ = model.predict(x)
print('均绝对值误差:', r2_score(y, y_))
结果输出
均绝对值误差: 0.7406426641094094
03分类模型评估指标
3.1混淆矩阵
混淆矩阵是用来判定实际值(label)和预测值(predict)之间关系的一种方式,可以用来判断预测效果。
最早是用来对二分类数据进行分析,有的时候更关注与正类别或者负类别,这个时候,我们就可以通过混淆矩阵来进行分析查找了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ETWKDyWo-1589287054529)(E:\八维\平时工作内容\专高工作进度\进度任务\模型选择及模型评估\图片4.png)]
TP: 将正类预测为正类数
FN: 将正类预测为负类数
FP: 将负类预测为正类数
TN: 将负类预测为负类数
通过混淆矩阵,就可以对分类后的效果进行合理的评测了
3.2准确率accuracy
预测正确的样本除以全部样本的数值,可以用在二分类和多分类的模型评测上。是分类模型的默认输出值
a
c
c
u
r
a
c
y
=
T
P
+
T
N
T
P
+
T
N
+
F
P
+
F
N
accuracy = \dfrac{TP+TN}{TP+TN+FP+FN}
accuracy=TP+TN+FP+FNTP+TN
代码演示
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
x = [[1, 2],
[2, 3],
[3, 1],
[4, 3],
[5, 3],
[6, 2]]
y = [[0],
[0],
[0],
[1],
[1],
[1]]
model = LogisticRegression()
model.fit(x, y)
y_ = model.predict(x)
print('准确率:', accuracy_score(y, y_))
结果输出
准确率: 0.8333333333333334
3.3精确率,查准率
描述预测出正类别的准确率,可以检测负样本混入的评测指标
p
r
e
c
i
s
i
o
n
=
T
P
T
P
+
F
P
precision = \dfrac{TP}{TP+FP}
precision=TP+FPTP
代码演示
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import precision_score
x = [[1, 2],
[2, 3],
[3, 1],
[4, 3],
[5, 3],
[6, 2]]
y = [[0],
[0],
[0],
[1],
[1],
[1]]
model = LogisticRegression()
model.fit(x, y)
y_ = model.predict(x)
print('精确率:', precision_score(y, y_))
结果输出
精确率: 0.75
3.4召回率,查全率
描述真实正类别被预测正确的比例
r
e
c
a
l
l
=
T
P
T
P
+
F
N
recall = \dfrac{TP}{TP+FN}
recall=TP+FNTP
代码演示
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import recall_score
x = [[1, 2],
[2, 3],
[3, 1],
[4, 3],
[5, 3],
[6, 2]]
y = [[0],
[0],
[0],
[1],
[1],
[1]]
model = LogisticRegression()
model.fit(x, y)
y_ = model.predict(x)
print('召回率:', recall_score(y, y_))
结果输出
召回率: 1.0
3.5F1数值
因为在实际的使用中,精确率和召回率不能单独的评测模型的效果,所以就使用F1指标来评测二分类的效果
F
1
=
2
p
r
e
c
i
s
i
o
n
⋅
r
e
c
a
l
l
p
r
e
c
i
s
i
o
n
+
r
e
c
a
l
l
F1 = 2 \dfrac{precision·recall}{precision+recall}
F1=2precision+recallprecision⋅recall
代码演示
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score
x = [[1, 2],
[2, 3],
[3, 1],
[4, 3],
[5, 3],
[6, 2]]
y = [[0],
[0],
[0],
[1],
[1],
[1]]
model = LogisticRegression()
model.fit(x, y)
y_ = model.predict(x)
print('f1得分:', f1_score(y, y_))
结果输出
f1得分: 0.8571428571428571
3.6ROC曲线
ROC全称是“受试者工作特征”(Receiver Operating Characteristic)。ROC曲线的面积就是AUC(Area
Under the Curve)。AUC用于衡量“二分类问题”机器学习算法性能(泛化能力)
分别采用不同的阈值,来查看对应的TPR和FPR的数值,从而绘制的一条曲线
T
P
R
=
T
P
T
P
+
F
N
TPR=\dfrac{TP}{TP+FN}
TPR=TP+FNTP
F P R = F P T N + F P FPR=\dfrac{FP}{TN+FP} FPR=TN+FPFP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dVnad3gj-1589287054530)(E:\八维\平时工作内容\专高工作进度\进度任务\模型选择及模型评估\图片5.png)]
代码演示
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve
import matplotlib.pyplot as plt
x = [[1, 2],
[2, 3],
[3, 1],
[4, 3],
[5, 3],
[6, 2]]
y = [[0],
[0],
[0],
[1],
[1],
[1]]
model = LogisticRegression()
model.fit(x, y)
y_score = model.predict_proba(x)[:, -1]
fpr, tpr, th = roc_curve(y, y_score)
plt.plot(fpr, tpr)
plt.savefig('1.jpg')
plt.show()
结果输出
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLZxnD0Q-1589287054532)(E:\八维\平时工作内容\专高工作进度\进度任务\模型选择及模型评估\1.jpg)]
3.7AUC得分
一般情况下,如果按照上图一样,有两条线(实现和虚线),如何来评测ROC曲线的优劣呢?这个时候就要借助AUC得分了,AUC得分是通过ROC曲线和X,Y轴围城的面积来确定的,最大值为1,最小值为0
代码演示
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
import matplotlib.pyplot as plt
x = [[1, 2],
[2, 3],
[3, 1],
[4, 3],
[5, 3],
[6, 2]]
y = [[0],
[0],
[0],
[1],
[1],
[1]]
model = LogisticRegression()
model.fit(x, y)
y_score = model.predict_proba(x)[:, -1]
score = roc_auc_score(y, y_score)
print('auc得分:', score)
结果输出
auc得分: 0.888888888888889
04聚类模型评估指标
4.1误差平方和
SSE(sumof the squared errors,误差平方和)
SSE是所有样本的聚类误差,代表了聚类效果的好坏
S
S
E
=
∑
i
=
1
k
∑
x
∈
C
i
∣
∣
x
−
μ
i
∣
∣
2
SSE=\sum_{i=1}^k\sum_{x\in C_i}||x-\mu_i||^2
SSE=i=1∑kx∈Ci∑∣∣x−μi∣∣2
Ci是第i个簇,x是Ci中的样本点,μi是Ci的质心(Ci中所有样本的均值),k代表每个聚类的样本数量
4.2轮廓系数
簇内不相似度:计算样本i到同簇其它样本的平均距离为ai,ai越小,表示样本i越应该被聚类到该簇,簇C中的所有样本的ai的均值被称为簇C的凝聚度。
簇间不相似度:计算样本i到其它簇Cj的所有样本的平均距离bij,bi=min{bi1,bi2,…,bik};bi越大,表示样本i越不属于其它簇。
轮廓系数:si值取值范围为[-1,1],越接近1表示样本i聚类越合理,越接近-1,表示样本i应该分类到另外的簇中,近似为0,表示样本i应该在边界上;所有样本的si的均值被称为聚类结果的轮廓系数。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YQGi4HdB-1589287054532)(E:\八维\平时工作内容\专高工作进度\进度任务\模型选择及模型评估\20181022184523301.jpg)]
ore)
**结果输出**
auc得分: 0.888888888888889
## 04聚类模型评估指标
### 4.1误差平方和
SSE(sumof the squared errors,误差平方和)
SSE是所有样本的聚类误差,代表了聚类效果的好坏
$$
SSE=\sum_{i=1}^k\sum_{x\in C_i}||x-\mu_i||^2
$$
Ci是第i个簇,x是Ci中的样本点,μi是Ci的质心(Ci中所有样本的均值),k代表每个聚类的样本数量
### 4.2轮廓系数
簇内不相似度:计算样本i到同簇其它样本的平均距离为ai,ai越小,表示样本i越应该被聚类到该簇,簇C中的所有样本的ai的均值被称为簇C的凝聚度。
簇间不相似度:计算样本i到其它簇Cj的所有样本的平均距离bij,bi=min{bi1,bi2,...,bik};bi越大,表示样本i越不属于其它簇。
轮廓系数:si值取值范围为[-1,1],越接近1表示样本i聚类越合理,越接近-1,表示样本i应该分类到另外的簇中,近似为0,表示样本i应该在边界上;所有样本的si的均值被称为聚类结果的轮廓系数。
[外链图片转存中...(img-YQGi4HdB-1589287054532)]