K-最近相邻(2)

 

K-最近邻算法的一大缺陷是:维度危机(curse  of  dimensionality)。当有大量不相干的属性存在时,近邻间的距离会被大量的不相关属性所支配。

 

比如,在数据集方面。在《K-最近相邻(1)》中的数据集是单一的,值域范围相同的,且对结果有着同样影响力的;但可能实际的数据集比之更为复杂。

例如:可能存在值域范围不同的变量(例如,酒瓶的大小);或者完全不相干的变量(如,酒瓶的颜色etc。)在实际的学习器训练中,我们不应该对这些因素考虑(针对不相干的变量),或者因对之进行合理的处理(如,值域范围不同的变量)。

 

我们来构造一个全新的数据集

 

这段代码构造了一乌七八糟什么都有的数据集。

如果使用我们前面的算法,会将这所有的数据,有用的无用的值域相同的值域不同的,同等对待,那么结果可能是这样的(幸亏我们可以交叉测试):

 

 

嗯,这个结果,不太好。。。

我们应该对不同变量(要素)区别对待。

 

解决维数危机的方法可以有:

1.当计算两个实例间的距离时对每个属性加权。

2.从实例空间中完全消除最不相关的属性。

 

按比例缩放(这里顺带进行了不相干属性的消除操作)

对数值进行归一化处理,从而使所有变量都位于相同的值域之内。对每一维度上的数值乘以该维度上的一个常量。

如果要忽略某些值,则将这些值乘以0,这样就自然地忽略了。(这其实也是在按比例缩放,只不过缩放的比例是0。。。)

 

我们来测试一下:

 

结果大约如下:

 

可以看出,缩放后的效果总体上是好于所缩放前的。

(PS1:如何进行缩放是关键。这里所使用的缩放方法是乘以一个因子,我们的例子中使用的是:sdata = rescale(data_x, [1,1,0,0.01]),乘以1表示不缩放,乘以0,表示忽略该项。)

(PS2:其实这里的比较并没有多大的意义;因为算法是随机产生一个随机数来进行数据集的划分的,两次随机产生的数据集并不相同;但鉴于数据集被缩放过的,所以无论如何划分数据集,所进行的总是:未缩放的数据与已缩放的数据之间的比较,所以还是具有一定的意义的)

(PS3:书《集体智慧编程》上给出的例子中缩放前喝缩放后的比较那叫一个明显啊。。。)

 

缩放参数确定的自动化进行

以上的数据是我们自己生成的,但如果我们事先并不知道这些数据(例如特征etc。)那么我们该选择什么缩放参数呢?

嗯,我们的问题是:如何从一系列的答案中得到比较好的那个,那么很显然,应使用优化算法来自动确定优秀的缩放参数。

我们要做的只是写一个控制函数而已。

 

貌似如果使用lambda来定义该函数的话会产生错误的结果。。。

另,注意weightdomain 的定义。(这个在优化算法中已有大量讲到)

 

我们来调用一下:

 

geneticoptimize_x是以爬山法产生初始种群的遗传算法。geneticoptimize_x的运行效率显然是相当的可观。。。

运行结果大致如下:

 

(说大致是因为:我们定义的成本函数,从本质上讲,是个基于概率的函数,且在其中,概率发生的作用相当巨大,因此,在每次调用时,该成本函数对同样的序列并不能给出同样的结果,因此,geneticoptimize_x的种群的最优异者是每次都变化的。从本质上将,在geneticoptimize_x中,迭代N次与不迭代没有显著的区别(因为迭代的结果并不能保持到下次迭代中去,即是,优异者在种群的下次进化中死掉了。。。)。。。):

 

通过测试,该序列[15, 8, 0, 2]在geneticoptimize_x产生的成本结果是:

scores =  (2647.7657340720734, [15, 8, 0, 2])

这在以后调同样的函数后,得到的成本结果却达不到该值。。。

 

基于以上的讨论,你可能认为,既然geneticoptimize_x的优异者并不能保持到下次种群进化中,也就是说,geneticoptimize_x中只有第一次爬山法产生的序列是真正有意义的,那么不如直接使用爬山法来得到序列得了。

但测试后发现,直接用爬山法得到的序列并不是很好。这大约是因为,geneticoptimize_x中我们产生的初始种群是由爬山法进行了N次获得的,且在geneticoptimize_x的main loop中叶并不是完全没有意义。。。

 

在测试中,遇到过这样的问题:

 

    return error/len(testset)

ZeroDivisionError: int division or modulo by zero

原来是len(testset)中testset是基于概率产生的,那么完全可能产生一个长度为0的testset。。。(汗,这概率。。。)

 

修改后的testalgorithm如下:

 

这让我想起《蝙蝠侠2》中的台词:“只有概率是公平的”。。。

 

以此来确定最佳参数还有额外的一个好处便是:我们可以通过所优化得到的参数判断出哪些参数是重要的,哪些是不太重要的,哪些是可以忽略的。。。如此在搜集数据时候,就可以有针对性的进行(比如,我们不会去费力收集某些实际上无用的数据。。。)。

 

嗯,看起来这篇博文字数不太多。。。那就贴个K-最邻近算法的全部代码吧。

 

(PS:其中很多部分可以单独成模块,或和其他模块整合在一起。)

 

嗯,关于K-最近邻算法大约就是这么些了。

K-最近邻算法属于基于实例的机器学习方法。但基于实例的机器学习算法还有很多。如局部加权回归,径向基函数,基于案例的推理等。具体可参看《机器学习》等书籍。

 

By Kewing

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值