python机器学习——感知器

最近在看机器学习相关的书籍,顺便把每天阅读的部分写出来和大家分享,共同学习探讨一起进步!作为机器学习的第一篇博客,我准备从感知器开始,之后会慢慢更新其他内容。

在实现感知器算法前,我们需要先了解一下神经元(neuron)的工作原理,神经元有很多树突和一个轴突,树突(Dendrites)可以从其他神经元接收信息并将其带到细胞体(Cell nucleus),轴突(Axon)可以从细胞体发送信息到其他神经元。树突传递过来的信息在细胞体中进行计算处理后,如果结果超过某个阈值,轴突会传递信号到其他的神经元。人们通过认识神经元的工作过程,创造出了感知器学习算法。

感知器是Frank Rosenblatt在1975年就职于康奈尔实验室时所发明的一种人工神经网络,它被视为一种最简单形式的前馈神经网络,是一种二元线性分类器,不足在于不能处理线性不可分问题。

下图为三种不同情况,左图中的两类可以使用一条直线(即线性函数)分开,即线性可分;中间和右边由于不能使用线性函数分开,则为线性不可分。

我们直接来看一个实例,假设我们现在需要对花进行分类,数据集中有两种花朵,分别将其记为1和-1,我们需要根据数据集含有的花的一些特征来进行分类,这里仅使用两种花的特征,即萼片长度和花瓣长度,将这两个特征用向量表示为:
\[
x = \begin{bmatrix}x_1\\x_2\end{bmatrix}
\]
x也叫做输入向量,我们再定义一个相应的权重向量w:
\[
w = \begin{bmatrix}w_1\\w_2\end{bmatrix}
\]
将x和w线性组合后得到z:
\[
z = w_1x_1+w_2x_2
\]
我们假设,如果样本的激活值z大于等于事先设置好的阈值b,我们就说此样本属于类别1,否则属于类别-1,公式表示如下:
\[
\phi(z) = \begin{cases}1,\quad z\ge b \\\\-1,\quad otherwise\end{cases}
\]
可以看出这个想法和神经元的工作原理很相似。为了方便,我们将阈值b移到等式的左边并额外定义一个权重参数来代替-b,更新z为以下等式:
\[
z = w_0x_0+w_1x_1+w_2x_2
\]
那么上式中的z大于等于0的情况也就等价于之前当z大于等于阈值b的情况,可以得到:
\[
\phi(z) = \begin{cases}1,\quad z\ge0 \\\\-1,\quad otherwise\end{cases}
\]
上面的函数也叫做激活函数,我们通过激活函数将z压缩到了一个二元输出(1,-1),也就是:

我们可以看出权重向量w决定着分类是否准确,那么我们如何选择合适的权重向量w呢?我们不能一个一个给w赋值,这样工作量太大且没有效率,其实感知器可以通过数据集中的样本自动调整w,随着训练的进行,w的变化趋于平稳,分类的准确率也会大大提高。

我们更新权重向量w的公式为:
\[
w_j = w_j + \Delta w_j
\]

\[
\Delta w_j = \eta(y^i-\hat{y^i})x^i_j
\]

\[
\eta-学习率\\w_j-w向量的第j个特征\\y^i-第i个样本的真实类别\\\hat{y^i}-第i个样本的预测类别\\x_j^i-第i个样本的第j个特征
\]

其中学习率介于0.0和1.0之间,用于控制w更新的程度,权重向量w中的每一个参数都是同步更新的,即只有在w的每个参数的更新大小都计算出来后才会改变w的值,我们使用数据集中的大量训练样本x来更新w,来逐渐提高分类准确率。

感知器算法只有类别线性可分且学习率较小的情况下才能保证收敛,感知器接收训练样本x,将x与w线性结合得到z,再将z传递给激活函数,产生一个分类结果作为对样本x的预测类别,之后按照更新规则来更新w,等收敛后感知器也就训练完成了。

接下来我们开始实现感知器算法并使用Iris数据集训练:

import pandas as pd

读取数据集

df = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None)
df.tail()

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
}

.dataframe thead th {
text-align: right;
}

0 1 2 3 4
145 6.7 3.0 5.2 2.3 Iris-virginica
146 6.3 2.5 5.0 1.9 Iris-virginica
147 6.5 3.0 5.2 2.0 Iris-virginica
148 6.2 3.4 5.4 2.3 Iris-virginica
149 5.9 3.0 5.1 1.8 Iris-virginica

由上表可以看到每个输入向量x都包含4个特征(0、1、2、3)和1个正确的类别(4)

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

取出前100个训练样本的类别向量,若其类别输入‘Iris-setosa’,则将其设置为-1,否则设置为1

y = df.iloc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)

取出前100个训练样本的前两个特征向量

X = df.iloc[0:100, [0, 2]].values

画出这100个训练样本的类别分布图

plt.scatter(X[:50, 0], X[:50, 1], color='red', marker='o', label='setosa')
plt.scatter(X[50:100, 0], X[50:100, 1], color='blue', marker='x', label='versicolor')
plt.xlabel('petal length')
plt.ylabel('sepal length')
plt.legend(loc='upper left')
plt.show()

实现感知器

import numpy as np

class Perceptron(object):
    """Perceptron classifier.

    Parameters
    ----------
    eta:float
        Learning rate(between 0.0 and 1.0
    n_iter:int
        Passes over the training dataset.

    Attributes
    ----------
    w_:1d-array
        weights after fitting.
    errors_:list
        Number of miscalssifications in every epoch.

    """

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

    def fit(self, X, y):
        """Fit training data.

        :param X:{array-like}, shape=[n_samples, n_features]
        Training vectors, where n_samples is the number of samples and
        n_features is the number of features.
        :param y: array-like, shape=[n_samples]
        Target values.
        :return:
        self:object

        """

        self.w_ = np.zeros(1 + X.shape[1]) # Add w_0
        self.errors_ = []

        for _ in range(self.n_iter):
            errors = 0
            for xi, target in zip(X, y):
                update = self.eta * (target - self.predict(xi))
                self.w_[1:] += update * xi
                self.w_[0] += update
                errors += int(update != 0.0)
            self.errors_.append(errors)
        return self

    def net_input(self, X):
        """Calculate net input"""
        return np.dot(X, self.w_[1:]) + self.w_[0]

    def predict(self, X):
        """Return class label after unit step"""
        return np.where(self.net_input(X) >= 0.0, 1, -1) #analoge ? :n in C++

ppn = Perceptron(eta = 0.1, n_iter = 10)
ppn.fit(X, y)
<__main__.Perceptron at 0x16680906978>

画出训练曲线

plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker = 'o')
plt.xlabel('Epoches')
plt.ylabel('Number of misclassifications')
plt.show()

画出分界线

from matplotlib.colors import ListedColormap
def plot_decision_region(X, y, classifier, resolution=0.02):
    # setup marker generator and color map
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    # plot the decision surface
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 0].max() + 1

    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                          np.arange(x2_min, x2_max, resolution))
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)

    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    #plot class samples
    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],
                   alpha=0.8, c=cmap(idx), marker = markers[idx],
                   label=cl)
plot_decision_region(X, y, classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()

参考:

https://www.toutiao.com/a6669391886744027662/
https://zh.wikipedia.org/wiki/%E6%84%9F%E7%9F%A5%E5%99%A8

原文地址:https://www.cnblogs.com/Dzha/p/11832453.html

时间: 2024-10-07 12:46:40

python机器学习——感知器的相关文章

机器学习--感知器数据分类算法步骤(慕课网-实现简单的神经网络)

权重向量W,训练样本X 1.把权重向量初始化为0,或把每个分量初始化为[0,1]之间的任意小数 2.把训练样本输入感知器,得到分类结果(-1或者1) 3.根据分类结果更新权重向量 感知器算法适用于图一的可线性分隔开的数据样本

机器学习——感知器算法实现

本次也是用processing3.0+写的,其官方网站https://processing.org/,建议直接看reference的例子进行学习. 感知器算法用的是我们老师给的ppt,实现的是二维的感知器,为了方便看,实际上多维的也是一样的: 运行效果是: 为了试验方便,我这是用了点击取点,键盘按一下t,大小写均可,下一个点的就是正例,按一下f,大小写均可,下一个点就是负例. 按s是开始进行学习度为1的迭代.结束会直接出直线,按2会出学习率为2的直线,迭代次数会打在程序底下,值是2. 代码仅供参

机器学习之感知器算法原理和Python实现

(1)感知器模型 感知器模型包含多个输入节点:X0-Xn,权重矩阵W0-Wn(其中X0和W0代表的偏置因子,一般X0=1,图中X0处应该是Xn)一个输出节点O,激活函数是sign函数. (2)感知器学习规则 输入训练样本X和初始权重向量W,将其进行向量的点乘,然后将点乘求和的结果作用于激活函数sign(),得到预测输出O,根据预测输出值和目标值之间的差距error,来调整初始化权重向量W.如此反复,直到W调整到合适的结果为止. (3)算法的原始形式 (4)Python代码实现 1 import

Coursera机器学习基石 第2讲:感知器

第一讲中我们学习了一个机器学习系统的完整框架,包含以下3部分:训练集.假设集.学习算法 一个机器学习系统的工作原理是:学习算法根据训练集,从假设集合H中选择一个最好的假设g,使得g与目标函数f尽可能低接近.H称为假设空间,是由一个学习模型的参数决定的假设构成的一个空间.而我们这周就要学习一个特定的H——感知器模型. 感知器模型在神经网络发展历史中占有特殊地位,并且是第一个具有完整算法描述的神经网络学习算法(称为感知器学习算法:PLA).这个算法是由一位心理学家Rosenblatt在1958年提出

感知器算法--python实现

写在前面: 参考: 1  <统计学习方法>第二章感知机[感知机的概念.误分类的判断]   http://pan.baidu.com/s/1hrTscza 2   点到面的距离 3   梯度下降 4   NumPy-快速处理数据    属性shape:表示几行几列:   dot(a,b) 计算数组.矩阵的乘积 感知器算法: Python实现: #coding:utf-8 import numpy as np class Perceptron(object): def __init__(self)

感知器代码实现--机器学习随笔2

这里主要是贴出我个人实现的代码做出以下测试说明1 分类并不能百分百正确,可能存在一些点无法正确分类的情况2 由于没有引入代价函数,也没有使用梯度算法,这个学习率并不是非常准确,分离超平面可能不正确.同样的参数下,可以多运行几次,会出现正确的结果的.3 希望感兴趣的朋友可以去实验以下,调整双月间距,多做几次实验. 这个算法主要验证了感知器算法是可以收敛的,并不保证能百分百分类正确!原因在前文也说明了. 希望大家能和我一起思考:如果改变数据的迭代方式(训练数据集)会对分类效果造成什么影响,为什么会有

机器学习 —— 基础整理(六):线性判别函数——感知器、松弛算法、Ho-Kashyap算法

本文简单整理了以下内容: (一)线性判别函数与广义线性判别函数 (二)感知器 (三)松弛算法 (四)Ho-Kashyap算法 (一)线性判别函数与广义线性判别函数 一.线性判别函数 这篇总结继续关注分类问题.假设判别函数(Discriminant function)的参数形式已知,用训练的方法直接根据样本估计判别函数的参数.线性判别函数的形式为: $$g(\textbf x)=\textbf w^{\top}\textbf x+w_0$$ $\textbf x\in \mathbb R^d$ 是

Stanford大学机器学习公开课(三):局部加权回归、最小二乘的概率解释、逻辑回归、感知器算法

(一)局部加权回归 通常情况下的线性拟合不能很好地预测所有的值,因为它容易导致欠拟合(under fitting).如下图的左图.而多项式拟合能拟合所有数据,但是在预测新样本的时候又会变得很糟糕,因为它导致数据的 过拟合(overfitting),不符合数据真实的模型.如下图的右图. 下面来讲一种非参数学习方法——局部加权回归(LWR).为什么局部加权回归叫做非参数学习方法呢?首先,参数学习方法是这样一种方法:在训练完成所有数据后得到一系列训练参数,然后根据训练参数来预测新样本的值,这时不再依赖

Python_sklearn机器学习库学习笔记(七)the perceptron(感知器)

一.感知器 感知器是Frank Rosenblatt在1957年就职于Cornell航空实验室时发明的,其灵感来自于对人脑的仿真,大脑是处理信息的神经元(neurons)细胞和链接神经元细胞进行信息传递的突触(synapses)构成. 一个神经元可以看做将一个或者多个输入处理成一个输出的计算单元.一个感知器函数类似于一个神经元:它接受一个或多个输入,处理 他们然后返回一个输出.神经元可以实时,错误驱动的学习,神经元可以通过一个训练样本不断的更新参数,而非一次使用整套的数据.实时学习可能有效的处理