什麼是感知機
感知機由Rosenblatt在1957年提出,是一種二類線性分類模型。輸入一個實數值的n維向量(特徵向量),經過線性組合,如果結果大於某個數,則輸出1,否則輸出-1.具體地:
其中的w0,w1,....wn權重,W向量稱爲權向量(本文中粗體代表向量)。權重決定每個輸入分類對最終輸出的貢獻率。爲了更簡潔地表示,我們加入一個x0=1,則可以將上面的式子寫成符號函數(輸入大於零的時候爲1,其他爲-1):
這就是感知機的數學表達,其中W*X爲內積,即向量對應元素相乘,然後求和。
感知機原理
e感知n機是二分類的線性模型,其輸入是實例的的特徵向量,輸出的是實例的類別,分別是+1和-1,屬於判別模型。假設訓練數據集是線性可分的,感知機學習的目標是求得一個能夠將訓練數據集正實例點和負實例點完全正確分開的分離超平面。如果是非線性的數據,則最後無法獲取超平面。
一個簡單的單層感知機如下圖所示
Python實現單層感知機
step1: 數據生成
在一條直線附近利用np.random.normal產生高斯白噪聲,然後生成分佈點。這裏使用y=k*x+b的形式。然後根據點的分佈,給點打上標籤是+1還是-1。
'''
利用高斯白噪聲生成基於某個直線附近的若干點
y = wb + b
weight 直線權值
bias 直線偏置
size 點的個數
'''
import numpy as np
def random_point_nearby_line(weight,bias,size=10):
x_point = np.linspace(-1,1,size)[:,np.newaxis]
noise = np.random.normal(0,0.5,x_point.shape)
y_point = weight * x_point + bias + noise
input_arr = np.hstack((x_point, y_point))
return input_arr
# 直線的真正參數
real_weight = 1
real_bias = 3
size = 100
# 輸入數據和標籤
# 生成輸入的數據
input_point = random_point_nearb_line(real_weight, real_bias, size)
# 給數據打標籤,在直線上方還是下方, above = 1, below = -1
label = np.sign(input_point[:,1] - (input_point[:,0] * real_weight + real_bias)).reshape((size,1))
step2: 拆分訓練集測試集
from sklearn.model_selection import train_test_split
testSize = 15
x_train, x_test, y_train, y_test = train_test_split(input_point, label, test_size=testSize)
trainSize = size - testSize
step3: 繪製初始點與直線
import matplotlib.pyplot as plt
# 將輸入點繪圖
fig = plt.figure() # 生成一個圖片框
ax = fig.add_subplot(111) # 編號
for i in range(y_train.size):
if y_train[i] == 1:
ax.scatter(x_train[i,0], x_train[i,1], color='r') # 輸入真實值,紅色在線上方
else:
ax.scatter(x_train[i,0], x_train[i,1], color='b') #輸入真實值, 藍色在線下方
plt.show()
step4: 隨機梯度下降法進行訓練
#初始化w,b
Weight = np.random.rand(2,1) #隨機生成-1到1的一個數據
Bias = 0 #初始化爲0
def trainBySGD(input, output, x_test, y_test, test_size,input_num,train_num = 10000, learning_rate=1):
global Weight, Bias
x = input
y = output
for rounds in range(train_num):
for i in range(input_num):
x1, x2 = x[i]
prediction = np.sign(Weight[0] * x1 + Weight[1] * x2 + Bias)
#print('prediaction', prediction)
if y[i] * prediction <= 0: # 判斷誤分類點
# Weight = Weight + np.reshape(learning_rate*y[i]*x[i],(2,1))
Weight[0] = Weight[0] + learning_rate * y[i] * x1
Weight[1] = Weight[1] + learning_rate * y[i] * x2
if rounds % 10 == 0:
learning_rate *= 0.9
accuracy = compute_accuracy(x_test, y_test, test_size, Weight, Bias)
print('rounds {}, accuracy {}'.format(rounds,accuracy))
def compute_accuracy(x_test, y_test, test_size, weight, bias):
x1, x2 = np.reshape(x_test[:,0], (test_size,1)), np.reshape(x_test[:,1],(test_size,1))
prediction = np.sign(y_test * (x1 * weight[0] + x2 * weight[1] + bias))
count = 0
#print('prediaction', prediction)
for i in range(prediction.size):
if prediction[i] > 0:
count = count + 1
return (count+0.0) / test_size
trainBySGD(x_train, y_train, x_test, y_test, testSize, 85, train_num = 100, learning_rate = 1)
參考鏈接:
https://blog.csdn.net/bingduanlbd/article/details/24468885
https://www.bilibili.com/video/BV1JE411Y7gB?from=search&seid=10392081171445846990