自学内容网 自学内容网

机器学习-数据集划分

一. 为什么要划分数据集

为了能够评估模型的泛化能力,可以通过实验测试对学习器的泛化能力进行评估,进而做出选择。因此需要使用一个 “测试集” 来测试学习器对新样本的判别能力,以测试集上的 “测试误差” 作为泛化误差的近似。

一般测试集满足:

  • 能代表整个数据集
  • 测试集与训练集互斥
  • 测试集与训练集建议比例: 2比8、3比7 等

二. 数据集划分的方法

1. 留出法:

将数据集划分成两个互斥的集合:训练集,测试集

● 训练集用于模型训练
● 测试集用于模型验证
● 也称之为简单交叉验证

from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import ShuffleSplit
from collections import Counter
from sklearn.datasets import load_iris

#加载数据集
x,y = load_iris(return_X_y=True)
Counter(y)

Counter({0: 50, 1: 50, 2: 50})

#留出法(随机分割)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=0)
Counter(y_train), Counter(y_test)

(Counter({2: 44, 0: 39, 1: 37}), Counter({1: 13, 0: 11, 2: 6}))

#留出法(分层分割)
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=0,stratify=y)
Counter(y_train), Counter(y_test)

(Counter({0: 40, 1: 40, 2: 40}), Counter({0: 10, 1: 10, 2: 10}))

# 多次划分(随机分割)
spliter = ShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
for train,test in spliter.split(x,y):
    print('随机多次分割:', Counter(y[test]))

随机多次分割: Counter({1: 13, 0: 11, 2: 6})
随机多次分割: Counter({1: 12, 2: 10, 0: 8})
随机多次分割: Counter({1: 11, 0: 10, 2: 9})
随机多次分割: Counter({2: 14, 1: 9, 0: 7})
随机多次分割: Counter({2: 13, 0: 12, 1: 5})

# 多次划分(分层分割)
spliter = StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
for train,test in spliter.split(x,y):
    print('随机多次分割:', Counter(y[test]))

随机多次分割: Counter({0: 10, 1: 10, 2: 10})
随机多次分割: Counter({2: 10, 0: 10, 1: 10})
随机多次分割: Counter({0: 10, 1: 10, 2: 10})
随机多次分割: Counter({1: 10, 2: 10, 0: 10})
随机多次分割: Counter({1: 10, 2: 10, 0: 10})

2. 交叉验证:将数据集划分为训练集,验证集,测试集

在这里插入图片描述
K-Fold交叉验证,将数据随机且均匀地分成k分,如上图所示(k为10),假设每份数据的标号为0-9
● 第一次使用标号为0-8的共9份数据来做训练,而使用标号为9的这一份数据来进行测试,得到一个准确率
● 第二次使用标记为1-9的共9份数据进行训练,而使用标号为0的这份数据进行测试,得到第二个准确率
● 以此类推,每次使用9份数据作为训练,而使用剩下的一份数据进行测试
● 共进行10次训练,最后模型的准确率为10次准确率的平均值
● 这样可以避免了数据划分而造成的评估不准确的问题

● 训练集用于模型训练
● 验证集用于参数调整
● 测试集用于模型验证

from sklearn.model_selection import KFold   
from sklearn.model_selection import StratifiedKFold
from sklearn.datasets import load_iris
from collections import Counter

from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import ShuffleSplit
from collections import Counter
from sklearn.datasets import load_iris

#加载数据集
x,y = load_iris(return_X_y=True)
Counter(y)

Counter({0: 50, 1: 50, 2: 50})

#随机交叉验证
spliter = KFold(n_splits=5, shuffle=True, random_state=0)
for tain,test in spliter.split(x,y):
    print('随机交叉验证:', Counter(y[test]))

随机交叉验证: Counter({1: 13, 0: 11, 2: 6})
随机交叉验证: Counter({2: 15, 1: 10, 0: 5})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 14, 2: 10, 1: 6})
随机交叉验证: Counter({1: 11, 0: 10, 2: 9})

#分层交叉验证
spliter = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
for tain,test in spliter.split(x,y):
    print('随机交叉验证:', Counter(y[test]))

随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})
随机交叉验证: Counter({0: 10, 1: 10, 2: 10})

KFold:
划分方式:每一折的数据都是从整个数据集中均匀划分的。例如,5 折交叉验证意味着数据集被划分成 5 个子集,每次验证时选择其中一个子集作为测试集,其余 4 个子集作为训练集。每个样本都会被用作一次验证集。
没有重复样本:每个样本仅会出现在一个折(训练集或验证集)中,不会有重复。
ShuffleSplit:
划分方式:ShuffleSplit 每次都会随机选择训练集和测试集,且训练集和测试集可能会有所重叠,也就是说,某些样本可能会出现在不同的划分中。
重复样本:允许样本在不同的划分中重复出现,因此数据集的某些样本在某次划分中可能作为训练集,而在另一划分中作为测试集。

3. 留一法:

每次从训练数据中抽取一条数据作为测试集

from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import LeavePOut
from sklearn.datasets import load_iris
from collections import Counter

#加载数据集
x,y = load_iris(return_X_y=True)
Counter(y)

Counter({0: 50, 1: 50, 2: 50})

#留一法
spliter = LeaveOneOut()
for train,test in spliter.split(x,y):
    print('训练集:', len(train), '测试集:', len(test), test)

在这里插入图片描述

#留p法
spliter = LeavePOut(p=2)
for train,test in spliter.split(x,y):
    print('训练集:', len(train), '测试集:', len(test), test)

在这里插入图片描述

4. 自助法:

以自助采样(可重复采样、有放回采样)为基础
每次随机从D中抽出一个样本,将其拷贝放入D,然后再将该样本放回初始数据集D中,使得该样本在下次采样时仍有可能被抽到;
这个过程重复执行m次后,我们就得到了包含m个样本的数据集D′,这就是自助采样的结果。

● 在数据集D中随机抽取m个样本作为训练集
● 没被随机抽取到的D-m条数据作为测试集

import pandas as pd

# 1. 构造数据集
data = [[90, 2, 10, 40],
        [60, 4, 15, 45],
        [75, 3, 13, 46],
        [78, 2, 64, 22]]

data = pd.DataFrame(data)
data

在这里插入图片描述

# 2. 产生训练集
'''
这行代码的作用是从 data 数据集中进行有放回的随机抽样,抽样比例为 100%(即 frac=1)。这意味着每次抽样后,数据点会被放回数据集中,因此某些数据点可能会被多次抽样到,而有些数据点可能一次也不会被抽样到。

具体来说:

frac=1 表示抽样的比例为 100%,即抽取的数据量与原数据集相同。
replace=True 表示抽样是有放回的,即每次抽样后数据点会被放回数据集中,允许重复抽样。
这样做的结果是生成一个与原数据集大小相同的新数据集 train,其中可能包含重复的数据点。
'''
train = data.sample(frac=1, replace=True,random_state=0)
print('训练集:\n', train)

print('*' * 30)

# 3. 产生测试集
test = data.loc[data.index.difference(train.index)]
print('测试集:\n', test)

在这里插入图片描述


原文地址:https://blog.csdn.net/weixin_45862390/article/details/145310725

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!