欢迎关注我的个人博客blog.timene.com

这个算法真是不太好懂,看了好几遍终于有点入门的感觉,就赶紧记录下这点感觉。我从复习线性分类开始,然后复习点积的含义,再引出核方法。

线性分类是最容易理解的分类方法,两组数据A和B,分别求出A和B的平均值,比如M和N,当判断新数据X是属于A还是属于B呢,就看新数据X到M近还是N近,X属于距离近的那个。为了实现这个算法,我们需要计算出各分类的均值点:

def lineartrain(rows):averages={}counts={}for row in rows:# Get the class of this pointcl=row.matchaverages.setdefault(cl,[0.0]*(len(row.data)))counts.setdefault(cl,0)# Add this point to the averagesfor i in range(len(row.data)):averages[cl][i]+=float(row.data[i])# Keep track of how many points in each classcounts[cl]+=1# Divide sums by counts to get the averagesfor cl,avg in averages.items():for i in range(len(avg)):avg[i]/=counts[cl]return averages

下来就可以给分类了,计算要分类的坐标点到各个分类的均值点的距离,然后从中选择距离最近者。

这里我们采用另一种方法,使用向量和点积。向量具有大小和方向,我们通常将其表示成平面的一个箭头。所谓点积,针对两个向量,将第一个向量中的每个值雨第二个向量中的对应值相乘,然后再将所得的每个乘积相加,最后得到一个总的结果。

def dotproduct(v1,v2):return sum([v1[i]*v2[i] for i in range(len(v1))])

点积也可以利用两个向量的长度乘积,再乘以两者夹角的余弦求得。最重要的是,如果夹角的度数大于90度,夹角余弦值为负,这样点积结果也就是负了。


M0和M1分别是分类0和分类1的均值点,C为M0和M1的中心点,还有两个点即将分类的点X1和点X2。很明显X1离M0近一点,应该划归为分类0,X2离M1近一些,应该划归为分类1。同时也注意到,向量X1--->C的向量M0--->M1的夹角小于90度,因此X1--->C和M0--->M1的点积结果为正数;向量X2--->C的向量M0--->M1的夹角大于90度,因此X2--->C和M0--->M1的点积结果为负数。由此,只需通过观察点积结果的正负,就可以判断出新坐标的类属。

点C为M0和M1的均值点,亦即(M0+M1)/2,所以寻找分类的公式如下:

class=sign((X-(M0+M1)/2) . (M0-M1))

相乘后的结果为:

class=sign(X.M0 - X.M1 + (M1.M1 - M0.M0)/2)

我们可以利用上面的公式来确定分类了:

def dpclassify(point,avgs):b=(dotproduct(avgs[1],avgs[1])-dotproduct(avgs[0],avgs[0]))/2y=dotproduct(point,avgs[0])-dotproduct(point,avgs[1])+bif y>0: return 0else: return 1

到这里,一切都很正常。正常的事情往往又不正常,目前正常的局面是,可以用到两个点的距离,也就是一个超平面来分割开分类0和分类1。不正常的局面是,面对下图着这种情况好像又鞭长莫及了,分类的均值点重合,尽管大家很清楚,任何位于圈圈内的都是X,圈圈外的都是O,但是线性分类器却无法识别这两个分类。

可是我们又发现,如果对每个点的x和y求平方,会是什么样呢?这样所有X都偏移到了图上的角落处,所有的O位于角落以外的区域,这样我们就可以用线性分类器来处理了。

上面的两站图说明:通过对坐标点的变换,构造出一个只用一条直线进行划分新数据是有可能的。有时我们需要升级维度,比如将一个x和y坐标的数据集,变换成一个由a,b,c三个坐标构成的新数据集,其中a=x*x,b=x*y,c=y*y。

尽管我们可以把数据依照上面的方式变换到新的坐标系中,但通常我们不会这么去做,下面来聊聊核技法。核技法的思路是用一个新的函数取代上面的点积函数,而不是将数据变换奥新坐标系中。一种备受推崇的方法被成为径向基函数,这个函数于点积类似,接受两个向量作为输入参数,并返回一个标量,与点积不同的是,径向基函数是非线性的,因而它能够将数据映射到更为复杂的空间中。

def rbf(v1,v2,gamma=10):dv=[v1[i]-v2[i] for i in range(len(v1))]l=veclength(dv)return math.e**(-gamma*l)

现在我们需要一个新函数,来计算坐标点在变换后的空间中与均值点的距离。遗憾的是,目前的均值是在原始空间中计算得到的,因为此处无法直接使用他们。所幸的是,先对一组向量求均值,然后再计算均值与向量A的点积结果,与先对向量A与该组向量中的每一个向量求点积,然后再计算均值,在效果上是等价的。因此,我们不再尝试对分类的两个坐标点求点积,也不在计算某个分类的均值点,取而代之的是,计算出某个坐标点与分类中其余每个坐标点之间的点积或径向基函数的结果,然后在对他们求均值。 再来看一遍这个函数  class=sign(X.M0 - X.M1 + (M1.M1 - M0.M0)/2)。 我们不直接去求M0和M1了,但心里必须清楚M0,M1是中心点,是径向基函数结果的平均值。

