Python3入门机器学习
2.3 训练数据集,测试数据集
(1).判断机器学习算法的性能:
思考这样一个问题,如果所有原始数据都当做训练数据,训练出一个模型,然后用这个模型预测新来的数据所属的类型。训练得到的模型的意义在于在真实环境中使用,但是如果得到的模型很差怎么办?真实的环境难以拿到真实的label(标签)怎么办?以上问题都在告诉我们,其实我们用所有的原始数据都去当训练集来直接训练出模型投入到生产的环境中,这样的做法是不恰当的。
那么如何改进这个问题?改进这个问题的一个最简单的方法被称之为是训练和测试数据集的分离。做法是:只从原始数据中抽出一大部分当做是训练数据,留出来一部分数据作为测试数据。我们只用训练数据来训练出模型,测试数据不参与模型的训练,而是将测试数据丢进模型来让模型预测。由于测试数据本身还包含真实的label值,我们就很容易地看出使用训练数据训练出的模型它的性能是怎样的。也就是说我们可以通过测试数据直接判断模型好坏,如果一旦模型不好,我们在模型进入真实环境前还可以改进模型,直到模型在测试数据中表现出相对好的性能。这样一种方式被称作“train test split”,也就是训练数据集和测试数据集的一个分离。如下图所示:
(2).“train test split”的代码实现:
首先我们需要准备数据集,这次我们使用sklearn提供的鸢尾花的数据集,如下:
我们可以挑选这些数据的20%作为测试数据,通过观察结果标签y,如下:
我们发现,这些鸢尾花的种类是按顺序排列的,所以我们首先需要打乱顺序,再挑选20%作为测试数据。
shuffle_indexes = np.random.permutation(len(X))
形成150个索引的乱序随机排序。
test_ratio = 0.2
test_size = int(len(X) * test_ratio)
设置测试数据所占的比例,这里设置为0.2。然后通过比例,计算出测试数据的大小。
test_indexes = shuffle_indexes[:test_size]
train_indexes = shuffle_indexes[test_size:]
得到测试数据的大小为30,然后将前30个数据设置为测试数据集,将后120个数据设置为训练数据集。
X_train = X[train_indexes]
y_train = y[train_indexes]
X_test = X[test_indexes]
y_test = y[test_indexes]
分别得到测试数据和训练数据的特征矩阵及标签。
(3).封装:
将以上的逻辑封装成一个函数,函数名就叫做“train_test_split”:
import numpy as np
def train_test_split(X, y, test_ratio=0.2, seed=None):
'''将数据 X 和 y 按照test_ratio分割成X_train, X_test, y_train, y_test'''
assert X.shape[0] == y.shape[0], \
"this size of X must be equal to the size of y"
assert 0.0 <= test_ratio <=1.0, \
"test_ratio must be valid"
if seed:
np.random.seed(seed) #由于函数中使用了随机化的过程,有时候我们在debug的时候希望前后两次调用这个函数产生的结果是一致的
#所以我们设置seed这样一个参数,默认为None。如果用户传来具体的数,就作为随机种子。
shuffled_indexes = np.random.permutation(len(X))
test_size = int(len(X) * test_ratio)
test_indexes = shuffled_indexes[:test_size]
train_indexes = shuffled_indexes[test_size:]
X_train = X[train_indexes]
y_train = y[train_indexes]
X_test = X[test_indexes]
y_test = y[test_indexes]
return X_train, X_test, y_train, y_test
(4).使用我们自己封装的算法:
(5).sklearn中的train_test_split: