初步学习k-NN算法以及使用GridSearchCV进行调参

k最近邻算法 (k-NN)

  k最近邻 (k-Nearst Neighbor, k-NN) 算法是一种比较简单易懂的机器学习算法,1968年由Cover和Hart提出,常应用于字符识别、文本分类、图像识别等领域。该算法的思想是:一个样本与数据集中的k个样本最相似,如果这k个样本中的大多数属于某一个类别,则该样本也属于这个类别。
  在sklearn库中,k-NN包含在sklearn.neighbors中,有k最近邻分类KNeighborsClassifier和k最近邻回归KNeighborsRegressor。本文以k-NN分类器为例进行学习。
  sklearn库中的k-NN方法有很多超参数,常用的超参数如下:
  1. weights:用于分配权重。基本的最近邻回归使用统一的权重,即本地邻域内的每个邻点对查询点的分类贡献一致。在某些环境下,对邻点加权可能是有利的,使得附近点对于回归所作出的贡献多于远处点。默认为weights = 'uniform',表示为所有点分配同等权重。weights = 'distance'表示分配的权重与查询点距离呈反比。此外,我们还可以自定义一个距离函数用来计算权重。
  2. n_neighbors:邻居个数。
  3. pp参数只有在weights = 'distance'时才有。p是一个大于或等于1的值。p = 1表示曼哈顿距离 (Manhattan Distance),p = 2表示欧式距离 (Euclidean Distance),p = ∞表示它是各个坐标距离的最大值。
  下面介绍一下三种距离计算公式。设特征空间 X \mathcal{X} X n n n维实数向量空间 R n R_{n} Rn x i , x j ∈ X x_{i},x_{j}\in\mathcal{X} xi,xjX x i = ( x i ( 1 ) , x i ( 2 ) , . . . , x i ( n ) ) T x_{i}=(x_{i}^{(1)},x_{i}^{(2)},...,x_{i}^{(n)})^{T} xi=(xi(1),xi(2),...,xi(n))T x j = ( x j ( 1 ) , x j ( 2 ) , . . . , x j ( n ) ) T x_{j}=(x_{j}^{(1)},x_{j}^{(2)},...,x_{j}^{(n)})^{T} xj=(xj(1),xj(2),...,xj(n))T x i , x j x_{i},x_{j} xi,xj L p L_{p} Lp距离定义为 L p ( x i , x j ) = ( ∑ l = 1 n    ∣ x i ( l ) − x j ( l ) ∣ p ) 1 p . L_p(x_i,x_j) = (\sum_{l=1}^{n} \; |x_i^{(l)}-x_j^{(l)}|^p)^{\frac{1}{p}}. Lp(xi,xj)=(l=1nxi(l)xj(l)p)p1.上式中 p ≥ 1 p\geq1 p1. 当 p = 1 p=1 p=1时,称为曼哈顿距离,此时 L 1 ( x i , x j ) = ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ . L_1(x_i,x_j)= \sum_{l=1}^{n} |x_i^{(l)}-x_j^{(l)}|. L1(xi,xj)=l=1nxi(l)xj(l). p = 2 p=2 p=2时,称为欧式距离,此时 L 2 ( x i , x j ) = ( ∑ l = 1 n    ∣ x i ( l ) − x j ( l ) ∣ 2 ) 1 2 . L_2(x_i,x_j) = (\sum_{l=1}^{n} \; |x_i^{(l)}-x_j^{(l)}|^{2})^{\frac{1}{2}}. L2(xi,xj)=(l=1nxi(l)xj(l)2)21. p = ∞ p=\infty p=时,表示各个坐标距离的最大值,此时 L ∞ ( x i , x j ) = m a x l    ∣ x i ( l ) − x j ( l ) ∣ . L_{\infty}(x_i,x_j)= \mathop{max}_l \; |x_i^{(l)}-x_j^{(l)}|. L(xi,xj)=maxlxi(l)xj(l).
  接下来简单说明一下k-NN的算法流程。输入训练数据集 T = ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) , T=(x_{1},y_{1}),(x_{2},y_{2}),...,(x_{N},y_{N}), T=(x1,y1),(x2,y2),...,(xN,yN),其中 x i ∈ X ⊆ R n x_{i}\in\mathcal{X}\subseteq R^{n} xiXRn为实例的特征向量, y i ∈ Y = { c 1 , c 2 , . . . , c k } y_{i}\in\mathcal{Y}=\{c_1,c_2,...,c_k\} yiY={c1,c2,...,ck}为实例的类别, i = 1 , 2 , . . . , N i=1,2,...,N i=1,2,...,N;实例特征向量 x x x.
  1. 根据给点的距离度量,在训练集 T T T中找出与 x x x最近邻的 k k k个点,涵盖着 k k k个点的领域,记为 N k ( x ) N_k(x) Nk(x).
  2. 在 N k ( x ) N_k(x) Nk(x)中根据分类决策规则(如多数表决),决定 x x x的类别 y y y y = a r g    m a x c j ∑ x i ∈ N k ( x )    I ( y i = c j ) , i = 1 , 2 , . . . , N ; y=arg \mathop{\; max}_{c_j} {\sum}_{x_i \in N_k(x)} \; I(y_i=c_j) , i=1,2,...,N; y=argmaxcjxiNk(x)I(yi=cj),i=1,2,...,N;在上式中, I I I为指示函数,即当 y i = c j y_i=c_j yi=cj时, I I I 1 1 1,否则 I I I 0 0 0.
  最后输出实例 x x x所属的类 y y y.
  k-NN的特殊情况是k=1的情形,称为最近邻算法。对于输入的实例点(特征向量) x x x,最近邻算法将训练数据集中与 x x x最近邻点的类作为 x x x的类。

