赞
踩
在完成特征选择之后,我们就可以用选择的特征来训练算法了,且能够得出准确度比较高的模型。现在的问题是,训练得到的模型,如何评估是好是坏呢?
这就牵涉到本篇涉及的话题:模型选择。
建立完模型,要去评估模型,这是机器学习流程必不可少的一部分,本篇就来讲讲如何评估模型的性能。
在这里有个关键词叫重采样,其实含义就是用新的数据集来评估算法,也即训练集之外的数据,这实在太熟悉,也讲了太多次,从各个角度讲过。
这里直接讲四种不同的分离数据集的方法:
这是最简单的方法,即将数据集完全分为训练集和测试集,并用测试集来评估模型。一般会将数据分为67%和33%,前者训练,后者评估,其实是挺浪费的分法。
# 算法评估 # 直接分离数据集 from pandas import read_csv from sklearn.model_selection import train_test_split # 数据集分割是为了模型选择,所以可以反向思考包划分的原因 from sklearn.linear_model import LogisticRegression # 导入数据 filename = 'pima_data.csv' names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] data = read_csv(filename, names=names) # 数据分割 array = data.values X = array[:, 0:8] y = array[:, 8] test_size = 0.33 seed = 4 # 人工指定随机种子是保证每次执行效果都一样 X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=test_size, random_state=seed) # 定义模型 model = LogisticRegression() model.fit(X_train, y_train) # result = model.predict(X_test) result = model.score(X_test, y_test) print("算法评估结果:%.3f%%" % (result * 100)) # 算法评估结果:80.315%
所以可以看出来,这个执行的流程非常清晰,值得细细品味,举一反三,其他模型的使用也是一样的道理。
也称之为循环估计。
K折交叉验证的方法是将原始数据分成K组,每组都会用做一次测试集,其余的K-1组作为训练集,这样的话,就意味着我们会训练K次,验证K次,得到K个模型。得出的K个准确率,做一下平均 ,就作为最终的此模型的性能指标。
实际运用时,K的取值大于2,一般从3开始取值,数据量比较小时,可以考虑取2看看。
通常会取值为3,5,10等。
#### K折交叉验证 from pandas import read_csv from sklearn.model_selection import KFold from sklearn.model_selection import cross_val_score # 交叉验证 from sklearn.linear_model import LogisticRegression # 导入数据 filename = 'pima_data.csv' names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] data = read_csv(filename, names=names) # 数据划分 array = data.values X = array[:, 0:8] y = array[:, 8] num_folds = 10 # 10折 seed = 7 kfold = KFold(n_splits=num_folds, random_state=seed) model = LogisticRegression() result = cross_val_score(model, X, y, cv=kfold) # 传递模型,特征,目标值,k折对象 print("算法评估结果:%.3f%% (%.3f%%)" % (result.mean() * 100, result.std() * 100)) # 算法评估结果:76.951% (4.841%) result.shape # 10折意味着10个结果 # (10,)
这是K交叉验证的特例,也即数据有N个样本,需要搞N轮,每轮一个数据样本用来测试,N-1个样本用来训练。也是用N个模型的均值作为总体的性能评估。
好处是:
缺点就是计算成本高。
#### 留一法交叉验证 from pandas import read_csv from sklearn.model_selection import LeaveOneOut from sklearn.model_selection import cross_val_score # 交叉验证 from sklearn.linear_model import LogisticRegression # 导入数据 filename = 'pima_data.csv' names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] data = read_csv(filename, names=names) # 数据划分 array = data.values X = array[:, 0:8] y = array[:, 8] num_folds = 10 # 10折 seed = 7 loocv = LeaveOneOut() model = LogisticRegression() result = cross_val_score(model, X, y, cv=loocv) # 传递模型,特征,目标值,留一对象 print("算法评估结果:%.3f%% (%.3f%%)" % (result.mean() * 100, result.std() * 100)) # 算法评估结果:76.823% (42.196%)
留一法得出的结果里,方差很大。
现在讲最后的这种分离方法,和K折交叉验证效果相同。
#### 随机分离 from pandas import read_csv from sklearn.model_selection import ShuffleSplit from sklearn.model_selection import cross_val_score # 交叉验证 from sklearn.linear_model import LogisticRegression # 导入数据 filename = 'pima_data.csv' names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] data = read_csv(filename, names=names) # 数据划分 array = data.values X = array[:, 0:8] y = array[:, 8] n_splits = 10 # 10折 test_size = 0.33 seed = 7 kfold = ShuffleSplit(n_splits=n_splits, test_size=test_size, random_state=seed) model = LogisticRegression() result = cross_val_score(model, X, y, cv=kfold) print("算法评估结果:%.3f%% (%.3f%%)" % (result.mean() * 100, result.std() * 100)) # 算法评估结果:76.535% (1.672%)
选择数据分离的指导准则:
最黄金的准则是:不知道用什么时用K折交叉验证,不知道K值设置为多少时,设置为10。
具体的JupterNotebook: https://github.com/Bingyy/MachineLearning/blob/master/FeatureEngineeringAndModelSelection.ipynb
END.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。