数据集的划分——Python实现

在建模时一般要将数据集划分为训练集、验证集、测试集

一、为什么要划分?

构建模型的目标是通过在训练集上训练模型,然后在验证集上验证模型的参数效果,最后在测试集上测试模型的泛化能力。
最终的目标是使模型的泛化能力最大化,也就是泛化误差最小化,然而怎样去度量或者近似度量泛化误差呢?

1.训练误差=经验误差(×)

原因:很可能出现过拟合,也有可能出现欠拟合

  • 过拟合:学习器把训练样本学的太好了,以至于把训练样本自身的一些性质作为潜在样本会具有的一般性质,这样会导致泛化性能下降。
  • 欠拟合:训练样本的一般性质尚未学好

2.泛化误差(×)

不可能泛化到所有的可能性

3.测试误差作为泛化误差的近似(✔)

二、怎样划分?

1.留出法(hold-out cross-validation)

  • 要尽可能保持数据分布的一致性,也就是训练集和测试集中样本类别比例是一致的。
  • 一般取2/3~4/5作为训练集。
  • 适用:数据量足够
  • 缺点:只做一次分割且比例是自己确定的、分割后数据分布与原始分布的差异等敏感问题
  • 改进:在验证模型效果的时候,可以随机分割训练集和测试集,一般随机生成10000次,然后生成模型准确率的分布。这样评估模型效果更加客观。通过分布,可以看到模型表现最差的时候是什么水平,如果最差的情况都可以接受,那模型效果就合格了。
# 选择变量
y=churn['flag']
x=churn[['contract_month','internet_other','streamingtv']]

# 切分训练集与测试集
from sklearn.cross_validation import train_test_split
for i in range(1000):
	X_train, X_test, y_train, y_test = train_test_split(x,y, test_size=0.3)  # 不要设置随机种子random_state保证每次划分的随机性

2.k折交叉验证(K-fold)

  • 一般取10
  • 适用:数据量足够
  • 缺点:k越大越好,但是计算负担大。对数据集的大小有很高的要求。如果数据量不是很足够的话,比如把k设成20,可能测试集里面就没有几个数据了。
(1)sklearn.model_selection
from sklearn.model_selection import StratifiedKFold
sk=StratifiedKFold(n_splits=5,shuffle=True,random_state=0)  
# shuffle=True:先打乱顺序再做划分
# random_state=0(固定值就可以),保证每次的拆分结果是相同的

X_data = Train_data[feature_cols]
Y_data = Train_data['price']

# 将训练集拆分成训练集和验证集validation
for train_ind,val_ind in sk.split(X_data,Y_data):
    train_x=X_data.iloc[train_ind].values
    train_y=Y_data.iloc[train_ind]
    val_x=X_data.iloc[val_ind].values
    val_y=Y_data.iloc[val_ind]
(2)sklearn.cross_validation
from sklearn.cross_validation import KFold
kf = KFold(25, n_folds=5, shuffle=False)
# 其他同上
(3)sklearn.cross_validation
from sklearn.cross_validation import cross_val_score
scores = cross_val_score(knn, X, y, cv=10, scoring='accuracy')
print(scores.mean())

3.自助法bootstrap

  • 问题:改变了初始数据的分布,引入了估计偏差,也就是用改变数据分布带来的误差来弥补数据量少带来的误差。
  • 适用:数据集较小,难以有效划分训练和测试集

你可能感兴趣的:(建模,机器学习)