统计学习:模型评估与选择--留出法(python实现)

使用测试集来测试学习器对新样本的判别能力,然后在测试集上的“测试误差”作为泛化误差的近似,且假设测试样本是从样本真实分布中独立同分布采用而得。这样的目的也就是利用测试样本模拟真实模型应用场景,看下模型对于现实的数据预测能力如何。
因此,测试样本应该尽可能地与训练集互斥,即测试样本尽量不出现在训练集中
常见的方法:留出法、交叉验证法、自助法
留出法的具体做法就是:直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T。理论上应该S集合∩T集合为空集。在使用留出法时,一般采用若干次的随即划分、重复进行实验评估后取平均值作为留出法的评估结果。注意划分时要保证数据的一致性
留出法的缺点:如果令训练集S包含绝大多数样本,则训练出来的模型可能更加接近D(原样本集的模型),但是T验证集比较小,评估结果可能不够准确稳定。如果测试集T多包含一些样本,那么训练集S和D差别更大了降低了模型的保真性。常见的做法是大约2/3~4/5的样本用于训练
本次训练使用鸢尾花数据集,鸢尾花数据集最初由Edgar Anderson 测量得到,而后在著名的统计学家和生物学家R.A Fisher于1936年发表的文章「The use of multiple measurements in taxonomic problems」中被使用,用其作为线性判别分析(Linear Discriminant Analysis)的一个例子,证明分类的统计方法,从此而被众人所知,尤其是在机器学习这个领域。
代码如下,使用逻辑回归模型作为训练模型:

import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets # 导入数据集
# 导入数据集划分工具
from sklearn.model_selection import train_test_split
# 标准化
from sklearn.preprocessing import StandardScaler
# 导入模型
from sklearn.linear_model import LogisticRegression
# 导入数据集
iris = datasets.load_iris()
# 将模型分为数据和标签
X, target = iris.data, iris.target
# 数据标准化,计算数据的平均值和标准偏差
X = StandardScaler().fit_transform(X)


def model_learn(X, arg_model):
    random_samples = []
    # 训练样本精度
    train_precision = []
    # 测试样本精度
    test_precision = []

    for i in range(100):
        # 对数据集进行100此随机划分,20%验证集,80%训练集
        X_train, X_test, y_train, y_test = train_test_split(X, target, test_size=0.2,
                                                                  random_state=i, shuffle=True, stratify=target)
        random_samples.append([len(y_test[y_test == 0]),
                               len(y_test[y_test == 1]), len(y_test[y_test == 2])])
        # print(len(random_samples)) 查看测试机样本数量
        # 多分类训练与测试
        model = arg_model()
        model.fit(X_train, y_train)
        # 训练样本预测 --经验误差
        y_pre_train = model.predict(X_train)
        # 测试样本预测 --泛化误差
        y_pre_test = model.predict(X_test)
        train_correct = 0
        for j, y in enumerate(y_pre_train):
            if y == y_train[j]:
                train_correct += 1
        train_precision.append(train_correct/len(y_pre_train))

        test_correct = 0
        for j, y in enumerate(y_pre_test):
            if y == y_test[j]:
                test_correct += 1
        test_precision.append(train_correct/len(y_pre_train))

    print("训练精度:%.5f" % np.mean(train_precision))
    print("测试精度:%.5f" % np.mean(test_precision))
    return train_precision, test_precision


def plt_precision(train_precision, test_precision):
    fig, ax = plt.subplots(1, 2, figsize=(12, 4))
    ax[0].plot(train_precision, 'r.-')
    ax[0].set_title("mean of train_precision = {:.5f}".format(np.mean(train_precision)))
    ax[0].set_xlabel("random split number")
    ax[0].set_ylabel("train_precision")
    ax[0].grid()

    ax[1].plot(test_precision, '.-')
    ax[1].set_title("mean of test_precision = {:.5f}".format(np.mean(test_precision)))
    ax[1].set_xlabel("random split number")
    ax[1].set_ylabel("test_precision")
    ax[1].grid()

    plt.show()


if __name__ == "__main__":
    train_precision, test_precision = model_learn(X, LogisticRegression)
    plt_precision(train_precision, test_precision)

程序运行效果如图:
另外还可以尝试其他不同的模型来进行训练
统计学习:模型评估与选择--留出法(python实现)_第1张图片

你可能感兴趣的:(统计学习方法,python,机器学习,数据挖掘)