《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()