【统计学习】感知机模型

感知机模型

假设输入空间是\(\chi \subseteq R^n\),输出空间是\(Y=\{+1, -1\}\)。输入\(x \subset \chi\)表示实例的特征向量,输出\(y \subset Y\)表示实例的类别。由输入空间到输出空间的如下函数:

\[f(x) = sign(w \cdot x +b) \]

其中w和b是感知机模型参数,w是权值向量,b是偏置,\(w \cdot x\)表示w和x的内积,sign是符号函数。

\[\operatorname{sign}(x)=\left\{\begin{array}{ll}{+1,} & {x \geqslant 0} \\ {-1,} & {x<0}\end{array}\right. \]

感知机学习策略

感知机的前提:假设训练数据集是线性可分的。
感知机学习的目的:求得一个能将训练集正实点和负实点完全分开的分离超平面。
损失函数选择:自然选择误分点总数,但是这样的损失函数对于参数w、b不是连续可导,不易优化。感知机选择误分点到超平面S的总距离。

\[\frac {1}{||w||}|w \cdot x_0 + b| \]

对于误分点\((x_i, y_i)\)来说,满足以下条件:

\[-y_i(w \cdot x_i + b) > 0 \]

对于正类误分:\(\left\{\begin{array}{ll}{y_i > 0} \\ {w \cdot x_i + b < 0}\end{array}\right.\),负类分类:\(\left\{\begin{array}{11}{y_i < 0}\\{w \cdot x_i +b >0}\end{array}\right.\)
不考虑\(\frac{1}{||w||}\),感知机的损失函数为:\(\operatorname{L}(w,b)=-\sum_{x_{i=1}}^M y_i (wx_i + b)\),如果没有误分类,损失函数值是0,误分类越少,误分点离超平面越近,损失函数值越小。

感知机学习算法

损失函数极小化问题:\(min(L(w,b)) = - \sum_{x_i = 1}^M y_i(w \cdot x_i +b)\)
感知机算法是误分类驱动的,采用随机梯度下降算法:首先任意选取一个超平面\(w_0, b_0\),然后用梯度下降法不断极小化目标函数。

原始算法

输入:训练数据集\(T={(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}\),其中\(x_i \in \chi = R^n\)\(y_i \in Y = {-1, + 1}\)\(i = 1,2,...N\);学习率\(\eta(0 < \eta \leq 1)\)
输出\(w,b\);感知机模型\(f(x) = sign(w \cdot x +b)\)

  1. 选取初始值\(w_0,b_0\)
  2. 在训练集中选取数据\((x_i,y_i)\)
  3. 如果\(y_i(w \cdot x_i +b) \leq 0\)

\[w \leftarrow w + \eta y_i x_i \]

\[b \leftarrow b + \eta y_i \]

  1. 转至(2),直到训练集中没有误分类点。
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
%matplotlib inline
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['lable'] = iris.target
df.columns = [
    'sepal length', 'sepal width', 'petal length', 'petal width', 'label'
]

可视化代码如下

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()
class PerceptronModel:
    def __init__(self, learning_rate=0.05):
        self._w =np.ones(features.shape[1], dtype=np.float32)
        self._bias = 0
        self._l_rate = learning_rate
    def sign(self,w, b, x):                         
        return np.dot(x, w) + b
    def fit(self, X_train, Y_train):
        running = True
        while running == True:
            err_count = 0                        
            for idx in range(len(X_train)):
                x = X_train[idx]
                y = Y_train[idx]                
                if  y *self.sign(self._w,self._bias, x) <=0:
                    self._w = self._w + self._l_rate * np.dot(y, x)
                    self._bias = self._bias + self._l_rate * y
                    err_count += 1
            if err_count == 0:
                running = False
        print("=============", self._w, self._bias)              
#使用apply函数修改标记
df['target'] = df['label'].apply(lambda x: 1 if x == 0 else -1)
features = np.array(df.iloc[:100, [0,1]])
#非df.iloc[:100, [-1]],而是df.iloc[:100, -1]
labels = np.array(df.iloc[:100, -1])
perp = PerceptronModel()
perp.fit(features, labels)

============= [-3.915 5.01 ] 6.099999999999986

对偶算法

对偶形式的基本思想:将w和b表示为实例\(x_i\)\(y_i\)的线性组合形式,通过求解其系数而求得w和b。在原始算法中,可假设初始值\(w_0,b_0\)均为0,对误分点\((x_i,y_i)\)通过

\[w \leftarrow w + \eta y_i x_i \]

\[b \leftarrow b + \eta y_i \]

逐步修改w,b,假设修改n次,则w,b关于\((x_i,y_i)\)的增量分别是\(\alpha_iy_ix_i\)\(\alpha_iy_i\),这里\(\alpha_i = n_i \eta\),这样,最后学习到的w,b分别表示为:

\[w = \sum_{i=1}^N \alpha_i y_i x_i \]

\[b = \sum_{i=1}^N \alpha_i y_i \]

输入:线性可分的数据集\(T = {(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}\),其中\(x_i \in R^n\)\(y_i \in {-1,+1},i = 1,2,...,N\);学习率\(\eta(0 < \eta \leq 1)\)
输出\(\alpha,b\);感知机模型 \(f(x) = sign \left(\sum_{j=1}^N \left(\alpha_j y_j x_j \right) \cdot x +b \right)\),其中 \(\alpha = (\alpha_1,\alpha_2,...,\alpha_n)^T\)
(1) \(\alpha \leftarrow 0, b \leftarrow 0\);
(2) 在训练集中选取数据\((x_i, y_i)\)
(3) 如果 \(y_i \left(\sum_{j=1}^N \left(\alpha_j y_j x_j \right) \cdot x_i +b \right) \leq 0\)

\[\alpha_j \leftarrow \alpha_j + \eta \]

\[b \leftarrow b + \eta y_i \]

(4) 转至(2)直到没有误分类数据
对偶形式中训练实例仅一内积的形式出现,可以提前将训练数据集中实例间的内积计算出来并以矩阵形式存储,这个矩阵就是所谓的Gram矩阵

\[G = [x_i \cdot x_j]_{N \times N} \]

\[G = \begin{bmatrix}x_1\\ x_2\\ \cdots\\ x_n\end{bmatrix} \cdot \begin{bmatrix}x_1 & x_2 \cdots & x_n\end{bmatrix} \]

posted @ 2021-02-05 11:01  逆风飞扬pro  阅读(92)  评论(0)    收藏  举报