机器学习|感知机代码实现解读

前言

如果你能找到这里,真是我的幸运~这里是蓝白绛的学习笔记,本集合主要针对《统计学习方法》这本书,主要是基本机器学习算法代码实现的解读。
本集合中的代码整理来自github:黄海广《统计学习方法》代码实现
本篇整理感知机实现,代码原作者github:wzyonggege《统计学习方法》笔记-基于Python算法实现

第二章 感知机

1、模型定义

  1. 感知机模型f(x) = {\rm sign}(w*x + b),
    其中w*x+b的值域是实数域R{\rm sign}是符号函数。
  2. 损失函数L(w, b) = -\sum_{x_i\in M}{y_{i}(w*x_{i} + b)},
    其中M是误分类点集合,感知机学习算法是误分类点驱动的。这里的y_i主要起取符号的作用,和式外面带上负号是因为误分类点与y_i的乘积一定为负,而损失函数最好为正。

2、模型训练

  1. 学习算法原始形式:采用随机梯度下降法,假设误分类点集合M是固定的,则损失函数L(w, b)的梯度为\nabla_wL(w,b)=-\sum_{x_i\in M}y_ix_i \nabla_bL(w,b)=-\sum_{x_i\in M}y_i根据y_i(w\cdot x_i+b)\leq0是否成立,随机选取误分类点(x_i,y_i),则wb的更新公式为:w\leftarrow w+\eta y_ix_i b\leftarrow b+\eta y_i其中\eta\in(0,1]为学习率。
  2. 算法收敛性:对于线性可分数据集,感知机学习算法原始形式收敛,即经过有限次迭代可以得到一个将训练数据集完全正确划分的分离超平面及感知机模型。(书中31页有证明)
  3. 学习算法对偶形式:从wb的更新公式中可看出,wb关于(x_i,y_i)的增量分别是\alpha_iy_ix_i\alpha_iy_i,即wb可以分别表示为w=\sum_{i=1}^N\alpha_iy_ix_i b=\sum_{i=1}^N\alpha_iy_i其中\alpha_i\geq0\alpha_i等于\eta乘以因点(x_i,y_i)误分类而更新的次数。也就是说,每次点(x_i,y_i)被误分类,则\alpha_i增加一个\eta
    根据y_i(\sum_{j=1}^N\alpha_jy_jx_j\cdot x_i+b)\leq0是否成立,随机选取一个误分类点(x_i,y_i),则更新公式为:\alpha_i\leftarrow\alpha_i+\eta b\leftarrow b+\eta y_i其中\eta\in(0,1]为学习率。

注:这里为什么将w替换成了\alpha_i,而b未替换,原因是b=\sum_{i=1}^N\alpha_iy_i,也就是说b能由\alpha计算出来。既然能计算出来,为什么更新公式还要两个,原因是b要及时更新,才能继续判断后面的点是否误分类。这里非常巧妙的是从b=\sum_{i=1}^N\alpha_iy_i可看出,如果此时点(x_i,y_i)误分类,那么只要将b在原基础上增加\eta y_i就行,而不是全部重新计算\sum_{i=1}^N\alpha_iy_i
并且,通常我们将b也看成w_0,将b对应的x_0的值令为1,更新了w也就更新了bb在原基础上增加\eta y_i,也就是w_0在原基础上增加了\eta y_i\cdot 1

  1. 对偶形式中,训练实例仅以内积的形式出现,可以预先将训练集实例间的内积计算出来并以矩阵的形式存储,这个矩阵就是Gram矩阵G=[x_i\cdot x_j]_{N\times N}

3、代码实现

这里只解读最关键的模型实现代码,完整的源代码由作者github:wzyonggege《统计学习方法》笔记-基于Python算法实现所编写,这里略去了iris数据准备等代码。该代码实现的是感知机学习算法的原始形式,我在原始代码的基础上进行了一定修改,测试通过。

class Model:
    def __init__(self):
        self.w = np.ones(len(data[0])-1, dtype=np.float32)# 初始化w参数为1
        self.b = 0
        self.l_rate = 0.1# 将学习率设置为0.1
        
    # sign函数主要用于后面判断点是否被误分类,不需要取符号,只计算w*x+b即可
    def sign(self, X):
        y = np.dot(X, self.w) + self.b
        return y
    
    # 原始代码中没有实现score方法,为实现score方法我添加了predict函数,在sign函数的基础上添加了取符号的过程
    def predict(self, X):
        y = np.dot(X, self.w) + self.b
        return 1 if y>0 else -1
    
    # 随机梯度下降法
    def fit(self, X_train, y_train):
        # 原始代码中这里本来是is_wrong = False,我觉得改成has_wrong = True比较好理解
        # 意为数据集中是否还有误分类的点,初始我们认为一定有误分类点,将has_wrong设置为True
        has_wrong = True
        while has_wrong:# 原始代码这里是while not is_wrong:,循环的主要功能是一直更新w和b,直到数据集中再没有误分类点
            wrong_count = 0# 每轮循环统计此次循环内的误分类点个数
            for d in range(len(X_train)):
                X = X_train[d]# 取一个点
                y = y_train[d]
                if y * self.sign(X) <= 0:# 如果该点是误分类点,则更新参数,并将wrong_count加一
                    self.w = self.w + self.l_rate*np.dot(y, X)# w <- w + learning_rate * np.dot(y_i * x_i)
                    self.b = self.b + self.l_rate*y# b <- b + learning_rate * y_i
                    wrong_count += 1
            if wrong_count == 0:# 直到该轮误分类点数为0,则将has_wrong设置为False,跳出循环
                has_wrong = False# 原始代码是is_wrong = True
            print('w =',self.w, 'b =',self.b)
        return 'Perceptron Model Done!'
        
    # 评价模型性能
    def score(self, X_test, y_test):
        count = 0# 用count来统计预测对的点的个数
        for d in range(len(X_test)):
            X = X_test[d]
            y = y_test[d]
            if y == self.predict(X):
                count += 1
        return count/len(X_test)

总的来说,fit()方法将整个数据集一次次进行遍历,每发现一个误分类点,则更新wb,直到没有误分类点为止。

结尾

如果您发现我的文章有任何错误,或对我的文章有什么好的建议,请联系我!如果您喜欢我的文章,请点喜欢~*我是蓝白绛,感谢你的阅读!

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

推荐阅读更多精彩内容

  • 线性模型 根据周志华老师的定义来说,线性模型是指其通过属性的线性组合来进行预测的函数,即用一般向量形式,则写成其中...
    怀柔小龙虾阅读 4,174评论 1 24
  • 最近在工作闲暇中也在追赶时代的潮流,于是就打起了机器学习的注意,通过网上查阅资料还有询问相关的从业人员,发现机器学...
    哇塞田阅读 3,244评论 8 25
  • 张小娴,香港知名作家 因/面包树上的女人/而声名鹊起 她以小说描绘爱情的热情与冷却 以散文倾诉恋人的微笑和泪水 起...
    南方的风景阅读 443评论 0 0
  • 九月情思 诗美景簇好丽浣 柳堤竹锦艳阳灿 湖畔秋雨点点寂 金秋月九藏思念
    纯水陆零阅读 339评论 0 13
  • “只要人人献出一点爱,世界将变成美好的人间……”我哼着小曲,手里拎着大包小包的食品玩具,带着满满的爱心,在爸...
    宝旺阅读 246评论 0 0