GridSearchCV调参

  GridSearchCV包含在sklearn.model_selection中。它可以拆分为“GridSearch”和“CV”两个部分,即网格搜索和交叉验证。网格搜索用于选取模型的最优超参数。获取最优超参数的方式可以绘制验证曲线,但是验证曲线只能每次获取一个最优超参数。如果多个超参数有很多排列组合的话,就可以使用网格搜索寻求最优超参数的组合。网格搜索针对超参数组合列表中的每一个组合,实例化给定的模型,进行交叉验证,将平均得分最高的超参数组合作为最佳的选择,返回模型对象。

GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True,
             refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', error_score='raise',
             return_train_score=True)

  以下是GridSearchCV方法中常用的超参数。
  1. estimator:创建的算法对象。
  2. param_grid:值为字典或者列表,需要最优化的参数的取值。
  3. scoring:准确度评价标准,默认None,这时需要使用score函数;或者如scoring='roc_auc',根据所选模型不同,评价准则不同。字符串(函数名)或是可调用对象,需要其函数签名,形如scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。
  4. n_jobs:并行数,默认为1n_jobs = -1表示跟CPU核数一致。
  5. cv:交叉验证参数,默认None,使用三折交叉验证。指定fold数量,默认为3,也可以是yield训练或测试数据的生成器。
  6. verbose:日志冗长度。verbose = 0表示不输出训练过程,verbose = 1表示偶尔输出,verbose > 1表示对每个子模型都输出。
  GridSearchCV还内置了一些属性。
  1. best_estimator_:效果最好的分类器。
  2. best_score_:成员提供优化过程期间观察到的最好的评分。
  3. best_params_:描述了已取得最佳结果的参数的组合。
  4. best_index_:对应于最佳候选参数设置的索引(cv_results_数组的索引)。

优化Titanic生存预测代码

  在上一篇博客中,我使用决策树和k-NN两种分类器对处理后的Titanic数据集进行了分类预测,其中k-NN分类器的training set score为0.82,test set score为0.72,还有一部分优化空间。下面用网格搜索和交叉验证进行调参。

# 使用GridSearchCV进行调参
from sklearn.model_selection import GridSearchCV

knn = KNeighborsClassifier()
param_grid = [
    {
        'weights': ['uniform'],
        'n_neighbors': [i for i in range(1, 11)]
    },
    {
        'weights': ['distance'],
        'n_neighbors': [i for i in range(1, 11)],
        'p': [i for i in range(1, 6)]
    }
]
grid_search = GridSearchCV(knn, param_grid, n_jobs=-1, verbose=2)
%%time
grid_search.fit(X_train, y_train)

在这里插入图片描述
  接下来查看一下GridSearchCV的属性。

# 最优超参数组合对应的分类器
grid_search.best_estimator_

在这里插入图片描述

# 最优超参数组合
grid_search.best_params_

在这里插入图片描述

# 最优超参数组合对应的准确率
grid_search.best_score_

在这里插入图片描述

  最后我们使用最优的分类器模型对测试集进行预测。

knn = grid_search.best_estimator_
y_predict = knn.predict(X_test)
print(y_predict)
print('Training set score: {:.2f}'.format(knn.score(X_train, y_train)))
print('Test set score: {:.2f}'.format(knn.score(X_test, y_test)))

在这里插入图片描述
  可以看出training set score有了明显的提升(从0.82提升到0.98),但是test set score的提升不是很多(从0.72提升到0.73)。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值