機(jī)器學(xué)習(xí)-2 感知機(jī)【附代碼】

返回主頁(yè)


感知機(jī)(perceptron)屬于判別模型,是神經(jīng)網(wǎng)絡(luò)與SVM的基礎(chǔ)媒吗,由 Rosenblatt 于1957年提出念搬。

1 假設(shè)空間

感知機(jī)的假設(shè)空間

2 目標(biāo)函數(shù)及其推導(dǎo)
2.1 數(shù)據(jù)集的線性可分性

數(shù)據(jù)集的線性可分性

2.2 目標(biāo)函數(shù)及其推導(dǎo)
損失函數(shù)-1
如果用誤分類點(diǎn)的總數(shù)來(lái)定義經(jīng)驗(yàn)損失函數(shù)瓷产,會(huì)因?yàn)椴豢蓪?dǎo)而難以優(yōu)化

損失函數(shù)-2


用誤分類點(diǎn)到超平面的距離來(lái)定義損失函數(shù)

所以倒慧,感知機(jī)的學(xué)習(xí)算法是誤分類點(diǎn)驅(qū)動(dòng)的按摘,L(w,b)非負(fù),如果沒(méi)有誤分類點(diǎn)纫谅,損失函數(shù)值為0院峡,而且誤分類點(diǎn)越少、或誤分類點(diǎn)離超平面越近系宜,損失函數(shù)值就越小。

3 優(yōu)化算法
3.1 原始形式

感知機(jī)使用隨機(jī)梯度下降

步驟:
(1)发魄、選取初始值w0 = 0, b0 = 0
(2)盹牧、在訓(xùn)練集中隨機(jī)選取數(shù)據(jù)(xi, yi)
(3)、如果yi(wxi + b) <= 0励幼,則執(zhí)行隨機(jī)梯度下降
(4)汰寓、轉(zhuǎn)至(2),直至訓(xùn)練集中沒(méi)有誤分類點(diǎn)

注:原始形式由于采用不同的初始值或隨機(jī)樣本點(diǎn)的不同苹粟,會(huì)得到不同的解有滑。

3.2 收斂性證明
第一步


第二步


第三步


第四步

手寫 Perceptron 算法并與 Sklearn 作比較

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function
import numpy as np
import pandas as pd
import random as rd
import matplotlib.pyplot as plt
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Perceptron

class PerceptronModel(object):
    def __init__(self, w_init, b_init, lr, max_iter):
        self.w_init = w_init
        self.b_init = b_init
        self.lr = lr
        self.max_iter = max_iter
    
    def get_loss(self, x_train, y_train, w, b):
        wrong_sample = (y_train.reshape(-1,1) * (x_train.dot(w) + b) <= 0).reshape(-1)
        x_wrong = x_train[wrong_sample]
        y_wrong = y_train[wrong_sample]
        loss = -y_wrong.dot(x_wrong.dot(w) + b)
        return loss[0]
    
    def fit(self, x_train, y_train):
        # 計(jì)算初始損失值
        loss_init = self.get_loss(x_train, y_train, self.w_init, self.b_init)
        loss_res = []; loss_res.append(loss_init)
        # 保存參數(shù)
        w_res = []; w_res.append(self.w_init)
        b_res = []; b_res.append(self.b_init)
        # 迭代優(yōu)化
        for step in range(self.max_iter):
            # 隨機(jī)抽樣一個(gè)樣本
            idx = rd.sample(range(len(x_train)), 1)
            x_, y_ = x_train[idx], y_train[idx]
            # 當(dāng)出現(xiàn)誤判時(shí)進(jìn)行梯度下降
            if y_ * (x_.dot(w_res[-1]) + b_res[-1]) <= 0:
                w = w_res[-1] + (self.lr*y_*x_).T
                b = b_res[-1] + self.lr*y_
            else:
                continue
            # 更新?lián)p失值,保存參數(shù)
            loss = self.get_loss(x_train, y_train, w, b)
            loss_res.append(loss); w_res.append(w); b_res.append(b)
        # 取損失值最小的參數(shù)為最優(yōu)參數(shù)
        w_best = w_res[np.argmin(loss_res)]
        b_best = b_res[np.argmin(loss_res)]
        return loss_res, w_best, b_best
    
    def predict(self, x, w, b):
        y_pred = np.sign(x.dot(w) + b).reshape(-1)
        return y_pred
    
    def get_score(self, y_true, y_pred):
        score = sum(y_true == y_pred) / len(y_true)
        return score