def nlclassify(point,rows,offset,gamma=10):sum0=0.0sum1=0.0count0=0count1=0for row in rows:if row.match==0:sum0+=rbf(point,row.data,gamma)count0+=1else:sum1+=rbf(point,row.data,gamma)count1+=1y=(1.0/count0)*sum0-(1.0/count1)*sum1+offsetif y>0: return 0else: return 1def getoffset(rows,gamma=10):l0=[]l1=[]for row in rows:if row.match==0: l0.append(row.data)else: l1.append(row.data)sum0=sum(sum([rbf(v1,v2,gamma) for v1 in l0]) for v2 in l0)sum1=sum(sum([rbf(v1,v2,gamma) for v1 in l1]) for v2 in l1)return ((1.0/(len(l1)**2))*sum1-(1.0/(len(l0)**2))*sum0)/2

注意函数getoffset函数就是求 (M1.M1 - M0.M1)/2,nlclassify函数就是具体的分类了。

集体智慧编程学习之核方法相关推荐

  1. 集体智慧编程学习笔记——第一讲

    1. 用户相似度评价 (1)欧几里德距离 (2)皮尔逊相关度评价 (3)jaccard 系数 (4)曼哈顿距离算法 转载于:https://www.cnblogs.com/gylhaut/p/9377 ...

  2. 《集体智慧编程》——第一章导读

    为什么80%的码农都做不了架构师?>>>    什么是集体智慧 其含义是指:为了长早新的想法,而将一群人的行为.偏好或思想组合在一起. 完成这项工作的一种最为基础的方法,便是使用调查 ...

  3. 《集体智慧编程》读书笔记2

    最近重读<集体智慧编程>,这本当年出版的介绍推荐系统的书,在当时看来很引领潮流,放眼现在已经成了各互联网公司必备的技术. 这次边阅读边尝试将书中的一些Python语言例子用C#来实现,利于 ...

  4. 《集体智慧编程》读书笔记10

    最近重读<集体智慧编程>,这本当年出版的介绍推荐系统的书,在当时看来很引领潮流,放眼现在已经成了各互联网公司必备的技术. 这次边阅读边尝试将书中的一些Python语言例子用C#来实现,利于 ...

  5. 《集体智慧编程》读书笔记4

    最近重读<集体智慧编程>,这本当年出版的介绍推荐系统的书,在当时看来很引领潮流,放眼现在已经成了各互联网公司必备的技术. 这次边阅读边尝试将书中的一些Python语言例子用C#来实现,利于 ...

  6. 《集体智慧编程》数学公式

    这篇博客的目的主要是为了记录这些公式,取自原书附录B. 1.欧几里得距离(Euclidean Distance) 用途:计算距离,衡量相似度 公式: 代码实现: def euclidean(p, q) ...

  7. 《集体智慧编程》笔记(1 / 12):集体智慧导言

    文章目录 什么是集体智慧 什么是机器学习 机器学习的局限性 真实生活中的例子 学习型算法的其他用途 小结 Netflix, Google都适用了先进算法,将来自不同人群的数据加以组合,进而得出新的结论 ...

  8. 《集体智慧编程》第九章

    1.P210 函数scaledata()在运行时会报错: AttributeError: 'list' object has no attribute 'data' 这是由于函数scaledata() ...

  9. 《集体智慧编程》第六章

    1.P126代码 为了定义阈值,请修改初始化方法,在classifier中加入一个新的实例变量: def __init__(self, getfeatures):classifier.__init__ ...

最新文章

  1. OS X 10.11 cocoapods
  2. mysql分页原理和sqlserver里面序列的用法
  3. Maven开发笔记(四)—— Maven中plugins和pluginManagement
  4. 何恺明一作,刷新7项检测分割任务,无监督预训练完胜有监督
  5. mybatis 显示 sql日志
  6. CentOS 使用spawn-fcgi配置Nginx+PHP 启动脚本
  7. vscode之parcel清空dist目录
  8. BZOJ 4520: [Cqoi2016]K远点对
  9. M1 Mac 档案的临时暂存区工具: Yoink
  10. 【verilog教程】第10篇:verilog代码规范
  11. 华为hs8145v5如何改桥接_华为 光猫 HS8546V5 改 桥接模式 简易教程
  12. 完全没有建站经验的人,怎么自己做网站
  13. oracle weituxinxi,Oracle 语句记录
  14. 趣味解析,斗鱼直播大数据的玩法儿
  15. 案例:模拟京东快递单号的查询效果
  16. Codeforces Round #583 (Div. 1 + Div. 2, based on Olympiad of Metropolises)
  17. 常见噪声及其消除的方式
  18. 记第一次编译Linux内核
  19. Qt 之设置 QWidget 背景色
  20. H3C单臂路由的配置

热门文章

  1. Spring核心AOP(面向切面编程)总结
  2. 贾俊平统计学思维导图- 第三章 数据的图表展示
  3. python int 转byte,byte转int
  4. UltraWinGrid冻结列和dataGridView冻结列
  5. webservice 暴漏接口_解决java web 项目发布webservice接口
  6. 基于Web的小型购书网站
  7. 黑莓9000刷机WIN7+DM6.0+ROM5.0+BBSAKv成功及安装使用经验
  8. bcrypt.dll怎么修复?bcrypt.dll修复工具下载
  9. 产品样机展示客户不满意?试试用Visualize这样做!
  10. 批处理判断文件夹是否为空