《统计学习方法》的Python实现:(1)感知机

0. 假装有一个前言

前几天看到有人转李航老师的《统计学习方法》python 3.6实现,突然发现书我是看了一半了,代码却只写过第三章的k近邻法。(不要问我为什么现在才看了一半,也不要问我为什么不一边看一边写)

1. 感知机原理

赶只鸡(划掉)

感知机(Perceptron)是二分类的线性分类模型,只适用于线性可分的二分类问题。


线性二分类问题
输入 输出 模型类型 参数意义
特征向量 类别(\pm1 判别模型 超平面参数

感知机的损失函数为所有误分类点到分类超平面的距离之和,因此算法是误分类驱动的,正确分类的点不会对算法的结果做出贡献。

2. 感知机学习算法的两种形式

2.1 原始形式

使用随机梯度下降法,针对每个误分类使其梯度下降。


算法2.1_感知机学习算法的原始形式
输入:训练数据集 T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\} ;学习率 \eta(0<\eta\leq1)
输出:w,b;感知机模型f(x)=\text{sign}(w\cdot x+b).
1 选取初值w_0,b_0
2 在训练集中选取数据(x_i,y_i)
3 如果y_i(w\cdot x+b)\leq 0
w \leftarrow w+\eta y_ix_i \\ b \leftarrow b+ \eta y_i
4 如果训练集中存在误分类点,转至 2;否则,结束


def trainOri(self,yita = 0.1):
        self.w = self.w0
        self.b = self.b0
        misDivision = True
        self.yita = yita
        self.k = 0
        while misDivision:
            for it in range(len(self.data)):
                if self.label[it] * (np.dot(self.w, self.data[it]) + self.b) <= 0:
                    self.w += self.yita * self.label[it] * self.data[it]
                    self.b += self.yita * self.label[it]
                    self.k += 1
                    break
                if it == len(self.data) - 1:
                    misDivision = False

原始形式这里没有问题,对1000个2维数据进行分类使用了0.14s,更新次数为7470

PerceptronOri

2.2 对偶形式

使用随机梯度下降法,针对每个误分类使其梯度下降。


算法2.2_感知机学习算法的对偶形式
输入:训练数据集 T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\} ;学习率 \eta(0<\eta\leq1)
输出:\alpha,\beta;感知机模型f(x)=\text{sign}(\sum_{j=1}^{N}\alpha_jy_jx_j\cdot x_i + \beta).
1 选取初值\alpha_0=\{\alpha_1,\alpha_2,...\alpha_N\}=\{0,...,0\},\beta_0=0
2 在训练集中选取数据(x_i,y_i)
3 如果y_i(\sum_{j=1}^{N}\alpha_jy_jx_j\cdot x_i + \beta)\leq 0
\alpha \leftarrow \alpha+\eta \\ \beta \leftarrow \beta+ \eta y_i
4 如果训练集中存在误分类点,转至 2;否则,结束


def trainDual(self, yita = 1):
        self.alpha = self.alpha0
        self.beta = self.beta0
        gram = []
        for it in self.data:
            temp = []
            for ot in self.data:
                temp.append(np.dot(it,ot))
            gram.append(temp)        
        misDivision = True
        self.yita = yita
        self.k = 0
        self.kk = 0
        while misDivision:
            for it in range(len(self.data)):
                temp = 0
                self.kk +=1
                if self.label[it] * (sum([self.alpha[i] * self.label[i] * gram[i][it] for i in range(len(self.data))]) + self.beta) <= 0:
                    self.alpha[it] += self.yita
                    self.beta += self.yita * self.label[it]
                    self.k += 1
                    break
                if it == len(self.data) - 1:
                    misDivision = False

对偶形式这里问题就大了,等了一分钟还以为是条件给错进入死循环了,反复检查确认没有问题,心想,跑去吧(其实去刷知乎了)。于是就有了下面这张图:


PerceptrDual

等一下,说好的使用Gram矩阵可以降低运算量呢?同样更新了七千多次为什么你跑了三分钟啊?!差了2000倍有木有啊!


emm

