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

在应用机器学习方法进行模型训练时,需要通过数据切分将数据集分为训练集/验证集/测试集。并且可以通过交叉验证,对模型在验证集上的拟合效果进行预评估,以选择表现最好的模型。此外,可以通过参数网格搜索的方法,确定最优的模型参数。
本篇文章通过具体数据做示例,总结了sklearn中模型选择model_selection模块常用函数的使用。包括:
1. 数据切分:train_test_split
2. K折交叉验证:KFold,StratifiedKFold,cross_val_score
3. 参数网格搜索:GridSearchCV
一、数据导入

导入python自带的wine数据集用于演示。该数据集为一个分类数据集,响应变量y取值为0、1、2.

from sklearn import datasets
wine_data = datasets.load_wine()
X = wine_data.data
y = wine_data.target
print(X.shape)
# (178, 13)
二、数据切分

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)

train_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个值为2
print(sum(y==0), sum(y==1), sum(y==2))
#### 输出:45 57 40

## 查看划分后的标签类别分布,可知并不是对标签按比例分割
print(sum(y_test==0), sum(y_test==1), sum(y_test==2))
#### 输出:14 14 8

实际使用中,如果对数据进行随机切分,可能导致某些数据量较少的类别全部被划分入训练集,影响模型的效果。所以,可以在数据分割时,按标签类别分层切分(取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.20833333333333334

可见,对每个类别,按0.2的比例切分到了测试集中。

三、K折交叉验证

K折交叉验证,指将训练数据等分成K个子集,每次选取1个子集作为验证集,其余K-1个子集作为训练集。该过程重复K次。

  1. KFold
    用于定义一个K折交叉验证。参数 n_splits 表示切分份数,其它参数含义同数据切分部分。如定义一个5折交叉验证:
from sklearn.model_selection import KFold,StratifiedKFold
n_splits = 5
kf = KFold(n_splits, shuffle=True, random_state=42)

其方法有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)
#### 输出: 5
kf_array = KFold(k, shuffle=True, random_state=42).split(X,y)
for train_index, test_index in KFold(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]

输出的每次验证集下标如下所示。可以看到,每次迭代验证集的数据量是总量的1/5,且5次迭代的验证集下标无重复。
在这里插入图片描述

  1. StratifiedKFold
    其使用方法同KFold,其作用是,按y各类别的比例切分。同第二节中,train_test_split 的参数 stratify=y 的情况。

  2. cross_val_score
    该函数用于直接计算K折交叉验证的模型得分。这个得分对所有内置的评分函数,都是得分越高,说明模型拟合越好。该函数的返回值是长度为K的list,为K次迭代在验证集上的模型得分。

如我们构建一个随机森林模型:

from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(random_state=42)  #随机种子固定

cross_val_score函数输入参数包括:

  • estimator:模型
  • X:特征
  • y:响应变量
  • scoring:评分函数,如果不设置该参数,其默认使用所用模型estimator的score()函数对应的得分。
  • cv:(1)其取值可以是一个整数,表示切分的折数,此时对于响应变量 y 为类别变量时,其默认使用StratifiedKFold()进行切分。其它情况时,使用KFold()进行切分。(2)其取值可以是一个CV切分器,如上述代码中的 kf。(3)其取值也可以是包含每折训练集和测试集下标的array,如上述代码中的 kf_array。(4)默认值为5.
from sklearn.model_selection import cross_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.97222222 0.94444444 0.97222222 0.97142857 1.        ]

# 例:
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)

