感知机代码实现
首先先直接给出一个复制粘贴就可以运行的代码实例,让大家先感受一下感知机的代码的执行过程。数据集采用的是经典的鸢尾花数据集,sklearn.datasets
中提供了鸢尾花数据集的接口可以直接使用,当然还有其他更多的数据集可以用来进行实验,比如非常有名的用于机器学习的数据库UCI,其中也包含了鸢尾花数据集,里面包含的大部分数据集的规模都很小,很适合初学者使用。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
# 读取iris数据集,并将数据,标签存入DataFrame中,
iris = load_iris()
raw_data = iris.data
data = pd.DataFrame(raw_data, columns=iris.feature_names)
data['label'] = iris.target
"""
根据鸢尾花数据集的前两个特征来对数据点做分类
"""
data_array = np.array(data.iloc[:100, [0, 1, -1]])
X, Y = data_array[:, :-1], data_array[:, -1]
Y = np.array([1 if i == 1 else -1 for i in Y]) # 将标签为0,1,变为-1,+1
"""
绘制不同类别的数据点
"""
plt.scatter(X[:50, 0], X[:50, 1], label='0')
plt.scatter(X[50:100, 0], X[50:100, 1], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
plt.show()
"""
训练过程
"""
# 定义sign函数
def sign(X, W, b):
return np.dot(W, X) + b
# 遍历数据集,采用随机梯度下降算法进行优化,即每次只用一个样本进行梯度下降
def train(X, Y, W, b, learning_rate=0.1):
for i in range(len(X)):
if Y[i] * sign(X[i], W, b) <= 0:
# 进行梯度更新
W = W + learning_rate * Y[i] * X[i]
b = b + learning_rate * Y[i]
return W, b
# 将数据集遍历1000遍,每100次打印一下W, b值
W = np.zeros([1, 2])
b = 0
for i in range(10000):
W, b = train(X, Y, W, b)
if i % 100 == 0:
print(i, W, b)
"""
对结果进行打印
"""
x_ = np.linspace(4, 7, 10)
y_ = -(W[0][0]*x_ + b)/W[0][1]
plt.plot(x_, y_)
plt.scatter(X[:50, 0], X[:50, 1], label='0')
plt.scatter(X[50:100, 0], X[50:100, 1], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
plt.show()
代码运行结果如下,第一个图为数据分布情况,第二个为对感知机模型进行训练后确定的分离超平面。