实验二:模型评估与选择(1)


实验二:模型评估与选择(1)

熟悉训练集-测试集划分、流水线和交叉验证函数的使用

训练集-测试集划分函数

1
2
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size, stratify, random_state)

输入参数:

参数 意义
test_size 0~1 的小数:测试集占原始样本比例;整数:测试集样本数
stratify 保持划分前的分布(各类样本的占比保持不变)
random_state 随机数种子

返回值:

返回值 意义
X_train 划分出的训练集数据
X_test 划分出的测试集数据
y_train 划分出的训练集标签
y_test 划分出的测试集标签

流水线函数

流水线

1
2
from sklearn.pipeline import make_pipeline
pipe_lr = make_pipeline(*steps, **kwargs)

输入参数:

参数 意义
*steps 需要串联的估计器(estimators)
**kwargs 一些关键词参数(memory,verbose)

返回值:

返回值 意义
p 返回一个 Pipeline 对象

如示例程序中:

1
2
3
4
5
6
7
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
pipe_lr = make_pipeline(StandardScaler(),
PCA(n_components=2),
LogisticRegression(random_state=1, solver='lbfgs'))

pipe_lr 为 Pipeline 类的一个实例,其步骤为:

  1. 标准化处理(StandardScaler)
  2. 主成分分析、特征降维(PCA)
  3. 逻辑回归(LogisticRegression)

交叉验证函数

交叉验证

K折交叉验证

1
2
from sklearn.model_selection import cross_val_score
scores = cross_val_score(estimator, X, y=None, *, groups=None, scoring=None, cv=None, n_jobs=None, verbose=0, fit_params=None, pre_dispatch='2*n_jobs', error_score=nan)

输入参数:

参数 意义
estimator 估计器
X,y 训练集
cv 交叉验证的折数(默认 5 折)
n_jobs 同时使用的处理器个数(默认一般为 1,-1 为全部使用)

返回值:

返回值 意义
scores 每次交叉验证的估计器的准确率

熟悉学习曲线的使用

学习曲线

学习曲线:在训练集和验证集上,关于训练数据规模的性能曲线。用于调试算法

熟悉函数

1
2
3
4
5
6
7
8
from sklearn.model_selection import learning_curve
train_sizes, train_scores, test_scores =\
learning_curve(estimator=pipe_lr,
X=X_train,
y=y_train,
train_sizes=np.linspace(0.1, 1.0, 10),
cv=10,
n_jobs=1)

输入参数:

参数 意义
estimator 估计器
X,y 训练集
train_sizes 训练集的数量,用于生成学习曲线横坐标
cv 交叉验证的折数(默认 5 折)
n_jobs 同时使用的处理器个数(默认一般为 1,-1 为全部使用)

返回值:

返回值 意义
train_sizes 已用于生成学习曲线的训练示例数
train_scores 训练集得分
test_scores 测试集得分

修改参数实验

进行 20 次训练(train_sizes=np.linspace(0.1, 1.0, 20)

CV=2

CV=5

CV=10

CV=15

实验结果:

  • 训练集上,CV 越大,偏差越大,方差越小
  • 测试集上,CV 越大,偏差越小,方差越大

因为 CV 越大,用于训练的样本越多,误差增大,因此训练准确率会下降、方差变小,而测试集样本变少,测试的方差变大。

就基础代码实际使用的数据而言,模型拟合效果不错,CV 取 5~10 时,偏差和方差都较小

熟悉验证曲线的使用

验证曲线(拟合图):反映模型泛化性能(测试误差)与模型复杂度关系的曲线,用于模型选择。

要防止过拟合,就需要进行模型选择:选择复杂度适当的模型,以达到使测试误差最小的学习目的。

熟悉函数

1
2
3
4
5
6
7
8
from sklearn.model_selection import validation_curve
train_scores, test_scores = validation_curve(
estimator=pipe_lr,
X=X_train,
y=y_train,
param_name='logisticregression__C',
param_range=param_range,
cv=5)

输入参数:

参数 意义
estimator 估计器
X,y 训练集
param_name 自变量名称
param_range 自变量
cv 交叉验证的折数(默认 5 折)

返回值:

返回值 意义
train_scores 训练集得分
test_scores 测试集得分

修改参数实验

逻辑回归

修改为:param_range = [0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0, 10000.0]

CV=5

CV=10

CV=15

实验结果:

  • CV 取 5~10 较好
  • C 取 10 较好

KNN

修改代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sklearn.neighbors import KNeighborsClassifier
pipe_lr = make_pipeline(StandardScaler(),
KNeighborsClassifier(n_neighbors=1))

param_range = [1,3,5,7,9,13,17]
train_scores, test_scores = validation_curve(
estimator=pipe_lr,
X=X_train,
y=y_train,
param_name='kneighborsclassifier__n_neighbors',
param_range=param_range,
cv=5)

"""
param_range = [0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0, 10000.0]
train_scores, test_scores = validation_curve(
estimator=pipe_lr,
X=X_train,
y=y_train,
param_name='logisticregression__C',
param_range=param_range,
cv=15,)
"""

第 54~60 行:

1
2
3
4
5
6
7
plt.grid()
#plt.xscale('log')
plt.xscale('linear')

plt.legend(loc='lower right')
#plt.xlabel('Parameter C')
plt.xlabel('n_neighbors')

CV=5

CV=10

CV=15

实验结果:

  • CV 取 5~10 较好
  • C 取 9 较好