[机器学习][3]--口袋算法与线性回归

[机器学习][3]--口袋算法与线性回归


  今天将会接着第一篇文章的PLA算法接着讲下去,将会去优化PLA算法。

  首先有个问题需要说一下,一般来说,如果要测试某个模型的可用性,最好就是利用真实数据。但是由于我没能找到好的数据来做测试,所以我下面就用随机生成的数据来做为例子了
 
  说一下参考文章:加州理工学院公开课:机器学习与数据挖掘_线性模型

  首先,我们看一下PLA算法的问题:
  计算量太大,上次就20组数据不到,就要计算300+次

  下面我们就一步一步看看如何来优化
  1.先生成我们要用的数据
  
downr = Table[{xr = RandomReal[5], 
    yr = RandomReal[5 - xr] + RandomReal[.5], -1}, {200}];
upr =  Table[{xr = RandomReal[5], yr = RandomReal[{5 - xr, 5}], 
    1}, {150}];
   2.接着我们把图画出来
data = Join[downr, upr];
temp = data[[All, {1, 2}]];
p1 = ListPlot[
  Table[Style[temp[[i]], Hue[.25*data[[i, 3]] + .75]], {i, 1, 
    Length[data]}],
  AxesOrigin -> {0, 0}, ImageSize -> Large]

现在有两种颜色的点,我们的任务就是找出一条直线,把这两条直线分开。

  3.我们还是使用之前的PLA算法,迭代15000次
 
x = data[[All, {1, 2}]];
y = data[[All, 3]];
lengthx = Length[x];
x = Prepend[x[[#]], 1] & /@ Table[i, {i, 1, lengthx}];
DIEDAI = 15000;
(*迭代次数为15000次*)
Ein = 0;
EinTable = Table[0, {DIEDAI }];
(*跟踪准确率*)
EinPocket = {0, 0, 0};
(*存放最好的w*)
EinPN = 0;
(*最好w对应的准确率*)
w = {0, 0, 0};
Do[
 (*i是用来在x和y中循环的*)
 i = Mod[index, lengthx];
 If[
  Sign[w.x[[i]]] != y[[i]],
  (*Print[{Sign[w.x[[i]]],y[[i]],index,i,w,x[[2]]}];*)
  w = w + y[[i]]*x[[i]];
  (*每次更换w,都计算下新的w的准确率*)
  len = 0;
  Do[
   If[
    Sign[w.x[[j]]] != y[[j]],
    len = len + 1;
    ]
   , {j, 1, lengthx}];
  (*----------------*)
  Ein = 1 - len/lengthx;
  (*如果准确率变高了,就把最高的放在口袋里*)
  If[EinPN < Ein , EinPocket = w; EinPN = Ein];
  ];
 EinTable[[index]] = Ein ;
 , {index, 1, DIEDAI}]
  4.画出迭代后的图和准确率变化的图

  画准确率变化图
ListLinePlot[EinTable, InterpolationOrder -> 0, PlotRange -> Full, 
 AxesLabel -> {Style["迭代次数", 25, Bold], Style["准确率", 25, Bold]}, 
 ImageSize -> Large]
  画线
k1 = -w[[2]]/w[[3]];
k2 = -w[[1]]/w[[3]];
p2 = Plot[k1*x + k2, {x, 0, 5.3}, PlotRange -> Full];
Show[p1, p2]


我们可以看到最后分割的直线并不好,观察右边的准确率的图可以发现,迭代的最后一步并不是准确率最好的。
于是我们使用口袋法。什么是口袋算法呢?
口袋算法就是增加一个跟踪器,该跟踪器跟踪最好的结果,并把它记录下来。这样在最后的时候,跟踪器就保留了所有迭代中表现的做好的那次迭代。可是为什么叫做口袋算法而不是什么其它的?作者解析说:想象一下,每次都把最好的结果放到口袋里,当发现更好的结果的时候,就把更好的放到你的口袋中并丢弃口袋中原有的结果。最后当算法结束时,你只需要把你口袋里面的结果拿出来就是了。所以叫做口袋算法。
上面的代码已经是口袋算法的了。

  5.我们画出使用口袋算法时的分割图
k1 = -EinPocket[[2]]/EinPocket[[3]];
k2 = -EinPocket[[1]]/EinPocket[[3]];
p2 = Plot[k1*x + k2, {x, 0, 5.3}];
Show[p1, p2]


  可以看到这张图就比上面的要好很多了

  但是还有个问题,就是每次都从初始w={0,0,0}开始迭代,这样比较慢,有更加好的方法吗,答案是有的。

  6.先使用线性回归来确定初始迭代点 
lm = LinearModelFit[data, {x1, x2}, {x1, x2}];
w = lm["BestFitParameters"];
k1 = -w[[2]]/w[[3]];
k2 = -w[[1]]/w[[3]];
p2 = Plot[k1*x + k2, {x, 0, 5.3}, PlotRange -> Full];
Show[p1, p2]
 
  这里插一句:本来线性回归计算出来的函数如下:

  我们用来预测的话是写成 y = -2.3+0.3*x1+0.57*x2 ,
  但是这里我们不这么用,上面那张图里的直线就是把{-2.3,0.3,0.57}看出w。两种颜色其实就是    -2.3+0.3x+0.57y>0(<0)的部分,所以那条直线就是用 -2.3+0.3x+0.57y = 0画出来的。

  7.接着用上面的w来作为初始迭代值 
x = data[[All, {1, 2}]];
y = data[[All, 3]];
lengthx = Length[x];
x = Prepend[x[[#]], 1] & /@ Table[i, {i, 1, lengthx}];
DIEDAI = 15000;
(*迭代次数为15000次*)
Ein = 0;
EinTable = Table[0, {DIEDAI }];
(*跟踪准确率*)
EinPocket = {0, 0, 0};
(*存放最好的w*)
EinPN = 0;
(*最好w对应的准确率*)
lm = LinearModelFit[data, {x1, x2}, {x1, x2}];
w = lm["BestFitParameters"];
Do[
 (*i是用来在x和y中循环的*)
 i = Mod[index, lengthx];
 If[
  Sign[w.x[[i]]] != y[[i]],
  (*Print[{Sign[w.x[[i]]],y[[i]],index,i,w,x[[2]]}];*)
  w = w + y[[i]]*x[[i]];
  (*每次更换w,都计算下新的w的准确率*)
  len = 0;
  Do[
   If[
    Sign[w.x[[j]]] != y[[j]],
    len = len + 1;
    ]
   , {j, 1, lengthx}];
  (*----------------*)
  Ein = 1 - len/lengthx;
  (*如果准确率变高了,就把最高的放在口袋里*)
  If[EinPN < Ein , EinPocket = w; EinPN = Ein];
  ];
 EinTable[[index]] = Ein ;
 , {index, 1, DIEDAI}]

  8. 画出迭代后的图和准确率变化的图
 
可以看到比之前好点(其实我是挑了一个好点的,有时候结果也并不是都是好的)
这里最后结点正好在高点上,可以看准确率的图

  9.画出使用口袋法的图
 

  到这里,我们就基本把两种颜色的点分开了。还是使用了PLA算法,不过使用了线性回归来确定其初始迭代点,使用口袋法找到其最好的值。

 

下面还是讲一下我自己做的一个小作品。

下面链接是自己做的一个小作品,是用来学习汉字结构的,我们将汉字的结构具体展现出来了,摆脱了以往汉字教学中的模糊概念,希望大家可以看看多提提意见。

汉字结构学习

以上,所有
2017/2/10

转载于:https://www.cnblogs.com/wmn7q/p/7265515.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值