日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

數(shù)學(xué)推導(dǎo) 純Python實(shí)現(xiàn)機(jī)器學(xué)習(xí)算法6:感知機(jī)

 LibraryPKU 2019-03-28

Python機(jī)器學(xué)習(xí)算法實(shí)現(xiàn)

Author:louwill

     今天筆者要實(shí)現(xiàn)的機(jī)器學(xué)習(xí)算法是感知機(jī)(perceptron)。感知機(jī)是一種較為簡(jiǎn)單的二分類模型,但由簡(jiǎn)至繁,感知機(jī)卻是神經(jīng)網(wǎng)絡(luò)和支持向量機(jī)的基礎(chǔ)。感知機(jī)旨在學(xué)習(xí)能夠?qū)⑤斎霐?shù)據(jù)劃分為+1/-1的線性分離超平面,所以說(shuō)整體而言感知機(jī)是一種線性模型。因?yàn)槭蔷€性模型,所以感知機(jī)的原理并不復(fù)雜,本節(jié)筆者就和大家來(lái)看一下感知機(jī)的基本原理和Python實(shí)現(xiàn)。

感知機(jī)原理

     假設(shè)輸入x表示為任意實(shí)例的特征向量,輸出y={+1,-1}為實(shí)例的類別。感知機(jī)定義由輸入到輸出的映射函數(shù)如下:

     其中sign符號(hào)函數(shù)為:

     w和b為感知機(jī)模型參數(shù),也是感知機(jī)要學(xué)習(xí)的東西。w和b構(gòu)成的線性方程wx+b=0極為線性分離超平面。

     假設(shè)數(shù)據(jù)是線性可分的,當(dāng)然有且僅在數(shù)據(jù)線性可分的情況下,感知機(jī)才能奏效。感知機(jī)模型簡(jiǎn)單,但這也是其缺陷之一。所謂線性可分,也即對(duì)于任何輸入和輸出數(shù)據(jù)都存在某個(gè)線性超平面wx+b=0能夠?qū)?shù)據(jù)集中的正實(shí)例點(diǎn)和負(fù)實(shí)例點(diǎn)完全正確的劃分到超平面兩側(cè),這樣數(shù)據(jù)集就是線性可分的。

     感知機(jī)的訓(xùn)練目標(biāo)就是找到這個(gè)線性可分的超平面。為此,定義感知機(jī)模型損失函數(shù)如下:

     要優(yōu)化這個(gè)損失函數(shù),可采用梯度下降法對(duì)參數(shù)進(jìn)行更新以最小化損失函數(shù)。計(jì)算損失函數(shù)關(guān)于參數(shù)w和b的梯度如下:

     由上可知完整的感知機(jī)算法包括參數(shù)初始化、對(duì)每個(gè)數(shù)據(jù)點(diǎn)判斷其是否誤分,如果誤分,則按照梯度下降法更新超平面參數(shù),直至沒(méi)有誤分類點(diǎn)。

     以上便是感知機(jī)算法的基本原理。當(dāng)然這里說(shuō)的感知機(jī)僅限于單層的感知機(jī)模型,僅適用于線性可分的情況。對(duì)于線性不可分的情形,筆者將在后續(xù)的神經(jīng)網(wǎng)絡(luò)和感知機(jī)兩講詳細(xì)介紹。

感知機(jī)算法實(shí)現(xiàn)

     完整的感知機(jī)算法包括參數(shù)初始化、模型主體、參數(shù)優(yōu)化等部分,我們便可以按照這個(gè)思路來(lái)實(shí)現(xiàn)感知機(jī)算法。在正式寫模型之前,我們先用sklearn來(lái)準(zhǔn)備一下示例數(shù)據(jù)。

# 導(dǎo)入相關(guān)庫(kù)import pandas as pdimport numpy as npfrom sklearn.datasets import load_irisimport matplotlib.pyplot as plt
# 導(dǎo)入iris數(shù)據(jù)集iris = load_iris()df = pd.DataFrame(iris.data, columns=iris.feature_names)df['label'] = iris.targetdf.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
# 繪制散點(diǎn)圖plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], c='red', label='0')plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], c='green', label='1')plt.xlabel('sepal length')plt.ylabel('sepal width')plt.legend();

# 取兩列數(shù)據(jù)并將并將標(biāo)簽轉(zhuǎn)化為1/-1data = np.array(df.iloc[:100, [0, 1, -1]])X, y = data[:,:-1], data[:,-1]y = np.array([1 if i == 1 else -1 for i in y])

下面正式開(kāi)始模型部分。先定義一個(gè)參數(shù)初始化函數(shù):

# 定義參數(shù)初始化函數(shù)def initilize_with_zeros(dim): w = np.zeros(dim) b = 0.0 return w, b

然后定義sign符號(hào)函數(shù):

# 定義sign符號(hào)函數(shù)def sign(x, w, b):    return np.dot(x,w)+b

最后定義模型訓(xùn)練和優(yōu)化部分:

# 定義感知機(jī)訓(xùn)練函數(shù)def train(X_train, y_train, learning_rate): # 參數(shù)初始化 w, b = initilize_with_zeros(X_train.shape[1]) # 初始化誤分類 is_wrong = False while not is_wrong: wrong_count = 0 for i in range(len(X_train)): X = X_train[i] y = y_train[i] # 如果存在誤分類點(diǎn) # 更新參數(shù) # 直到?jīng)]有誤分類點(diǎn) if y * sign(X, w, b) <= 0: w = w + learning_rate*np.dot(y, X) b = b + learning_rate*y wrong_count += 1 if wrong_count == 0: is_wrong = True print('There is no missclassification!') # 保存更新后的參數(shù) params = { 'w': w, 'b': b } return params

對(duì)示例數(shù)據(jù)進(jìn)行訓(xùn)練:

params = train(X, y, 0.01)params

最后對(duì)訓(xùn)練結(jié)果進(jìn)行可視化,繪制模型的決策邊界:

x_points = np.linspace(4, 7, 10)y_hat = -(params['w'][0]*x_points + params['b'])/params['w'][1]plt.plot(x_points, y_hat)
plt.plot(data[:50, 0], data[:50, 1], color='red', label='0')plt.plot(data[50:100, 0], data[50:100, 1], color='green', label='1')plt.xlabel('sepal length')plt.ylabel('sepal width')plt.legend()

最后,我們也可以建一個(gè)perceptron類來(lái)方便調(diào)用。對(duì)上述代碼進(jìn)行整理:

class Perceptron:    def __init__(self):        pass        def sign(self, x, w, b):        return np.dot(x, w) + b        def train(self, X_train, y_train, learning_rate):        # 參數(shù)初始化        w, b = self.initilize_with_zeros(X_train.shape[1])        # 初始化誤分類        is_wrong = False        while not is_wrong:            wrong_count = 0            for i in range(len(X_train)):                X = X_train[i]                y = y_train[i]                # 如果存在誤分類點(diǎn)                # 更新參數(shù)                # 直到?jīng)]有誤分類點(diǎn)                if y * self.sign(X, w, b) <= 0:                    w = w + learning_rate*np.dot(y, X)                    b = b + learning_rate*y                    wrong_count += 1            if wrong_count == 0:                is_wrong = True                print('There is no missclassification!')
# 保存更新后的參數(shù) params = { 'w': w, 'b': b } return params

     以上便是本節(jié)內(nèi)容。完整代碼文件和數(shù)據(jù)可參考我的GitHub地址:

https://github.com/luwill/machine-learning-code-writing

參考資料:

李航 統(tǒng)計(jì)學(xué)習(xí)方法

https://github.com/fengdu78/lihang-code

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多