if __name__ == "__main__":
    # 構(gòu)造二分類數(shù)據(jù)集
    N = 500
    x1 = np.random.uniform(low=1, high=5, size=[N,2]) + np.random.randn(N, 2)*0.01
    y1 = np.tile(-1, N)
    
    x2 = np.random.uniform(low=5, high=10, size=[N,2]) + np.random.randn(N, 2)*0.01
    y2 = np.tile(1, N)
    
    x = np.concatenate([x1,x2], axis=0)
    y = np.concatenate([y1,y2])
    
    x, y = shuffle(x, y, random_state=0)
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
    
    # 參數(shù)初始化
    w_init = np.zeros([x.shape[1], 1]) + 0.001
    b_init = 0
    lr = 0.01
    max_iter = 5000
    
    # 運(yùn)行自寫算法
    model = PerceptronModel(w_init, b_init, lr, max_iter)
    loss_res, w_best, b_best = model.fit(x_train, y_train)
    
    y_pred = model.predict(x_test, w_best, b_best)
    score = model.get_score(y_test, y_pred)
    print(f"PerceptronModel 預(yù)測(cè)準(zhǔn)確率:{score}")
    
    fig, ax = plt.subplots(figsize=(8,6))
    ax.plot(loss_res)
    plt.xlabel("steps")
    plt.ylabel("loss")
    plt.title("Loss")
    plt.show()

    fig, ax = plt.subplots(figsize=(8,6))
    x_axis = np.linspace(1, 10, 10)
    y_axis = -(w_best[0]*x_axis + b_best) / w_best[1]
    ax.plot(x_axis, y_axis, color="red")
    ax.scatter(x=x_test[:,0], y=x_test[:,1], c=y_test, label=y_test)
    plt.xlabel("x1")
    plt.ylabel("x2")
    plt.title("PerceptronModel")
    plt.show()
    
    # 收斂性驗(yàn)證
    mod_res = []
    for i in range(len(x_train)):
        mod = np.sqrt(np.sum(x_train[i]**2))
        mod_res.append(mod)
    R = np.max(mod_res)
    w_aug = np.append(w_best, b_best)
    C = np.sqrt(np.sum(w_aug**2))
    r = np.min(y_train.reshape(-1,1) * (x_train.dot(w_best) + b_best))
    k = np.floor((R*C / r)**2)
    print(f"理論上嵌削,基于當(dāng)前數(shù)據(jù)集毛好,算法的收斂上界為{k}輪")
    
    # 運(yùn)行sklearn算法
    clf = Perceptron(eta0=lr, fit_intercept=True, max_iter=max_iter, tol=0.001)
    clf.fit(x_train, y_train)
    
    w = clf.coef_[0]
    b = clf.intercept_
    y_pred = clf.predict(x_test)
    score = sum(y_test == y_pred) / len(y_test)
    print(f"PerceptronSklearn 預(yù)測(cè)準(zhǔn)確率:{score}")
        
    fig, ax = plt.subplots(figsize=(8,6))
    x_axis = np.linspace(1, 10, 10)
    y_axis = -(w[0]*x_axis + b) / w[1]
    ax.plot(x_axis, y_axis, color="red")
    ax.scatter(x=x_test[:,0], y=x_test[:,1], c=y_test, label=y_test)
    plt.xlabel("x1")
    plt.ylabel("x2")
    plt.title("PerceptronModel")
    plt.show()

PerceptronModel 預(yù)測(cè)準(zhǔn)確率:1.0
理論上望艺,基于當(dāng)前數(shù)據(jù)集,算法的收斂上界為7262972.0輪



PerceptronSklearn 預(yù)測(cè)準(zhǔn)確率:1.0



返回主頁(yè)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肌访,一起剝皮案震驚了整個(gè)濱河市找默,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吼驶,老刑警劉巖惩激,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蟹演,居然都是意外死亡风钻,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門酒请,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)骡技,“玉大人,你說(shuō)我怎么就攤上這事蚌父∠迹” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵苟弛,是天一觀的道長(zhǎng)喝滞。 經(jīng)常有香客問(wèn)我,道長(zhǎng)膏秫,這世上最難降的妖魔是什么右遭? 我笑而不...
    開(kāi)封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮缤削,結(jié)果婚禮上窘哈,老公的妹妹穿的比我還像新娘。我一直安慰自己亭敢,他們只是感情好滚婉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著帅刀,像睡著了一般让腹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扣溺,一...
    開(kāi)封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天骇窍,我揣著相機(jī)與錄音,去河邊找鬼锥余。 笑死腹纳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘲恍,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼足画,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蛔钙?” 一聲冷哼從身側(cè)響起锌云,我...
    開(kāi)封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吁脱,沒(méi)想到半個(gè)月后桑涎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兼贡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年攻冷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遍希。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡等曼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凿蒜,到底是詐尸還是另有隱情禁谦,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布废封,位于F島的核電站州泊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏漂洋。R本人自食惡果不足惜遥皂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刽漂。 院中可真熱鬧演训,春花似錦、人聲如沸贝咙。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)庭猩。三九已至乌奇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間眯娱,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工爬凑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留徙缴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像于样,于是被迫代替她去往敵國(guó)和親疏叨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容