使用python实现感知器学习算法

《python机器学习》中,使用python实现了感知器算法,源码如下:

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


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

    def fit(self, X, Y):
        # 若X为m行n列,则X.shape为(m,n),X.shape[1]为n
        self.w_ = np.zeros(1 + X.shape[1])   # 意思为将构造n+1个0元素的w_向量
        self.errors_ = []

        for i in range(self.n_iter):
            errors = 0
            # zip将X,Y的列表元素一一对应打包为元组形式并返回,元素个数与最短的列表保持一致
            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

    # 使用dot方法计算向量的点积,向量w的转置乘以向量x
    def net_input(self, X):
        return np.dot(X, self.w_[1:]) + self.w_[0]

    # where后面的判断条件为真,选择第一个;为假,选择第二个
    def predict(self, X):
        return np.where(self.net_input(X) >= 0.0, 1, -1)


def plot_decision_regions(X, y, classifier, resolution=0.02):
    # 确定需要的颜色
    makers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    # unique对于一维数组或者列表,unique函数去除其中重复的元素,并按元素由小到大返回一个新的无元素重复的元组或者列表
    cmap = ListedColormap(colors[:len(np.unique(y))])

    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    # np.meshgrid从坐标向量返回坐标矩阵, arange功能:生成一维数组,ravel:将多维数组转换为一维数组,T:矩阵转置
    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)  # 此处调用的是Myperceptron类的predict函数
    Z = Z.reshape(xx1.shape)   # xx1.shape是m行n列数组,其返回的是(m, n),则z.reshape就是将z更改为m行n列的新数组
    # contourf中xx1、xx2指的是
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)  # cmap
    # xlim:设置x、y轴刻度的取值范围
    plt.xlim(xx1.min(), xx1.max())
    plt.xlim(xx2.min(), xx2.max())
    # enumerate是python内置函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
    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=makers[idx], label=cl)


# 获取相应的数据集
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']
df = pd.read_csv(url, names=names)
# df.tail()  # tail加载最后5行数据

# pandas.DataFrame.iloc函数是基于索引来选取部分数据集,[0:100]即选取0-99行的数据,是前闭后开的集合
# 加上valus之后返回的是numpy.ndarray(多维数组),而不加values返回的是pandas.core.series.Series
y = df.iloc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)
X = df.iloc[0:100, [0, 2]].values
# scatter绘制离散点
plt.scatter(X[:50, 0], X[:50, 1], color='red', marker='o', label='setosa')
plt.scatter(X[50:, 0], X[50:, 1], color='blue', marker='x', label='versicolor')
plt.xlabel('petal length')
plt.ylabel('sepal length')
plt.legend(loc='upper left')   # 注释图标的位置
plt.show()

# 每次迭代错误分类数量的折线图,检验算法是否可以找到分开两类花型的决策边界
ppn = Myperceptron()
ppn.fit(X, y)
# plot绘制折线图
plt.plot(range(1, len(ppn.errors_)+1), ppn.errors_, marker='o')
plt.xlabel('Epochs')
plt.ylabel('number of misclassfications')
plt.show()

plot_decision_regions(X, y, classifier=ppn)
plt.xlabel('sepal length[cm]')
plt.ylabel('petal length[cm]')
plt.legend(loc='upper left')
plt.show()

猜你喜欢

转载自blog.csdn.net/yanwucao/article/details/80042938