Python實現感知機算法——李航《統計學習方法》

接下來一學期選了門《機器學習》的課程,所以打算把相關的作業也發上來!
一:
請說明感知機爲何不能解決異或問題。
答:我們知道感知機屬於線性模型,由於其無法找到一個線性模型對異或問題進行劃分,所以其不能解決異或問題。具體解釋如下:
首先我們知道感知機的數學表達式就是:
f(x)=sign(wx+b)
其中sign是符號函數,w和b都是感知機參數,x表示實例的特徵向量,而y=f(x)就是實例的類別。以二維特徵向量爲例:
輸入空間也就特徵向量空間是 ,輸出空間也是 ,輸入 表示實例的特徵向量,對於輸入空間的點,輸出 表示實例的類別。
由此知感知機爲線性模型;
而對於異或問題,以二維爲例:
輸入 輸出
Xi1 Xi2 Yi
0 0 0
1 0 1
0 1 1
1 1 0
利用Python繪製散點圖如下
在這裏插入圖片描述
由上述知,異或問題輸出可以分爲兩類,顯示在二維座標系中如上圖所示:其中輸出結果爲1對應圖中”o”,輸出爲0對應圖中”x”,我們可以很容易發現對於這種情況無法找到一條直線將兩類結果分開。所以感知機無法找到一個線性模型對異或問題進行劃分。
實際上不單單是感知機無法處理異或問題,所有的線性模型都無法處理線性模型。
二、編程題:
請使用python構建一個感知機,對上述數據進行分類,並誠實滴給出分類準確率。
把分界面的表達式寫於下方,並將其可視化出來粘貼到下方。
對於感知機Python代碼,其內容如下,其主要步驟就是:
① 構建訓練數據,形成適合訓練的數據向量與標籤向量
② 載入數據利用感知機數據進行計算得出感知機參數以獲取感知機模型
③ 將測試數據代入上述獲取的感知機模型觀察錯誤率結果(此處即將訓練數據全部代入進行測試,獲取的錯誤率爲0)如下圖所示,且感知機模型爲
f(x)=sign(-2.350232x1+(-1.779757x2)+(1.000000))
注:由於選用的爲高斯隨機數據,故每次運行後參數有所不一樣,但都能完全分類正確。。
④ 繪製相關圖形界面
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
python代碼如下:

import numpy as np
import matplotlib.pyplot as plt
num=100

# 類別 1 
class_1=np.random.normal(loc=2.3,scale=0.7,size=(num,2))
label_1=-1*np.ones((num,1))
classlabel_1=np.concatenate((class_1,label_1),axis=1)
#print(classlabel_1)
# 類別 2 
class_2=np.random.normal(loc=-0.9,scale=0.5,size=(num,2))
label_2=np.ones((num,1))
classlabel_2=np.concatenate((class_2,label_2),axis=1)

plt.figure()
plt.plot(class_1[:,0],class_1[:,1],"*")
plt.plot(class_2[:,0],class_2[:,1],"*")
#print(classlabel_2)
# 請根據課本構建數據標籤 高斯分佈 loc爲均值 scale爲標準差


#數據準備
classlabel=np.concatenate((classlabel_1,classlabel_2),axis=0)#拼接成一個整體
X1=classlabel[:,0]
X2=classlabel[:,1]
n=classlabel.shape[1]#訓練數據特徵數爲n-1
Y=classlabel[:,2]    #構建標籤數組
X=classlabel[:,0:n-1]#構建訓練數據數組

#感知機分類學習
def precep_classify(data_mat, label_mat, eta=1):
    #eta爲學習速率取1,omega爲權重因子
    omega = np.mat(np.zeros(n-1))#omega爲權重因子初值爲0
    m = np.shape(data_mat)[0]    #獲取總樣本數
    b = 0                        #b爲偏置初值爲0
    error_data = True
    while error_data:
        error_data = False
        for i in range(m):
            judge = label_mat[i] * (np.dot(omega, data_mat[i].T)+b)
            if judge <= 0:       #判斷y(wx+b)
                error_data = True
                omega = omega + np.dot(label_mat[i], data_mat[i])
                b=b+label_mat[i] #隨機梯度下降法更新參數
    w_b=np.array([omega,b])
    return w_b                   #傳回感知機參數

#可視化處理
def plot(data_mat, label_mat, omega, b):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    X = data_mat[:, 0]
    Y = data_mat[:, 1]

    for i in range(len(label_mat)):
        if label_mat[i] > 0:
            ax.scatter(X[i].tolist(), Y[i].tolist(), color='red')
        else:
            ax.scatter(X[i].tolist(), Y[i].tolist(), color='green')
    o1 = omega[0, 0]
    o2 = omega[0, 1]
    x = np.linspace(-1, 3, 50)
    y = (-o1 * x - b) / o2
    ax.plot(x, y)
    plt.show()
#測試
def precep_test(test_data_mat, test_label_mat, omega, b):
    m = np.shape(test_data_mat)[0]
    error = 0.0
    for i in range(m):
        classify_num = np.dot(test_data_mat[i], omega.T)+b
        if classify_num > 0:
            class_ = 1
        else:
            class_ = -1
        if class_ != test_label_mat[i]:
            error += 1
    print ('錯誤率爲 %f' %(error/m))
    

#主程序
for i in range(0,10):#多循環訓練幾次以提高抗噪容限
    w_b=precep_classify(X, Y)   #載入訓練數據進行感知機分類獲取參數

w=w_b[0]
b=w_b[1]
print("感知機模型爲f(x)=sign(%f*x1+(%f*x2)+(%f))"%(w[0,0],w[0,1],b))
precep_test(X, Y, w, b)     #進行測試
plot(X, Y, w, b)            #可視化展示

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章