[Python-程式碼實現]統計學習方法之感知機模型
阿新 • • 發佈:2018-12-03
內容簡介
- 感知機模型 - 手寫 Coding
- 使用手寫模型進行鳶尾花分類
- 使用 sklearn 中的感知機進行鳶尾花分類
感知機模型 - 手寫 Coding
class Model:
"""感知機模型"""
def __init__(self, data):
"""選取初值 w, b, η"""
self.w = np.zeros(len(data[0]) - 1, dtype=np.float32) # 引數 w 應與 x 等量
self.b = 0
self.η = 0.1
def sign(self, x):
"""感知機模型"""
y = np.dot(self.w, x) + self.b
return 1 if y >= 0 else -1
def fit(self, x_train, y_train):
"""模型訓練"""
while True:
for d, x in enumerate(x_train): # 取出一條資料
y = y_train[d] # 取出對應資料的 target
if y * self.sign(x) <= 0: # 分類不正確進行引數更迭
self.w = self.w + np.dot(self.η * y, x)
self.b = self.b + self.η * y
break # 發生更迭即存在分類錯誤,從頭再來
else: # 沒有發生更迭即全部分類正確,停止訓練
break
return self.w, self.b
使用手寫模型進行鳶尾花分類
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
def main():
# 一、載入資料
iris = load_iris()
# 二、提取輸入與輸出資料
# 為輸入特徵建立 Frame,並使用特徵名稱作為列標題(注意不是列索引)
df = pd.DataFrame(iris.data, columns=iris.feature_names)
# 新增輸出列 target
df['target'] = iris.target
# 給 Frame 新增列索引(只有加了索引才可以使用索引)
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'target']
# 列印輸出值分佈情況
print(df.target.value_counts())
# 三、繪出資料並觀察分佈情況
# 通過 frame 能夠看出資料是 50 間隔分佈,因此可以以 50 間隔分別取出
plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
plt.show()
# 四、特徵提取與目標值提取
# 使用 iloc 選取前 100 條資料的第 0, 1, -1 列,並轉換為 array
data = np.array(df.iloc[:100, [0, 1, -1]])
# 將 第 0, 1 列資料賦值給 x,將 第 -1 列資料賦值給 y
x_train, y_train = data[:, :-1], data[:, -1]
# 將 y 值進行 1, -1分類
y_train = np.array([i if i == 1 else -1 for i in y_train])
# 五、感知機模型訓練
perceptron = Model(data)
w, b = perceptron.fit(x_train, y_train)
# 六、繪出判定邊界
# 分離超平面為 w[0]x_1 + w[1]x_2 + b = 0
x_1 = np.linspace(4, 7, 10)
x_2 = -(w[0] * x_1 + b) / w[1]
plt.plot(x_1, x_2)
plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
plt.show()
if __name__ == '__main__':
main()
使用 sklearn 中的感知機進行鳶尾花分類
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
from sklearn.linear_model import Perceptron
import matplotlib.pyplot as plt
def main():
# 一、載入資料
iris = load_iris()
# 二、提取輸入與輸出資料
# 為輸入特徵建立 Frame,並使用特徵名稱作為列標題(注意不是列索引)
df = pd.DataFrame(iris.data, columns=iris.feature_names)
# 新增輸出列 target
df['target'] = iris.target
# 給 Frame 新增列索引(只有加了索引才可以使用索引)
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'target']
# 三、特徵提取與目標值提取
# 使用 iloc 選取前 100 條資料的第 0, 1, -1 列,並轉換為 array
data = np.array(df.iloc[:100, [0, 1, -1]])
# 將 第 0, 1 列資料賦值給 x,將 第 -1 列資料賦值給 y
x_train, y_train = data[:, :-1], data[:, -1]
# 將 y 值進行 1, -1分類
y_train = np.array([i if i == 1 else -1 for i in y_train])
# 四、使用SKlearn感知機進行模型訓練
clf = Perceptron()
clf.fit(x_train, y_train)
w = clf.coef_[0] # w
b = clf.intercept_ # b
# 五、繪出判定邊界
# 分離超平面為 w[0]x_1 + w[1]x_2 + b = 0
x_1 = np.linspace(4, 7, 10)
x_2 = -(w[0] * x_1 + b) / w[1]
plt.plot(x_1, x_2)
plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
plt.show()
if __name__ == '__main__':
main()
希望對你有所幫助,點個贊哇大兄dei!
個人部落格:http://xingtu.info
GitHub:https://github.com/BreezeDawn/MachineLearning