2.3 问题分析

1) 从编程角度分析

冷静分析一下,Gram矩阵计算时间只需0.6s基本可以忽略不记,由于刚刚只统计了参数更新次数,我们重新统计一下两种算法第三步的判别步骤:

判别步骤

原始算法判别15133次,更新参数239次,耗时0.016s
对偶算法判别16300次,更新参数235次,耗时33.29s

由算法2.1,2.2可知,参数更新基本不消耗时间,也即大部分时间用于判别步骤。原始算法平均耗时1.05\cdot 10^{-6}s,对偶算法平均耗时2ms。这中间也就差了,额,1931倍吧。
继续冷静分析,算法2.2中第三步计算量大的主要原因是有一个求积再求和的过程,这个过程也可以当作向量内积来计算,这样就实现了在一次参数更新前只计算一次\alpha_jy_j。这个部分书中没有提及,可能因为不属于算法而是计算方法的一部分吧。

更新对偶算法如下:

    def trainDual(self, yita = 1):
        self.alpha = self.alpha0
        self.beta = self.beta0
        gram = []
        for it in self.data:
            temp = []
            for ot in self.data:
                temp.append(np.dot(it,ot))
            gram.append(temp)
        gramA = np.array(gram)
        misDivision = True
        self.yita = yita
        self.k = 0
        self.kk = 0
        while misDivision:
            ay = np.array([self.alpha[x] * self.label[x] for x in range(len(self.alpha))])
            for it in range(len(self.data)):
                temp = 0
                self.kk +=1
                if self.label[it] * (np.dot(ay, gramA[it]) + self.beta) <= 0:
                    self.alpha[it] += self.yita
                    self.beta += self.yita * self.label[it]
                    self.k += 1
                    break
                if it == len(self.data) - 1:
                    misDivision = False  

同样,我们使用1000个2维数据进行测试,结果如下:


更新对偶算法之后

虽然对偶算法还是比原始算法慢了20倍左右,但最起码两者是接近量级的运行时间了。

2)从算法角度分析

样本包括三个属性:个数,特征向量尺寸和标签。对于感知机,标签与数据个数相同。Gram矩阵是将样本的特征向量两两做内积,当特征向量尺寸较大时对偶算法应该可以比原算法简化更多的计算量。
我们将数据由1000个2维数据提升为1000个1000维数据,此时两种算法结果对比如下:


1000维数据

虽然对偶算法依然慢于原始算法,但两者间的差距已经由30倍缩小到了2.5倍。

我们继续增加样本的维数,将维数提高到丧(gan)心(de)病(piao)狂(liang)的500,000维,为了硬盘着想,我们这次只生成了100条数据。


绝不会用记事本打开的文本文档

最终结果是,原始算法速度依然是对偶算法的两倍左右。


50w维数据

大概是我代码能力太烂?可能还需要进一步优化。另外1957年有500,000维的数据需要处理吗?

代码

项目地址

P.S. 大概也许有可能还会更新

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容

  • 【概述】 1、感知机模型特征:感知机对应于输入空间中将实例划分为正负两类的分离超平面,属于判别模型。 2、感知机策...
    sealaes阅读 3,115评论 2 3
  • 机器学习是做NLP和计算机视觉这类应用算法的基础,虽然现在深度学习模型大行其道,但是懂一些传统算法的原理和它们之间...
    在河之简阅读 20,500评论 4 65
  • 注:题中所指的『机器学习』不包括『深度学习』。本篇文章以理论推导为主,不涉及代码实现。 前些日子定下了未来三年左右...
    我偏笑_NSNirvana阅读 39,968评论 12 145
  • 本文总结了《统计学习方法》(李航)中的一些机器学习方法,组织目录如下: 【第1章】 统计学习方法概论【第2章】 感...
    牛奶芝麻阅读 4,423评论 0 13
  • 此刻,我正坐在火车站旁边的麦当劳里等着晚上的火车,今晚在这里中转,再次踏上离乡的旅程。 音响里正放着费翔的《故乡的...
    胡八毛阅读 207评论 0 3