模型的选择与调优

1 交叉验证

1.1 交叉验证过程

交叉验证:为了让被评估的模型更加准确可信

交叉验证的意义:为了使一部分数据即当成验证集,也做过训练集,更加准确得出准确率,把最后的准确率取平均值。

注意:线上的测试数据才有测试集如果没有测试数据集,怎么知道结果好与不好,那就把训练集分成训练集和验证集(和测试集没关系,抛开测试集)。

交叉验证过程:将拿到的数据分为数据集和验证集。以下图为例:将数据分成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉验证。10折交叉验证是最常用的。

python十折交叉验证的模型代码 十折交叉验证的作用_模型的选择

1.2 交叉验证目的

使用交叉验证方法的目的主要有2个:

①从有限的学习数据中获取尽可能多的有效信息;

②可以在一定程度上避免过拟合问题。

1.3 交叉验证API

使用交叉验证的最简单的方法是在估计器和数据集上使用cross_val_score函数。

sklearn.model_selection._validation.cross_val_score

def cross_val_score(estimator, X, y=None, groups=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch='2*n_jobs')

参数:     estimator:模型估计器             X:特征变量集合      y:目标变量

cv:使用默认的3折交叉验证,整数指定一个(分层)KFold中的折叠数                    return :预估系数

1.4 案例

from sklearn.model_selection._validation import cross_val_score
from sklearn.datasets import load_digits
from sklearn import linear_model
diabetes = load_digits()
X = diabetes.data[:150]
y = diabetes.target[:150]
lasso = linear_model.Lasso()
print(cross_val_score(lasso, X, y))

2 网格搜索-超参数搜索

通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。

python十折交叉验证的模型代码 十折交叉验证的作用_机器学习_02

2.1 网格搜索API

sklearn.model_selection.GridSearchCV

sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)

常改参数:                         estimator:估计器对象                 param_grid:估计器参数(dict){“n_neighbors”:[2,4,6]}

cv:指定几折交叉验证               

常用方法:       

fit(X, y=None, groups=None, **fit_params):输入训练数据,与所有参数组合运行

score(X, y=None):准确率

predict(X):调用使用最佳找到的参数对估计量进行预测,X:可索引,长度为n_samples

常用属性

best_score_:在交叉验证中测试的最好结果

best_estimator_:最好的参数模型

cv_results_:每次交叉验证后的测试集准确率结果和训练集准确率结果

2.2 案例

from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

#1 读取数据
data = pd.read_csv("./data/train.csv")

#2 处理数据,截取部分数据
data = data.query("x > 1.0 &  x < 1.5 & y > 2.5 & y < 3")
timev = pd.to_datetime(data['time'],unit='s')
timev = pd.DatetimeIndex(timev)

#构造新特征
data['day']=timev.day
data['hour'] = timev.hour
data['weekday'] = timev.weekday
#删除时间特性,pandas的列是1,sklearn的列是0
data.drop(['time'],axis=1)

#根据palce_id分组
data_count = data.groupby('palce_id').count()

#调用reset_index,reset_index()的所用是把索引palce_id变成某一列,便于获取
tf = data_count[data_count.row_id>5].reset_index()

#筛选data里面id是tf里面的id,在就保留下来
data[data['place_id'].isin(tf.place_id)]

# 取出数据当中的特征值和将place_id作为目标值,
y = data['place_id']
x = data.drop(['place_id'], axis=1)

# 将数据的分割成训练集合测试集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)

#3 特征工程标准化
std = StandardScaler()
x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)

#进行算法流程 使用网格验证超参数在这不加
knn = KNeighborsClassifier()

#构造参数值进行搜索,字典形式
params = {"n_neighbor":[2,4,6,8]}

#进行网格搜索
gsc = GridSearchCV(knn,params,cv=3)
gsc.fit(x_train,y_train)

# 预测准确率
print("在测试集上准确率:", gsc.score(x_test, y_test))
print("在交叉验证当中最好的结果:", gsc.best_score_)
print("选择最好的模型是:", gsc.best_estimator_)
print("每个超参数每次交叉验证的结果:", gsc.cv_results_)