【说明】文章内容来自《机器学习入门——基于sklearn》,用于学习记录。若有争议联系删除。
1、数据划分
在机器学习中,通常将数据集划分为训练集和测试集。训练集用于训练数据,生成机器学习模型;测试集用于评估学习模型的泛化性能和有效程度。
数据划分一般有留出法、交叉验证法和自助法。
1.1留出法
留出法(hold-out)是将已知数据集分成两个互斥的部分:一部分用来训练模型;另一部分用来测试模型,评估其误差。留出法的稳定性较差,通常会进行若干次随机划分,重复进行评估,取平均值作为评估结果。
留出法具有如下优点:
- 实现简单、方便,在一定程度上能评估泛化误差。
- 训练集和测试集分开,缓解了过拟合问题。
留出法具有如下缺点:
- 数据都只被使用了一次,没有得到充分利用。
- 在测试集上计算出来的最后的评估指标与原始分组有很大关系,
一般情况下,数据划分的大致比例是:训练集占70%~80%,测试集占20%~30%。测试数据不参与训练,只用于评估模型与数据的匹配程度。
train_test_split函数随机从样本中按比例选取训练数据和测试数据,语法形式为
x_train, x _test, y_train, y_test=sklearn.model_selection.train _test _split
(train data,train target, test_size,random state)
【参数说明】
- train_data:待划分的样本数据
- train_target:待划分样本数据的结果(标签)
- test_size:测试数据占样本的比例。若为整数,则表示样本数量。若test_size= 0.3,表示将样本数据的30%作为测试集,计入x_test;其余70%数据记入x_train。
- random_state:随机种子,保证每次都是同一个随机数,若为0或不填,每次生成随机数都不同。
- x_train:划分出的训练集数据(特征值)
- x_test:划分成的测试集数据(特征值)
- y_train:划分出的训练集标签(目标值)
- y_test:划分出的测试集标签(目标值)
示例:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
#获取鸢尾花数据集
iris = load_iris()
#test_size 默认取值为25%,test_size取值为0.2,随机种子为22
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size = 0.2, random_state = 22)
print('训练集的特征值:\n', x_train, x_train.shape)
1.2 交叉验证法
根据数据集大小的不同和数据类别不同,交叉验证法分为3种。
(1)留一交叉验证法
当数据集较小时,采用留一交叉验证法。留一交叉验证法是指数据集划分数量等于样本量,这样每次只有一个样本用于测试。留一交叉验证法是K折交叉验证法的特殊形式,较为简单,随机采样一定比例作为训练集,剩下的作为测试集使用。
(2)K折交叉验证法
当数据集较大时,采用K折交叉验证法。K折是指对数据集进行K次划分,使得所有数据在训练集和测试集中都出现,但每次划分不会重叠,相当于无放回抽样。
K折交叉验证法使用FKold函数
语法:Fkold(n_splits, shuffle, random_state)
参数说明:
- n_splits:表示划分为几等分(至少是2)
- shuffle:表示是否进行洗牌,即是否打乱划分。默认为fales,既不打乱。
- random_state:随机种子数
当采用K折交叉验证时,需要使用以下两个方法:
- get_n_splits([X,y,groups]):获取参数n_splits的值
- split(X,[Y,group]):将数据集划分为训练集和测试集,返回索引生成器。
Kfold示例
import numpy as np
from sklearn.model_selection import KFold
X = np.array([[1,2],[3,4],[1,2],[3,4]])
#kf = KFold(n_splits = 2)
print(kf.get_n_splits(X))
for train_index, test_index in kf.split(X):
print('train:\n',train_index,'test:\n',test_index)
(3)分层交叉验证法
在构建模型时,调参是极为重要的步骤,只有选择最佳的参数,才能构建最优的模型。Sklearn 提供了cross_val_score函数一一以实现调参,将数据集划分为k个大小接近的互斥子集,然后每次用k一1个子集的并集作为训练集,将余下的子集作为测试集,如此反复进行k次训练和测试,返回k个测试结果的平均值。例如,10次10折交叉验证法是将数据集分成10份,轮流将其中9份作为训练数据,将剩余1份作为测试数据,这样迭代10次。通过传入的模型训练10次,最终对10次结果求平均值。
cross_val_score函数的语法形式如下:
cross_val_score (estimator,train_x,train_y,cv=10)
参数说明如下
- estimator:需要使用交叉验证的算法。
- train_x:输人样本数据。
- train_y:样本标签。
- cv:进行10次训练。
交叉验证法有以下优点:
- 将交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现可以在一定程度上减小过拟合。
- 可以从有限的数据中获取尽可能多的有效信息。
交叉验证示例
from sklearn import datasets
from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
iris = datasets.load_iris()
#加载iris数据集
x = iris.data
y = iris.target
#对应的数据标签
train_x, test_x, train_y, test_y =train_test_split(x, y, test_size = 1/3, random_state = 3)
#以1/3的比列划分训练集的训练结果和测试集的测试结果
k_range = range(1, 31)
cv_scores = []
#用来存放每个模型的结果
for n in k_range:
knn = KNeighborsClassifier(n)
scores = cross_val_score(knn, train_x, train_y, cv = 10)
#采用knn算法进行交叉验证,进行10 次训练
cv_scores.append(scores.mean())
plt.plot(k_range, cv_scores)
plt.xlabel('k')
plt.ylabel('Accuracy')
plt.show()
best_knn = KNeighborsClassifier(n_neighbors = 3)
#选择最优的k = 3传入模型
best_knn.fit(train_x, train_y)
#训练模型
print('score:\n',best_knn.score(test_x, test_y))
【运行结果】
1.3 自助法
自助法是一种产生样本的抽样方法,其实质是有放回的随机抽样,自助法从数据集中随机抽取记录用于测试集,然后将其放回原数据集,继续下一次随机抽样,直到测试集中的数据条数满足要求为止。
语法:
ShuffleSplit(n_split, test_size, train_size, random_state)
参数说明:
- n_splits:表示划分为几块(至少是2)
- test_size: 测试集比例或样本数量
- train_size:训练集比列或样本数量
- random_state;随机种子数,默认为None
示例
import numpy as np
from sklearn.model_selection import ShuffleSplit
x = np.arange(5)
ss = ShuffleSplit(n_splits = 3, test_size = .25, random_state = 0)
for train_index, test_index in ss.split(x):
print('TRAIN', train_index, 'TEST', test_index)
2、数据划分方法的选择原则
- 当数据集较大时,通常采用留出法或者K折交叉验证法
- 当数据集较小且难以有效划分训练集和测试集时,采用自助法
- 当数据集较小且可以有效划分训练集和测试集时,采用留一交叉验证法。