QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3408|回复: 0
打印 上一主题 下一主题

[其他资源] K-近邻算法分类和回归

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-5 15:43 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    & D% x9 F- P$ f# A: Y/ {& }6 ?
    K-近邻算法分类和回归
    , u& u' d9 T- G+ ]K近邻算法的主要思想是用离测试集数据点最近的训练集点(称为其邻居)的输出来估计测试集数据点的输出,参数K代表用多少个邻居来估计。超参数K通常设置为奇数来防止平局现象。( h( W; U1 `' Y- B# R) m& m$ M; y

    0 j8 s/ c' m% J6 N; Q: v其中对邻居的判定:我们可以用欧几里得距离来衡量距离来确定其K个邻居。
    ' S7 j1 f! B3 Z4 S0 I: g. y; U+ X, I' I, U+ Z8 z& J
    K近邻算法是一种惰性学习和非参数模型。当训练数据数量庞大,同时你对响应变量和解释变量之间的关系所知甚少时,非参数模型会非常有用。KNN 模型只基于一个假设:互相接近的实例拥有类似的响应变量值。非参数模型提供的灵活性并不总是可取的,当训练数据很缺乏或者你对响应变量和解释变量之间的关系有所了解时,对响应变量和解释变量之间关系做假设的模型就很有用。3 v- D* j0 e( q" T. v1 S

    4 _" [: l# l2 I% }( q8 RKNN模型分类:/ j, T$ v1 Y, O/ }$ |3 _" i+ l
    下面我们看一个分类的例子和代码实现来了解一下K近邻算法:. G1 m" M: A" K2 y' v
    3 S7 Y+ J8 i; i; P

    - r6 R# d' [3 X* o3 t; |' q  T& O$ c, W2 q2 d  ]. z" s
    上表是我们的训练集,下面先对数据进行可视化
    3 w% L% x% J3 ?. Z
    0 q7 w. V; Z5 c! B( [import numpy as np9 [* j$ L: E4 C2 L
    from matplotlib import pyplot as plt4 V, q. ?9 ]2 z; ~% f+ T: o# k
    import sklearn
    # U* Y* s  Q  a
    & z3 X& a1 A! x* e1 f, AX_train = np.array([ # 身高体重8 z5 s' Q' T; I9 X3 n
        [158, 64],! z2 J/ g; \+ w, c8 H3 Z5 `" Y. Q
        [170, 86],7 h. F. v" D% h
        [183, 84],
    1 Y8 A8 W9 d, T% b! {    [191, 80],$ t) f. d! d. O4 d
        [155, 49],
    , ~  e  w1 m  x: |4 w# x  E    [163, 59],5 r) l- A( z! F" {0 U" r
        [180, 67],
    / b3 _( A3 Y+ h    [158, 54],3 j9 _$ a/ F2 g2 m6 D: A. H) X3 w$ I
        [170, 67]])
    . ^6 I3 Z) n6 By_train = ['male']*4 + ['female']*5 # 性别3 I& R0 ~' @; s: @

    9 A# {+ X$ j; t4 X#绘制图像( a* ?( T, J- [' r  d9 J
    plt.figure()6 G1 Z2 E; j2 z2 _4 L! e+ }1 Y
    plt.title('Human Height and Weights by Sex')$ ^& O& l0 P8 S  H4 E3 N
    plt.xlabel('Height in cm')
    9 J, H% r: l  ?# ]  Fplt.ylabel('Weight in kg')
    6 A7 H: ^* a* B( z. N1 @0 Ofor i, x in enumerate(X_train):
    9 c1 Z% H/ B/ W5 N3 V: G+ M8 G    plt.scatter(x[0],x[1],c='k',marker='x' if y_train == 'male' else 'D')
    5 m" T" ^! }9 Lplt.grid()
    / C+ t1 J* y3 ~7 `8 I( T; Lplt.show()
    8 c, G. Q% l- w( Z, x) {" v, S  N* ?. D# ]* Z# E; Z, S( m
    结果: / Q* M  E8 ^$ M0 v8 @4 h6 }" u
    0 u! v4 q. T: S& v5 K+ x
    9 t6 @7 p! D& ?: @& z
    / H$ J( C  z0 o  p- R
    我们使用欧几里得距离公式来衡量距离:8 k' M3 R2 ?, b9 ~* ]
    3 l+ K7 J  M# s6 L1 F* @2 O
    + p4 U# B. P: g* s' D
    ! |! W. e! U1 F2 G( o. @
    % @# n  e* J* V1 w! f9 l+ z9 u

    8 I# e. R* j2 C3 a 我们设置参数K=3,来寻找3个距离最近的训练实例
    7 x+ b8 ~. u( S, S$ P
    $ U+ Y3 T) j1 ]2 a9 k3 p" F% o下面代码实现K近邻算法进行分类:
    1 M6 ^: u& {  \1 g3 |* ?
    % }2 h0 k+ ~+ ]: n7 J2 Z, }x = np.array([[155, 70]])
    4 p' Z; H3 o" W( G- u* H. ldistances = np.sqrt(np.sum((X_train - x)**2, axis=1)) # 计算距离* n/ }: \  I' M
    * {) b9 c7 T6 \! L! a% H4 N$ i. Z
    nearest_neighbor_indices = distances.argsort()[:3] # 找出前三个距离最小的下标
    5 Y6 O  `, A0 A: U# T) A2 _nearest_neighbor_genders = np.take(y_train, nearest_neighbor_indices) # 得到下标对应的标签
    6 u2 j; n6 P# i! P3 D  k) j, B
    * @7 h8 m6 E6 _# q* qfrom collections import Counter
    ; J0 @# _1 A0 h4 Y, M* m  Db = Counter(np.take(y_train, distances.argsort()[:3])) #得到三个结果标签中最频繁的标签得到结果female
    # L8 x. X- }  E! `6 C* X8 j* O4 @
    print(b.most_common(1)[0][0]) # female4 `( e2 v& P' r# q4 \
    因此,从上述代码可以得到K近邻算法进行分类就是找到离样本点最近的K个实例,再取K个实例的标签中出现次数最多的那个作为我们的结果。& H: N6 @2 j& g+ y' ~* j

    . G2 ^# ?. K  H上述K近邻算法在scikit-learn中也有对应的函数:
    % n; t/ t' r5 T) j3 G6 t4 p
    ( x5 z1 O" `% m( P) v# }; L; ~, l: Bfrom sklearn.preprocessing import LabelBinarizer# k- ]& f0 @+ o" V" s) J5 X. @
    from sklearn.neighbors import KNeighborsClassifier
    * X& K& v( w9 ]2 L3 p' A0 z, l
    4 ?. l+ z4 A: |! t# ?6 v" elb = LabelBinarizer() # 创建将标签二值数值化的类实例0 y1 h; ]( z! ]* P* n$ k+ j
    y_train_binarized = lb.fit_transform(y_train) # 将标签二值数值化* k4 y* r. l2 D) k" I
    print(y_train_binarized) + B1 i6 f, C* a; e9 w4 S

    1 ?; g: R2 W% I1 Z; eK = 3* p$ t1 F6 R8 d5 ], I# D7 x
    clf = KNeighborsClassifier(n_neighbors=K) # 创建K近邻分类器实例# p5 c: v( ~$ P$ H3 H' @
    clf.fit(X_train, y_train_binarized.reshape(-1, 1)) # 对训练集进行训练
    * d$ ]1 d$ g5 p1 V. Y% Qprediction_binarized = clf.predict(np.array([155, 70]).reshape(1,-1))[0] # 对测试样本点进行预测
    / j* W) G0 R$ Y& `6 K, wprediction_label = lb.inverse_transform(prediction_binarized) # 将预测结果从数字转换为标签
    0 P- m  {3 s/ C2 wprint(prediction_label) # array(['female'], dtype='<U6')
    8 J1 g8 s7 @. m, SKNN回归:
    ( f: `+ |  ~+ _, O4 P) F7 iK近邻算法进行回归和K近邻思想一致,只不过在得到了K个邻居后,分类是取邻居中出现次数最多的那个,而回归是取其他的操作来预测输出值(比如取平均)+ p! k' h0 @2 S, {) D

    6 v: R; w$ R8 `  k: L' u. P对应的代码在scikit-learn中其实也很简单
    % x4 o1 s4 j8 }
    ( g6 D! }# m; @% d, E0 L0 Dfrom sklearn.neighbors import KNeighborsRegressor
    . b! D) g0 B$ ]# x% w% G: FK = 39 n$ N$ i6 N' _8 u8 Q
    clf = KNeighborsRegressor(n_neighbors=K)
    # m3 [1 W) Q) }- Qclf.fit(X_train, y_train)
    ( ~- O. D- }: C3 c" Opredictions = clf.predict(X_test)+ e' c3 K& {( m- a+ P" m7 F$ Z
    特征缩放
    5 i, a! X+ E' x0 l/ m下面我们谈谈一个提升算法精确度的小细节。假设还是上面的数据,我们现在要做回归,给定身高和性别标签来预测体重。如果我们的训练数据集包含一个身高170cm的男性和身高160cm的女性。如果我们的测试集数据为身高为164cm的男性,你觉得其预测结果会接近170cm的男性还是身高160cm的女性呢?我们可能相信测试实例更接近男性实例,因为对预测体重来说,性别差异可能会比 6cm 的身高差距更重要。但是如果我们以毫米为单位表示身高,测试实例更接近于身高1600mm 的女性。如果我们以米为单位表示身高,测试实例更接近于身高 1.7m 的男性。(记住我们以欧几里得距离来衡量)
    * v7 j% Z4 D' `' P% ]( B/ n3 G' {0 }, O
    因此,我们的特征缩放的作用就出来了(其实就相当于深度学习对数据集预处理中的Normalize)
    & @3 x0 D) F* k, s# }! V3 O4 J$ H6 |" o. Q! [5 \5 d8 M
    将所有实例特征值减去均值来将其居中。其次将每个实例特征值除以特征的标准差对其进行缩放。均值为 0,方差为 1 的数据称为标准化数据。
    1 T4 k& D0 A  r- C0 ?% [2 @————————————————
    6 v5 h5 w7 _, g( S4 H版权声明:本文为CSDN博主「王大队长」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% Q( j( c, }- Q0 S9 v
    原文链接:https://blog.csdn.net/qq_55621259/article/details/126695549
    ' A  b- ?) H" ?1 C$ W, n/ E" P: J2 _( i
    2 U  w6 l0 E. r1 s2 [9 `+ v
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-6-15 18:09 , Processed in 0.436632 second(s), 51 queries .

    回顶部