Press "Enter" to skip to content

20210613 感知机的代码实现

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

感知机

 

感知机可以看做一个仿生算法, 生物学的思想不止一次的***到机器学习里,感知机是最简单的一种。神经元通过树突“收集信息” , 通过“轴突”放电进行决策行为。用生活里的比喻看,感知机就是一个最简单的自动分类机,你可以用它来预测货架上的的东西是香蕉还是苹果,或者你面前的人是否值得交往;在数学上看,感知机就是一个特征平面(假设二维)里的分类直线。

 

从简单到抽样理解,一个计算图的流程

 

1 收集数据

 

2 通过不同的权重代表不同的偏好,得到加和输出

 

3 输出通过阈值函数变成分类决策

 

4 分类决策有对错,错误返回后,会修改权重

 

感知机算法采用的是梯度下降算法

1 代码的快速实现

 

# Reading-in the Iris data
import pandas as pd
import numpy as np
# 引用数据,将数据读取到 df 中,df 本身是一个 data frame
df = pd.read_csv('http://archive.ics.uci.edu/ml/'
    'machine-learning-databases/iris/iris.data',header=None)
# 这里只用了 4 个特征,鸢尾花花瓣的长度和宽度
# select setosa and versicolor
y = df.iloc[0:100, 4].values
y = np.where(y=='Iris-setosa',-1,1)
# extract sepal length and petal length
X = df.iloc[0:100, [0,2]].values
# y 是花的种类,X是特征

 

1-1 定义类型

 

from sklearn.linear_model import Perceptron
# 使用 sklearn 中的 Perceptron 进行快速训练,sklearn 是最常用的库,里面有各种各样的算法
# 各种各样算法的实现,只需要用一句话调用即可
ppn = Perceptron()
# 函数 fit 可以得到预测结果
ppn.fit(X,y)
# 现在可以得到一个预测结果

 

1-2 画出预测结果

 

import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
# 可视化模型预测结果
def plot_decision_regions(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[:, 1].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.3, 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=colors[idx],
                    marker=markers[idx], 
                    label=cl, 
                    edgecolor='black')
plot_decision_regions(X, y, classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()

感知机只能处理线性可分的问题

 

2 详细讲解感知机

 

手写一个算法,算法实现,首先定义一个感知机算法模型的类,然后用梯度下降法训练模型。

 

2-1 定义感知机模型

 

整个感知机的算法,无非是一个随机梯度下降的过程,随机梯度下降体现在双循环中

 

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.
    random_state : int
      Random number generator seed for random weight
      initialization.
    Attributes
    -----------
    w_ : 1d-array
      Weights after fitting.
    errors_ : list
      Number of misclassifications (updates) in each epoch.
    """
    def __init__(self, eta=0.01, n_iter=50, random_state=1):
        self.eta = eta
        self.n_iter = n_iter
        self.random_state = random_state
    def fit(self, X, y):
        """Fit training data.
        Parameters
        ----------
        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.
        y : array-like, shape = [n_samples]
          Target values.
        Returns
        -------
        self : object
        """
        rgen = np.random.RandomState(self.random_state)
        self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
        self.errors_ = []
        # 第一层循环是迭代次数,第二层是随机梯度下降
        for _ in range(self.n_iter):
            errors = 0
            for xi, target in zip(X, y):
                # update 代表如何去改变参数
                update = self.eta * (target - self.predict(xi))
                # 下面的两项对应公式中,w1 和 w0(就是截距 b) 如何 改变自己得到一个更加正确的参数
                self.w_[1:] += update * xi
                self.w_[0] += update
                errors += int(update != 0.0)
            self.errors_.append(errors) 
        return self
    # 函数 fit 是一个训练的过程,构建机器学习算法还 需要预测,也就是 wx+b 然后和阈值进行对比,得到一个数值
    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"""
        # 和阈值做比较,得到一个 1 或者 -1 的结果
        return np.where(self.net_input(X) >= 0.0, 1, -1)

 

v1 = np.array([1, 2, 3])
v2 = 0.5 * v1
np.arccos(v1.dot(v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))

 

2-2 训练一个感知机模型

 

# Reading-in the Iris data
import pandas as pd
df = pd.read_csv('https://archive.ics.uci.edu/ml/'
        'machine-learning-databases/iris/iris.data', header=None)
print(df.head())

 

 

df = pd.read_csv('iris.data', header=None)
print(df.tail())

 

2-3 Plotting the Iris data

 

import matplotlib.pyplot as plt
import numpy as np
# select setosa and versicolor
y = df.iloc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)
# extract sepal length and petal length
X = df.iloc[0:100, [0, 2]].values
# plot data
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('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()

 

2-4 训练 perceptron

 

ppn = Perceptron(eta=0.1, n_iter=10)
ppn.fit(X, y)
plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Number of updates')
plt.show()

 

 

错误随着时间的变化越来越少

 

2-5 A function for plotting decision regions

 

from matplotlib.colors import ListedColormap
def plot_decision_regions(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[:, 1].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.3, 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=colors[idx],
                    marker=markers[idx], 
                    label=cl, 
                    edgecolor='black')
plot_decision_regions(X, y, classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()

 

Be First to Comment

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注