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

来源:互联网 发布:淘宝卖家如何实名认证 编辑:程序博客网 时间:2024/04/30 04:03
[机器学习][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

0 0
原创粉丝点击