找回密码
 会员注册
查看: 52|回复: 0

python——机器学习:sklearn模型选择model_selection模块函数说明和应用示例

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
71062
发表于 2024-9-5 19:12:35 | 显示全部楼层 |阅读模式
在应用机器学习方法进行模型训练时,需要通过数据切分将数据集分为训练集/验证集/测试集。并且可以通过交叉验证,对模型在验证集上的拟合效果进行预评估,以选择表现最好的模型。此外,可以通过参数网格搜索的方法,确定最优的模型参数。本篇文章通过具体数据做示例,总结了sklearn中模型选择model_selection模块常用函数的使用。包括:1.数据切分:train_test_split2.K折交叉验证:KFold,StratifiedKFold,cross_val_score3.参数网格搜索:GridSearchCV12345一、数据导入导入python自带的wine数据集用于演示。该数据集为一个分类数据集,响应变量y取值为0、1、2.fromsklearnimportdatasetswine_data=datasets.load_wine()X=wine_data.datay=wine_data.targetprint(X.shape)#(178,13)123456二、数据切分sklearn中train_test_split函数用于数据切分。其输入为待切分的特征X和相应变量y。输出按顺序为:切分后的训练集特征X_train,测试集特征X_test,训练集响应变量y_train,测试集响应变量y_test。X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)1train_test_split函数参数说明:train_size:指定训练集大小(整数)/训练集比例(小数)test_size:指定测试集大小(整数)/测试集比例(小数)shuffle:默认值为True,表示在进行数据分割前,先进行数据打乱重排。random_state:随机种子,用来保证每次运行函数时,数据打乱重排的结果是一致的。stratify:用于控对制数据按标签类别进行分层切分。默认值为None,表示随机划分标签。当给定一个array时,将对array中的每个类别按相同的比例切分,此时其取值通常为类别响应变量y。(后面将通过具体实例进行演示)当stratify取默认值None时,运行结果如下:#执行如下代码,测试集占比为0.2,查看划分结果X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)#查看训练集和测试集大小print(X_train.shape,X_test.shape)####输出:(142,13)(36,13)#查看原始数据中标签类别分布,可知标签中有45个值为0,57值为1,40个值为2print(sum(y==0),sum(y==1),sum(y==2))####输出:455740##查看划分后的标签类别分布,可知并不是对标签按比例分割print(sum(y_test==0),sum(y_test==1),sum(y_test==2))####输出:1414812345678910111213实际使用中,如果对数据进行随机切分,可能导致某些数据量较少的类别全部被划分入训练集,影响模型的效果。所以,可以在数据分割时,按标签类别分层切分(取stratify=y),代码如下。#按y分布切分X_train_1,X_test_1,y_train_1,y_test_1=train_test_split(X,y,test_size=0.2,random_state=42,stratify=y)#查看测试集中,各类别标签所占比例print(sum(y_test_1==0)/sum(y==0))print(sum(y_test_1==1)/sum(y==1))print(sum(y_test_1==2)/sum(y==2))####输出:####0.2033898305084746####0.19718309859154928####0.208333333333333341234567891011可见,对每个类别,按0.2的比例切分到了测试集中。三、K折交叉验证K折交叉验证,指将训练数据等分成K个子集,每次选取1个子集作为验证集,其余K-1个子集作为训练集。该过程重复K次。KFold用于定义一个K折交叉验证。参数n_splits表示切分份数,其它参数含义同数据切分部分。如定义一个5折交叉验证:fromsklearn.model_selectionimportKFold,StratifiedKFoldn_splits=5kf=KFold(n_splits,shuffle=True,random_state=42)123其方法有get_n_splits()、split()。get_n_splits()返回切分的数量,split()返回每个子集中的数据在原数据集中的位置标识。应用方法和结果如下:kf_n=KFold(n_splits,shuffle=True,random_state=42).get_n_splits(X,y)print(kf_n)####输出:5123kf_array=KFold(k,shuffle=True,random_state=42).split(X,y)fortrain_index,test_indexinKFold(k,shuffle=True,random_state=42).split(X,y):#打印下标#print("TRAIN:",train_index,"TEST:",test_index)print("TEST:",test_index)#提取每次切分后训练集和验证集数据X_train,X_test=X[train_index],X[test_index]y_train,y_test=y[train_index],y[test_index]12345678输出的每次验证集下标如下所示。可以看到,每次迭代验证集的数据量是总量的1/5,且5次迭代的验证集下标无重复。StratifiedKFold其使用方法同KFold,其作用是,按y各类别的比例切分。同第二节中,train_test_split的参数stratify=y的情况。cross_val_score该函数用于直接计算K折交叉验证的模型得分。这个得分对所有内置的评分函数,都是得分越高,说明模型拟合越好。该函数的返回值是长度为K的list,为K次迭代在验证集上的模型得分。如我们构建一个随机森林模型:fromsklearn.ensembleimportRandomForestClassifierrf=RandomForestClassifier(random_state=42)#随机种子固定12cross_val_score函数输入参数包括:estimator:模型X:特征y:响应变量scoring:评分函数,如果不设置该参数,其默认使用所用模型estimator的score()函数对应的得分。cv:(1)其取值可以是一个整数,表示切分的折数,此时对于响应变量y为类别变量时,其默认使用StratifiedKFold()进行切分。其它情况时,使用KFold()进行切分。(2)其取值可以是一个CV切分器,如上述代码中的kf。(3)其取值也可以是包含每折训练集和测试集下标的array,如上述代码中的kf_array。(4)默认值为5.fromsklearn.model_selectionimportcross_val_score#例:kf=KFold(5,shuffle=True,random_state=42)cv_score=cross_val_score(rf,X,y,scoring='accuracy',cv=kf)print(cv_score)####输出:[0.972222220.944444440.972222220.971428571.]#例:kf_array=KFold(k,shuffle=True,random_state=42).split(X,y)cv_score_2=cross_val_score(rf,X,y,scoring='accuracy',cv=kf_array)12345678910补充:(1)评分函数score可以使用内置的评分函数,其可选取值如下所示:(说明文档链接:https://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter)(2)评分函数score也可以自行定义。使用sklearn的metrics模块中,make_scorer()函数。fromsklearn.metricsimportmake_scorer#定义一个自己的函数#如均方误差importnumpyasnpdefmy_score_fun(y_true,y_pred):score=-np.abs(y_true-y_pred).max()#为了满足得分越大越好,取个负值returnscorecv_score_3=cross_val_score(rf,X,y,scoring=make_scorer(my_score_fun,greater_is_better=True),cv=5)12345678910四、参数网格搜索GridSearchCV函数,给定模型参数的可选值,对这些可选值所有组合,计算交叉验证的得分,找到最优的参数组合。#函数常用参数说明GridSearchCV(estimator,param_grid,scoring,cv)#estimator:模型#param_grid:字典格式,‘key’为参数名,‘value’为参数取值的list#scoring、cv:同上述cross_val_score()函数12345使用示例:fromsklearn.model_selectionimportGridSearchCV#定义参数搜索取值的字典rf_para={'max_depth':[3,5,7],'min_samples_split':[5,10]}#定义网格搜索rf_search=GridSearchCV(rf,rf_para,cv=5,scoring='accuracy')#模型拟合rf_model=rf_search.fit(X,y)#获取最优参数print(rf_model.best_params_)####输出:{'max_depth':3,'min_samples_split':5}####如果搜索出的最优参数为边界值,可以尝试在超出边界值的一侧增加取值,再进行搜索#获取最优模型rf_best=rf_model.best_estimator_print(rf_best)####输出:RandomForestClassifier(max_depth=3,min_samples_split=5,random_state=42)#计算最优模型的得分rf_best.score(X,y)#使用最优模型进行预测rf_pred=rf_best.predict(X)##实际使用中,此处应该使用划分出的测试集中的X_test1234567891011121314151617181920212223
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-9 05:09 , Processed in 0.441704 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表