找回密码
 注册
关于网站域名变更的通知
查看: 729|回复: 3
打印 上一主题 下一主题

基于留一法的快速KNN代码

[复制链接]
  • TA的每日心情

    2019-11-19 15:32
  • 签到天数: 1 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
    发表于 2021-7-12 14:14 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    留一法交叉验证(LOOCV)/ Z0 U6 d& V5 V( R
    留一法即Leave-One-Out Cross Validation。这种方法比较简单易懂,就是把一个大的数据集分为k个小数据集,其中k-1个作为训练集,剩下的一个作为测试集,然后选择下一个作为测试集,剩下的k-1个作为训练集,以此类推。其主要目的是为了防止过拟合,评估模型的泛化能力。计算时间较长。
    : t5 w3 S8 K1 v! P
    1 b. I: y! _# l" a适用场景:9 `3 e: g+ I) Z' }+ D" c) V

    : E6 F4 e- _# q) @& B4 n数据集少,如果像正常一样划分训练集和验证集进行训练,那么可以用于训练的数据本来就少,还被划分出去一部分,这样可以用来训练的数据就更少了。loocv可以充分的利用数据。
    , b: P, b: ~. h1 X1 u  a# g$ X$ ?2 b/ h( [0 _# e% S, D

    # z# _$ o/ j/ R6 N快速留一法KNN/ _. @  n- y0 _7 N( T; Z6 D/ V

    + |' U/ ]9 W1 w! x因为LOOCV需要划分N次,产生N批数据,所以在一轮训练中,要训练出N个模型,这样训练时间就大大增加。为了解决这样的问题,根据留一法的特性,我们可以提前计算出不同样本之间的距离(或者距离的中间值),存储起来。使用LOOCV时直接从索引中取出即可。下面的代码以特征选择为Demo,验证快速KNN留一法。
    0 M. V9 {5 d4 Z' \% @+ s% B5 M  y3 B0 B) A8 c
    其中FSKNN1是普通KNN,FSKNN2是快速KNN5 r% W) O0 D: R$ ?- o  ^. v5 x
    ) U1 d( t: [5 j- Y, e$ p: q
    主函数main.m
    9 m2 n# s0 N5 E9 k7 W# Q* B3 v$ M- E! x- [8 e* s
    • clc
    • [train_F,train_L,test_F,test_L] = divide_dlbcl();
    • dim = size(train_F,2);
    • individual = rand(1,dim);
    • global choice
    • choice = 0.5;
    • global knnIndex
    • [knnIndex] = preKNN(individual,train_F);
    • for i = 1:100
    •     [error,fs] = FSKNN1(individual,train_F,train_L);
    •     [error2,fs2] = FSKNN2(individual,train_F,train_L);
    • end
      1 U- {$ V) u! y/ g

    7 y* _" j! O0 T( b: L9 S5 l' S
    ( B; ?0 t- t7 K0 @数据集划分divide_dlbcl.m
    7 E7 D3 q  k& `5 M) ?
    ; ?" N, G7 {# T1 p2 o" P+ y
    • function [train_F,train_L,test_F,test_L] = divide_dlbcl()
    • load DLBCL.mat;
    • dataMat=ins;
    • len=size(dataMat,1);
    • %归一化
    • maxV = max(dataMat);
    • minV = min(dataMat);
    • range = maxV-minV;
    • newdataMat = (dataMat-repmat(minV,[len,1]))./(repmat(range,[len,1]));
    • Indices   =  crossvalind('Kfold', length(lab), 10);
    • site = find(Indices==1|Indices==2|Indices==3);
    • test_F = newdataMat(site,:);
    • test_L = lab(site);
    • site2 = find(Indices~=1&Indices~=2&Indices~=3);
    • train_F = newdataMat(site2,:);
    • train_L =lab(site2);
    • end1 Y. t' V) J- A8 n/ g9 q9 Y

    6 f( _% r# P9 A, `, `9 S
    " ?$ x! w% R+ L! D. Q4 ?简单KNN
    - @5 g0 `, g' g& Q& {+ ~4 X3 j& t1 H# g7 q1 g( `3 U
    FSKNN1.m/ j4 Y9 d6 F6 o% ^6 K$ a

    . ^# Q4 m' L5 c. X+ r6 ~
    • function [error,fs] = FSKNN1(x,train_F,train_L)
    • global choice
    • inmodel = x>choice;%%%%%设定恰当的阈值选择特征
    • k=1;
    • train_f=train_F(:,inmodel);
    • train_length = size(train_F,1);
    • flag = logical(ones(train_length,1));
    • error=0;
    • for j=1:train_length
    •     flag(j) = 0;
    •     CtrainF = train_f(flag,:);
    •     CtrainL = train_L(flag);
    •     CtestF = train_f(~flag,:);
    •     CtestL = train_L(~flag);
    •     classifyresult= KNN1(CtestF,CtrainF,CtrainL,k);
    •     if (CtestL~=classifyresult)
    •         error=error+1;
    •     end
    •     flag(j) = 1;
    • end
    •   error=error/train_length;
    •   fs = sum(inmodel);
    • end
      " g, e9 a* h: U  a

    6 u- J8 E) ~, }2 [% t1 n
    * n. V4 Q  e4 JKNN1.m7 O& z! h4 u) D5 f/ ?

    5 i& R, x0 `  x" o/ `/ a4 D
    • function relustLabel = KNN1(inx,data,labels,k)
    • %%
    • %   inx 为 输入测试数据,data为样本数据,labels为样本标签 k值自定1~3
    • %%
    • [datarow , datacol] = size(data);
    • diffMat = repmat(inx,[datarow,1]) - data ;
    • distanceMat = sqrt(sum(diffMat.^2,2));
    • [B , IX] = sort(distanceMat,'ascend');
    • len = min(k,length(B));
    • relustLabel = mode(labels(IX(1:len)));
    • end$ }6 ~$ _1 [$ x% h
    5 I& x$ V& ~. `! {* r. ?# Y; W

      G3 L( I/ [6 K. ~快速KNN* g) W. Q3 Z1 x3 h6 I# G" m% I
    1 V3 t% I" c3 G; A+ c8 ^& M
    preKNN.m
    - ]; {1 H7 K* J4 h9 {
    0 o2 m* \) X. I6 e+ h. ~
    • function [knnIndex] = preKNN(x,train_F)
    •     inmodel = x > 0;
    •     train_f=train_F(:,inmodel);
    •     train_length = size(train_F,1);
    •     flag = logical(ones(train_length,1));
    •     knnIndex = cell(train_length,1);
    •     for j=1:train_length
    •         flag(j) = 0;
    •         CtrainF = train_f(flag,:);
    •         CtestF = train_f(~flag,:);
    •         [datarow , ~] = size(CtrainF);
    •         diffMat = repmat(CtestF,[datarow,1]) - CtrainF ;
    •         diffMat = diffMat.^2;
    •         knnIndex{j,1} = diffMat;
    •         flag(j) = 1;
    •     end
    • end
      ! y- d. C9 O3 k5 x+ A! ^, v; A/ k9 G5 L

    0 Z" ?: {, v' s4 Q+ P; v3 ?+ }$ S5 s) I  x: ]4 C! Y
    FSKNN2.m
    ( E; m% B& z/ @; T8 x6 H3 B) \# Z
    • function [error,fs] = FSKNN2(x,train_F,train_L)
    • global choice
    • inmodel = x>choice;%%%%%设定恰当的阈值选择特征
    • global knnIndex
    • k=1;
    • train_length = size(train_F,1);
    • flag = logical(ones(train_length,1));
    • error=0;
    • for j=1:train_length
    •     flag(j) = 0;
    •     CtrainL = train_L(flag);
    •     CtestL = train_L(~flag);
    •     classifyresult= KNN2(CtrainL,k,knnIndex{j}(:,inmodel));
    •     if(CtestL~=classifyresult)
    •         error=error+1;
    •     end
    •     flag(j) = 1;
    • end
    •   error=error/train_length;
    •   fs = sum(inmodel);
    • end; ]/ b8 T! q) S1 u! I0 S

    * C9 U# @9 l, t: E1 a  C; Y' h9 R
    0 P% k! }9 c. A/ dKNN2.m1 t# I* S2 e$ [- t

      Q, t* F$ g$ l: i/ h) C- L+ ]0 M! e
    • function relustLabel = KNN2(labels,k,diffMat)
    • distanceMat = sqrt(sum(diffMat,2));
    • [B , IX] = sort(distanceMat,'ascend');
    • len = min(k,length(B));
    • relustLabel = mode(labels(IX(1:len)));
    • end
      * a' A9 V9 T+ C7 [  Q: E

    7 c6 E0 K" i1 m9 A) H
    ( d0 f3 D* D" ]& z: q/ s4 w" b6 w结果- b" c8 P9 v& @

    $ }- w1 x3 h, h4 R8 n  S/ W 7 N4 z) b% Z1 t" t+ J

    ( I% j* b$ R" c6 V1 V; Y% z可以看到FSKNN2+preKNN的时间比FSKNN1要少很多。3 b2 f9 ]5 s2 x8 \! W) |

    该用户从未签到

    2#
    发表于 2021-7-12 15:08 | 只看该作者
    基于留一法的快速KNN代码

    该用户从未签到

    3#
    发表于 2021-7-12 15:10 | 只看该作者
    基于留一法的快速KNN代码

    该用户从未签到

    4#
    发表于 2021-7-12 15:10 | 只看该作者
    基于留一法的快速KNN代码
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-10-5 10:22 , Processed in 0.156250 second(s), 26 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表