补充:(1)评分函数score 可以使用内置的评分函数,其可选取值如下所示:
(说明文档链接:https://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter)
对分类模型
对回归模型
(2)评分函数score 也可以自行定义。使用 sklearn 的 metrics 模块中,make_scorer() 函数。

from sklearn.metrics import make_scorer
# 定义一个自己的函数
# 如均方误差
import numpy as np
def my_score_fun(y_true, y_pred):
    score = -np.abs(y_true-y_pred).max()
    # 为了满足得分越大越好,取个负值   
    return score

cv_score_3 = cross_val_score(rf, X, y, scoring=make_scorer(my_score_fun, greater_is_better = True) ,cv = 5)
四、参数网格搜索

GridSearchCV 函数,给定模型参数的可选值,对这些可选值所有组合,计算交叉验证的得分,找到最优的参数组合。

# 函数常用参数说明
GridSearchCV(estimator, param_grid, scoring, cv)
# estimator:模型
# param_grid:字典格式,‘key’为参数名,‘value’为参数取值的list
# scoring、cv:同上述 cross_val_score() 函数

使用示例:

from sklearn.model_selection import GridSearchCV
# 定义参数搜索取值的字典
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_test
  • 22
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 好的,这是一个Python语言的代码片段,它使用scikit-learn库中的模型选择模块,用于将数据集分为训练集和测试集。 代码的意思是导入scikit-learn库中的模型选择模块中的train_test_split函数。该函数可以帮助我们将数据集随机分成训练集和测试集,以便我们可以在训练集上训练模型,然后在测试集上测试模型的性能。 示例代码如下: ``` from sklearn.model_selection import train_test_split # 假设我们有一个数据集X和对应的标签y X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # 这里将数据集分为训练集和测试集,测试集占总数据集的30% # random_state=42表示设置随机数种子为42,保证每次分割的结果相同 ``` 在这个例子中,我们将数据集X和对应的标签y传递给train_test_split函数,并指定了测试集的大小为30%。函数将返回四个数据集:X_train,y_train,X_test,y_test。我们可以使用这些数据集来训练和测试模型。 ### 回答2: “from sklearn.model_selection import train_test_split” 是一个在 Python 中使用 scikit-learn 库中的 model_selection 模块,导入 train_test_split 函数的语句。 train_test_split 是一个用于将数据集划分为训练集和测试集的函数。它的作用是将数据集划分为两个部分,一部分用于训练模型,另一部分用于评估模型的性能。 train_test_split 函数的输入参数包括数据集(通常是特征矩阵)和标签(可选),以及其他参数如测试集的比例、随机种子等。 函数的返回值是划分后的训练集和测试集(特征矩阵以及标签),可以通过赋值给不同的变量来保存这些数据。 train_test_split 函数的使用非常方便,它可以在机器学习任务中起到非常重要的作用。通过将数据集划分为训练集和测试集,可以用训练集来训练模型,再用测试集来评估模型的泛化能力,从而选择最优的模型或调整模型参数。 该函数的导入语句是从 scikit-learn 库的 model_selection 模块中导入 train_test_split 函数。导入后就可以在代码中调用 train_test_split 函数来完成数据集划分的任务。 ### 回答3: `from sklearn.model_selection import train_test_split`是一个从sklearn库中导入train_test_split函数的语句。 train_test_split函数用于将数据集分成训练集和测试集。这是为了在机器学习任务中评估模型在未知数据上的泛化能力。通常,我们将数据集分成70-80%的训练集和20-30%的测试集。 train_test_split函数接受多个参数,其中最重要的是X和y。X是特征矩阵,包含了所有的输入特征。y是目标向量,包含了对应每个输入特征的目标值。 另一个重要的参数是test_size,它表示将原始数据集的百分之几作为测试集。通常,我们设置为0.2,表示将20%的数据作为测试集,剩下的80%作为训练集。 还有一个可选的参数random_state,用于确定数据分割的随机性。如果不设置,则每次运行代码时都会生成不同的划分结果。如果设置了一个固定的值,那么每次运行时都会得到相同的划分结果,这在调试和比较算法性能时非常有用。 train_test_split函数的返回值是一个元组,包含4个数组:X_train,X_test,y_train,y_test。这些数组将原始数据集按照指定的比例分割成了训练集和测试集。我们可以使用这些数组来训练模型和评估模型的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值