简 介:下面是我在学习时候的记录并加上自己的理解。本文意在记录自己近期学习过程中的所学所得,如有错误,欢迎大家指正。
关键词:Python、机器学习
一、K折交叉验证
有的时候我们将数据分为训练集和测试集,但是可能不太科学,会有很大的偶然性在里面,如果划分不同可能存在不同的结果,所以为了增强模型的泛化能力,我们将数据分成k份,其中的k-1份作为训练集,剩余的1份作为测试集,这样就会存在10组数据集,我们就可以得到10组结果,然后取10组的平均值作为我们的模型结果。
1.K-fold
在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获得最优参数,以及对应的模型用于之后的使用。