本文用python实现自适应线性神经元(Adaline)算法,命名为myAdaline.py,会对前面的感知器算法的模块进行调用。
import numpy as np import matplotlib.pyplot as plt import myPerceptron as mP # 从自定义的myPerceptron文件中导入指定函数模块 class AdalineGD(object): def __init__(self, eta=0.01, n_iter=50): self.eta = eta self.n_iter = n_iter def fit(self, X, y): self.w_ = np.zeros(1 + X.shape[1]) self.cost_ = [] for i in range(self.n_iter): output = self.net_input(X) errors = (y - output) # 这是一个连续值组成的数组 self.w_[1:] += self.eta * X.T.dot(errors) # 计算w_[1:]的权重值 self.w_[0] += self.eta * errors.sum() # 计算w_[0]的权重值 cost = (errors ** 2).sum() / 2.0 # errors是一个数组,这个数组中的每个值的平方之后求和,最后再除以2 self.cost_.append(cost) # 根据代价函数值大小判断是否得到最优解 return self # 此处应与感知器的net_input区别,感知器输入的是xi,返回的是一个值,而此处返回的是一个数组 def net_input(self, X): return np.dot(X, self.w_[1:]) + self.w_[0] # 此处功能是激活 def activation(self, X): return self.net_input(X) def predict(self, X): return np.where(self.activation(X) >= 0.0, 1, -1) X, y = mP.getXy() # subplots中的nrows=1、ncols=2指的是有1*2个区域块,figsize=(8,4)指的是创建一个800*400像素的画布 fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(8, 4)) ada1 = AdalineGD(n_iter=10, eta=0.01).fit(X, y) ax[0].plot(range(1, len(ada1.cost_) + 1), np.log10(ada1.cost_), marker='o') # np.log10表示以10为底取对数 ax[0].set_xlabel('Epochs') ax[0].set_ylabel('log(sum-squared-error)') ax[0].set_title('Adaline-learning rate 0.01') ada2 = AdalineGD(n_iter=10, eta=0.0001).fit(X, y) ax[1].plot(range(1, len(ada2.cost_) + 1), ada2.cost_, marker='x') # 此处没有取对数 ax[1].set_xlabel('Epochs') ax[1].set_ylabel('sum-squared-error') ax[1].set_title('Adaline-learning rate 0.0001') plt.show() # 对第j个特征的值进行标准化处理,使对应的数据具有标准正态分布的特性 X_std = np.copy(X) X_std[:, 0] = (X[:, 0] - X[:, 0].mean()) / X[:, 0].std() X_std[:, 1] = (X[:, 1] - X[:, 1].mean()) / X[:, 1].std() # 再次训练Adaline ada = AdalineGD(n_iter=15, eta=0.01) ada.fit(X_std, y) mP.plot_decision_regions(X_std, y, ada) plt.title('Adaline - gradient descent') plt.xlabel('sepal length[standardized]') plt.ylabel('petal length[standardized]') plt.legend(loc='upper left') plt.show() plt.plot(range(1, len(ada.cost_) + 1), ada.cost_, marker='o') plt.xlabel('Epochs') plt.ylabel('sum-squared-error') plt.show()