感知机入门:从理论到实践的完整指南
引言
在上一篇博客深入解析线性回归:算法原理、应用与Python实战案例中,我们学习了线性回归的基本原理,简单线性回归以及多元线性回归,同时使用python对两具体的案例进行实现。在本篇博客中,我们将详细探索机器学习中的一种基本模型——感知机。本文分为三个部分:首先是对感知机的详细介绍,接下来是一个具体的应用案例,最后我们将使用Python进行实现,并通过生成的超平面图像直观展示分类效果。
感知机模型简介
感知机是一种简单的线性二分类模型,其基本形式是一个二分类的线性分类器。由Frank Rosenblatt于1957年提出,感知机是神经网络,支持向量机以及逻辑回归分析的基础。感知机模型旨在找到一个能够将两类数据完全正确分开的分离超平面。其数学表达式为:
f ( x ) = sign ( w ⋅ x + b ) f(x)=\operatorname{sign}(\boldsymbol{w}\cdot\boldsymbol{x}+b) f(x)=sign(w⋅x+b)
其中, w \boldsymbol{w} w 表示权重向量, b b b 是偏差项, x \boldsymbol{x} x是输入的特征向量,sign 是符号函数,它会输出+1或-1,对应两个分类。感知机的学习过程基于损失函数,损失函数定义为所有误分类点到超平面的总距离。学习的目标是最小化这个损失函数。更新规则如下:
w
←
w
+
η
y
i
x
i
\boldsymbol{w}\leftarrow \boldsymbol{w}+\eta y_i\boldsymbol{x}_i
w←w+ηyixi
b
←
b
+
η
y
i
b\leftarrow b+\eta y_i
b←b+ηyi
其中, η ( 0 < η ≤ 1 ) \eta(0<\eta\leq1) η(0<η≤1)表示学习率,学习率太小容易导致迭代次数增多,学习率太大容易造成过拟合,因此需要选择合适的学习率, y i y_i yi表示实际分类标签, x i \boldsymbol{x}_i xi表示输入的特征向量,感知机通过迭代方式逐步调整 w \boldsymbol{w} w和 b b b,直到找到一个能够正确分类所有训练样本的超平面。
感知机案例:二维数据分类
我们可以生成一个包含50个数据点的数据集,这些点将均匀地分布在两个类别中。为了确保这些数据点具有一定的线性可分性,我们可以选择两个中心位置,然后在这两个中心位置周围生成一系列随机数。下面的Python代码将生成一个包含50个数据点的数据集。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
# 设置matplotlib的字体
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体为黑体
rcParams['axes.unicode_minus'] = False # 正确显示负号
np.random.seed(42) # 保证可重复性
# 生成50个随机点
X = np.random.rand(50, 2) * 10 # 生成0到10之间的随机数
y = np.where(X[:, 1] > X[:, 0], 1, -1) # 标签
# 可视化数据点,使用柔和的颜色
colors = ['#abdda4' if label == 1 else '#fdae61' for label in y]
plt.scatter(X[:, 0], X[:, 1], c=colors)
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title('随机数据集')
plt.show()
这个数据集是在一个二维空间中生成的,它使用 了numpy 的 random.randn 函数生成正态分布的随机数,然后通过加上一个常数数组来调整它们的中心位置。这样可以创建两组数据,一组围绕点 (5, 5) 集中,另一组围绕点 (2, 2) 集中。
Python实现感知机
使用Python,我们定义了一个感知机分类器并在生成的数据集上对它进行训练,最终绘制出决策边界来直观展示分类效果。
# 感知机分类器类定义
class Perceptron:
def __init__(self, learning_rate=0.01, n_iters=1000):
"""
初始化感知机分类器
:param learning_rate: 学习率,用于更新权重
:param n_iters: 迭代次数,即训练数据集的遍历次数
"""
self.lr = learning_rate # 设置学习率
self.n_iters = n_iters # 设置迭代次数
self.weights = None # 初始化权重
self.bias = None # 初始化偏置
def fit(self, X, y):
"""
训练感知机模型
:param X: 特征数据集,形状为 (n_samples, n_features)
:param y: 标签数据集,形状为 (n_samples,)
"""
n_samples, n_features = X.shape # 获取样本数和特征数
self.weights = np.zeros(n_features) # 初始化权重为0
self.bias = 0 # 初始化偏置为0
# 主训练循环
for _ in range(self.n_iters):
for idx, x_i in enumerate(X):
linear_output = np.dot(x_i, self.weights) + self.bias # 计算线性组合
y_predicted = np.sign(linear_output) # 应用符号函数得到预测结果
# 如果预测错误,更新权重和偏置
if y_predicted * y[idx] <= 0:
self.weights += self.lr * y[idx] * x_i
self.bias += self.lr * y[idx]
def predict(self, X):
"""
对新数据进行预测
:param X: 新数据,形状为 (n_samples, n_features)
"""
linear_output = np.dot(X, self.weights) + self.bias # 计算线性组合
return np.sign(linear_output) # 应用符号函数进行分类
# 训练模型
p = Perceptron()
p.fit(X, y)
# 绘制决策边界的函数
def plot_hyperplane(X, y, weights, bias):
"""
绘制数据点和决策边界
:param X: 数据点的特征
:param y: 数据点的标签
:param weights: 感知机的权重
:param bias: 感知机的偏置
"""
ax = plt.gca()
xlim = [X[:, 0].min() - 1, X[:, 0].max() + 1] # 设置x轴范围
ylim = [X[:, 1].min() - 1, X[:, 1].max() + 1] # 设置y轴范围
# 计算决策边界的x和y值
x_values = np.array(xlim)
y_values = -(bias + weights[0] * x_values) / weights[1]
plt.plot(x_values, y_values) # 绘制决策边界直线
plt.scatter(X[:, 0], X[:, 1], c=colors) # 绘制数据点
plt.xlim(xlim)
plt.ylim(ylim)
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Decision Boundary of the Perceptron')
plt.show()
plot_hyperplane(X, y, p.weights, p.bias)
运行程序可以得到如下结果:
结论
感知机作为机器学习领域中最简单的线性分类模型之一,虽然在处理非线性可分数据集时存在局限,但其在简单问题上的表现依然出色。通过这篇文章的学习,您不仅掌握了感知机的理论基础,还通过实践深入理解了其工作原理。接下来,我们将继续探讨支持向量机与逻辑回归分析,这些都是基于感知机进一步发展的算法。