文章目录

  • 一、K折交叉验证
  • 1.K-fold
  • 2.Stratified K-flod
  • 二、网格参数搜索


【机器学习】模型的训练和评估(理论+图解)_深度学习

 
简 介:下面是我在学习时候的记录并加上自己的理解。本文意在记录自己近期学习过程中的所学所得,如有错误,欢迎大家指正。
 
关键词:Python、机器学习

一、K折交叉验证

  有的时候我们将数据分为训练集和测试集,但是可能不太科学,会有很大的偶然性在里面,如果划分不同可能存在不同的结果,所以为了增强模型的泛化能力,我们将数据分成k份,其中的k-1份作为训练集,剩余的1份作为测试集,这样就会存在10组数据集,我们就可以得到10组结果,然后取10组的平均值作为我们的模型结果。

【机器学习】模型的训练和评估(理论+图解)_python_02

1.K-fold

【机器学习】模型的训练和评估(理论+图解)_python_03

  在sklearn的model_selection模块就集成了这个算法,它是随机不放回的进行切分数据集,不会产生重复的数据。

代码实现:

from sklearn.datasets import load_iris
from sklearn import metrics
from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold
from sklearn.tree import DecisionTreeClassifier

import numpy as np

X,y=load_iris(return_X_y=True)
# 定义分割器
kf=KFold(n_splits=10)
# 定义模型
model=DecisionTreeClassifier()
# 用于保存每折的分数
scores=[]

for i,(train_index,test_index) in enumerate(kf.split(X)):
model.fit(X[train_index],y[train_index])

y_pred=model.predict(X[test_index])

# 评估模型分数
accuracy=metrics.accuracy_score(y[test_index],y_pred)
scores.append(accuracy)

print("Fold:{} accuracy:{:.4f}".format(i+1,accuracy))

print("平均accuracy:{}".format(np.mean(scores)))

  • KFold(n_splits=10)的意思就是将数据集切分成10份
  • kf.split(X)就是将利用定义好的分割器进行切分数据集,返回的是对应训练集和测试集的索引,注意是索引不是数据,需要用该索引进行从原数据中进行提取数据

2.Stratified K-flod

  Stratified K-flod也是集成好的分割算法,但是它不同的地方就是它会按照标签中的类别进行按比例分割,保证训练集和测试集的样本比例相同。

代码实现:

skf=StratifiedKFold(n_splits=3)
model=DecisionTreeClassifier()
scores=[]

for i,(train_index,test_index) in enumerate(skf.split(X,y)):
model.fit(X[train_index],y[train_index])

y_pred=model.predict(X[test_index])

accuracy=metrics.accuracy_score(y[test_index],y_pred)
scores.append(accuracy)

print("Fold:{} accuracy:{:.4f}".format(i+1,accuracy))

print("平均accuracy:{}".format(np.mean(scores)))

二、网格参数搜索

  你会发现有的算法参数很多,而且范围很大是连续型的,如果一个一个尝试的相当的费时间,所以很容易想到有没有那种循环性遍历尝试的,GridSerarchCV就是这样的,它会将我们传入的参数一个一个的进行尝试,然后用每组参数进行交叉验证,选择最优的参数组合,虽然可以帮助我们很容易的找到最优参数组合,但是也会产生一定负面影响,因为要不断遍历每个参数组合,所以耗时较长,还有一点就是很容易产生过拟合,所以针对大数据集这种方法还是没有用的,还是要依赖一定的经验进行调整参数,过度依赖它肯定是不行的,但是作为新手使用它可以很容易帮助我们找打最优的参数组合。

代码实现:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV

  • Pipeline:管道,可以将我们一些通用步骤进行封装
  • StandardScaler:用于将数据进行标准化
  • KNeighborsClassifier:K近邻算法
  • GridSearchCV:网格搜索

# 定义待评估的模型,这是个管道
pipe_KNN=Pipeline([('scale',StandardScaler()),
('KNN',KNeighborsClassifier())])

n_neighbors=np.arange(1,11)

# 需要遍历的网格参数
params={"scale__with_mean":[True,False],
"KNN__n_neighbors":n_neighbors}

# 定义网格器
gsCV=GridSearchCV(pipe_KNN,
params,
cv=10)

# 开始搜索参数
gsCV.fit(X,y)

  我们将标准化和K近邻算法封装在一个管道内,Pipeline的参数就是一个列表,列表中包括多个流程,每个流程是一个键值对,键就是这个流程的名字,用于后面进行提取该步骤,值就是每个流程的操作对象。

  然后定义了需要搜索的网格参数,他是一个字典,键是参数的名字,值是每个参数可选的值,这里发现键就是Pipeline管道中的键加__再加上参数名字,这是Pipeline中提取参数的方法,用于指明哪个步骤的哪个参数。

  然后GridSearchCV的参数就是评估器,网格参数,以及交叉验证的折数,这里用Pipeline充当一个评估器。

# 网格搜索后最优参数
>>>gsCV.best_params_
{'KNN__n_neighbors': 8, 'scale__with_mean': True}

# 搜索参数过程中的最优分数
>>>gsCV.best_score_
0.9666666666666668

# 返回最优参数下的模型
>>>model=gsCV.best_estimator_
>>>model
Pipeline(memory=None,
steps=[('scale',
StandardScaler(copy=True, with_mean=True, with_std=True)),
('KNN',
KNeighborsClassifier(algorithm='auto', leaf_size=30,
metric='minkowski', metric_params=None,
n_jobs=None, n_neighbors=8, p=2,
weights='uniform'))],
verbose=False)

# 将最优模型用于预测
>>>y_pred=model.predict(X)
>>>print("accuracy:{}".format(metrics.accuracy_score(y,y_pred)))
accuracy:0.9666666666666667

  当我们进行完网格搜索后,可以用gsCV获得最优参数,以及对应的模型用于之后的使用。

写在最后

      一键三连”哦!!!

以上是我在读这本书的时候的记录并加上自己的理解。本文意在记录自己近期学习过程中的所学所得,如有错误,欢迎大家指正。

【机器学习】模型的训练和评估(理论+图解)_深度学习_04