感知器(Perceptron)数据分类算法


  • 基本原理
  • 步调函数与阈值
  • 权重更新算法
  • 阈值的更新
  • 感知器算法使用范围
  • 机器学习-简单实现神经网络感知器分类算法部分代码
  • 参考与引用
一、基本原理

权重向量W,训练样本X

1. 把权重向量初始化为0,或把每个分量初始化为[0, 1]间任意小数
2. 把训练样本输入感知器,得到分类结果(-1或1)
3. 根据分类结果更新权重向量

二、步调函数与阈值

w0 = -θ(w0为阈值) and x0 = 1
z = w0x0+w1x1+...+wmxm=wTx and Φ(z) = 1 , if z ≥ θ; -1, otherwise;

三、权重更新算法

感知器(Perceptron)数据分类算法_第1张图片
权重更新算法.png

其中x(j)是传入的对应样本,学习率需要人为调整


感知器(Perceptron)数据分类算法_第2张图片
权重更新算法演示.png

w(0)为w第一个分量

四、阈值的更新

感知器(Perceptron)数据分类算法_第3张图片
阈值的更新.png
五、感知器算法使用范围

  • Linearly separable
六、机器学习-简单实现神经网络感知器分类算法部分代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as pt
from matplotlib.colors import ListedColormap


class Perceptron(object):
    """
    eta:学习率
    n_iter:权重向量的训练次数
    w_:神经分叉权重向量
    errors:用于记录神经元判断出错次数
    """

    def __init__(self, eta=0.01, n_iter=10):
        self.eta = eta
        self.n_iter = n_iter
        pass

    def fit(self, X, y):
        """
        输入训练数据,培训神经元,x输入样本向量,y对应样本分类

        X:shape[n_samples, n_features]
        X:[[1, 2, 3], [4, 5, 6]]
        n_samples:2
        n_features:3

        y:[1, -1]
        """

        """
        初始化权重向量为0
        +1是因为前面算法提到的w0,也就是步调函数的阈值
        """
        self.w_ = np.zeros(X.shape[1] + 1)
        self.errors_ = []

        """
        同一数据训练n_iter次得到训练好了的感知器
        """
        for _ in range(self.n_iter):
            errors = 0
            """
            X:[[1, 2, 3], [4, 5, 6]]
            y:[1, -1]
            zip(X, y) = [([1, 2, 3], 1), ([4, 5, 6], -1)]
            """
            for xi, target in zip(X, y):
                """
                xi、target分别对对应的X行及y行
                """
                # print(xi)
                # print(target)
                """
                update = η * (y - y')
                """
                update = self.eta * (target - self.predict(xi))

                """
                xi 是一个向量
                update * xi 等价
                ▽W(1) = X[1]*update, ▽W(2) = X[2]*update, ▽W(3) = X[3]*update
                    
                w_[1:]从第一个开始忽略了第0个(阈值)到最后一个
                """
                self.w_[1:] += update * xi
                self.w_[0] += update    # 阈值的更新

                errors += int(update != 0.0)    # 统计错误次数
                self.errors_.append(errors)
                pass
            pass
        pass

    def net_input(self, X):
        """
        z = W0*1 + W1*X1 + ...+ Wn*Xn
        """
        return np.dot(X, self.w_[1:]) + self.w_[0]
        pass

    def predict(self, X):
        return np.where(self.net_input(X) >= 0.0, 1, -1)
        pass

    pass


file = 'test.csv'

df = pd.read_csv(file, header=None)

df.head(10)

# df.to_csv('test.csv', index=False, header=None)

"""
将第4列单独抽取出来赋给y
"""
y = df.loc[0:99, 4].values

"""
y == 'Iris-setosa'时改为1,否则改为-1
"""
y = np.where(y == 'Iris-setosa', -1, 1)

"""
抽取0到100行第0列和第2列数据赋给X
"""
X = df.iloc[0:100, [0, 2]].values

pt.scatter(X[:50, 0], X[:50, 1], color='red', marker='o', label='setosa')
pt.scatter(X[50:100, 0], X[50:100, 1], color='blue', marker='x', label='versicolor')
pt.xlabel('Petal-length')
pt.ylabel('FlowerDiameter-length')
pt.legend(loc='upper left')  # 将label放在左上角
# pt.show()
# print(X)

ppn = Perceptron(eta=0.1, n_iter=10)  # 创建一个学习率为0.1,权重向量训练次数为10的感知器
print('Here are X:')
print(X)
print(y)
ppn.fit(X, y)  # 将X, y传入感知器进行训练
pt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')    # ???
pt.xlabel('Epochs')     # Epoch训练次数
pt.ylabel('Fail ClasifierNumber')
pt.show()


def plot_decision_regions(X, y, classifier, resolution=0.02):
    marker = ('s', 'x', 'o', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    """
    根据向量y中不同不同元素的种类分配不同的颜色
    y 由01构成,有两种不同的元素,len(np.unique(y))为2
    """
    cmap = ListedColormap(colors[:len(np.unique(y))])

    """
    获取两列数据中的最小值、最大值
    """
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max()
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max()

    print(x1_min, x1_max)
    print(x2_min, x2_max)

    """
    meshgrid()通过x1_min, x1_max, resolution的值来
    构造一个向量,然后再将该向量扩展成一个二维矩阵
    """
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))

    """
    np.arange()从x1_min开始到x1_max(不包含)结束,等差resolution生成单维向量
    """
    # print(np.arange(x1_min, x1_max, resolution).shape)
    # print(np.arange(x2_min, x2_max, resolution))
    """
    第一个向量参数向下扩展第二个向量参数行,第二个向量参数向右扩展第一个向量参数列
    """
    # print(xx1.shape)
    # print(xx1)
    # print(xx2.shape)
    # print(xx2)

    """
    ravel()函数将扩张后的二维向量还原回扩张前的单位向量
    """
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    print(xx1.ravel())
    print(xx2.ravel())
    """
    xx1.ravel()、xx2.ravel()对应列数据组合得到Z中对应列结果
    """
    print(Z)

    Z = Z.reshape(xx1.shape)
    # print('xx1.shape:')
    # print(xx1.shape)
    # print('Z.shape:')
    # print(Z.shape)
    # print(Z)
    """
    countourf()根据给的数据绘制数据间的分界线
    """
    pt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)  # alpha为透明度
    """
    x、y坐标轴起始和结束点分别对应xx1、xx2最小最大值
    """
    pt.xlim(xx1.min(), xx1.max())
    pt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):  # 绘制区域打上标签说明
        pt.scatter(x=X[y == cl, 0], y=X[y == cl, 1], alpha=0.8, c=cmap(idx),
                   marker=marker[idx], label=cl)


"""
plot_decision_regions()传入训练好的感知器并模拟数据进行分类
"""
plot_decision_regions(X, y, ppn, resolution=0.02)
pt.xlabel('Petal Length')
pt.ylabel('Flower Diameter Length')
pt.legend(loc='upper left')
pt.show()

七、参考与引用

慕课网

你可能感兴趣的:(感知器(Perceptron)数据分类算法)