交叉验证
交叉验证是一种评估泛化能力性能的统计学方法,它比单次划分训练集和测试集的方法更加稳定、全面。交叉验证就是重复的利用数据集,把样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏。
使用交叉验证而不是将数据单次划分为训练集和测试集,这种做法具有一下优点:
1、train_test_split对数据进行随机划分。想象一下,在随机划分数据时我们很幸运,所有难分的样本都在训练集,这种情况下,测试集将包含容易分类的样本,并且测试集的分类精度会偏高。相反,难分的样本都在测试集,那么测试集的分类精度会偏低。如果使用交叉验证,每个样本都刚好测试集中出现一次,因此模型需要对数据集中所有样本的泛化能力都很好,才能让所有的交叉验证得分都很高。
2、对数据的使用更加高效。在使用train_test_split时,我们通常将80%的样本用于训练,20%的样本用于测试。在10折交叉验证中,90%的样本用于训练,10%的样本用于测试。更多的数据通常可以得到更为精准的模型。
常见的交叉验证方式有以下三种:
第一种是简单交叉验证。首先,随机的将样本数据分为两部分(比如: 80%的样本作为训练集,20%的样本作为测试集),然后用训练集来训练模型,在测试集上验证模型及参数。然后,再把样本进行随机排序后,重新选择训练集(80%)和测试集(20%),继续训练数据和测试模型。
第二种是K折交叉验证(K-Folder Cross Validation)。K折交叉验证会把样本数据随机的分成K份,每次随机的选择K-1份作为训练集,剩下的1份做测试集。此次训练结束,重新选择K-1份来训练数据。
第三种是留一交叉验证(Leave-one-out Cross Validation),它是第二种情况的特例,此时K等于样本数N,这样对于N个样本,每次选择N-1个样本来训练数据,留一个样本来验证模型预测的好坏。
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_digits
from sklearn.linear_model import LogisticRegression
digits = load_digits()
x = digits.data
y = digits.target
lr = LogisticRegression()
scores = cross_val_score(lr, x, y, cv=5)
print(scores.mean())
from sklearn.datasets import load_iris
from sklearn.model_selection import KFold
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import numpy as np
data = load_iris()
x = data.data
y = data.target
kf = KFold(n_splits=5, shuffle=True, random_state=0)
lr = LogisticRegression()
scores = []
for item in kf.split(x, y):
x_train = x[item[0]]
y_train = y[item[0]]
x_test = x[item[1]]
y_test = y[item[1]]
lr.fit(x_train, y_train)
y_pred = lr.predict(x_test)
scores.append(accuracy_score(y_pred, y_test))
print(np.array(scores).mean())