读取数据:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 读取数据
df = pd.read_csv("./iris.data")
y = df.iloc[0:100, 4].values
y = np.where(y == "Iris-setosa", 1, -1)
x = df.iloc[0:100, [0,2]].values
plt.scatter(x[y==1,[0]], x[y==1, [1]], color='red', marker="o", label="Iris-setosa") # 散点图
plt.scatter(x[y==-1,[0]], x[y==-1, [1]], color='blue', marker="o", label="setosa")
plt.xlabel("sepal length [cm]")
plt.ylabel("petal length [cm]")
plt.legend(loc="upper left")
plt.show()
采用自定义的感知机进行训练:
class perception:
def __init__(self, X, Y, lr = 0.01, Iter = 50):
self.lr = lr
self.Iter = Iter
self.X = X
self.Y = Y
np.random.seed(10)
self.w = np.random.normal(loc=0.0, scale=0.01, size=X.shape[1]+1)
def prediction(self, x):
result = np.dot(x, self.w[1:]) + self.w[0]
return np.where(result >= 0.0, 1, -1)
def fit(self):
error = []
for _ in range(self.Iter):
_error = 0
for x,y in zip(self.X, self.Y):
update = self.lr * (y - self.prediction(x))
self.w[1:] += update*x
self.w[0] += update
_error += int(update != 0)
error.append(_error)
_error = 0
return error
per = perception(X=x, Y=y, lr=0.1,Iter=10)
error = per.fit()
plt.plot(range(1, len(error)+1), error, color='red')
plt.xlabel("Epoch")
plt.ylabel("Errors")
plt.legend("upper left")
绘制色度图:
from matplotlib.colors import ListedColormap
def plt_decision_regions(x, y, classfer):
markers = ["*", "s", "x", "o"]
colors = ["red", "blue", "lightgreen", "gray"]
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
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02), np.arange(x2_min, x2_max, 0.02))
z = classfer.prediction(np.array([xx1.ravel(), xx2.ravel()]).T)
z = z.reshape(xx1.shape)
plt.contourf(xx1, xx2, z, alpha=0.3, cmap = cmap)
plt.xlim(x1_min, x1_max)
plt.ylim(x2_min, x2_max)
for idx,c1 in enumerate(np.unique(y)):
plt.scatter(x=x[y==c1,0],y=x[y==c1,1],alpha=0.8,c=colors[idx],marker=markers[idx],label=c1,edgecolor="black" )
plt.legend(loc="upper left")
plt.xlabel("sepal legenth [cm]")
plt.ylabel("prtal length [cm]")
plt.show()
增加激励单元:
class AdalineGD:
def __init__(self, X, Y, lr=0.1, epoch=10):
'''
Input:
X: (N,2)
Y: (N,1) -- 1 or -1
Output:
w: (3,) and w[0] is bias
'''
self.X = X
self.Y = Y
self.lr = lr
self.epoch = epoch
np.random.seed(1)
self.w = np.random.normal(loc=0.0, scale=0.01, size = X.shape[1] + 1)
def fit(self):
error = []
for _ in range(self.epoch):
_error = self.Y - self.activation(np.dot(self.X, self.w[1:]) + self.w[0])
self.w[1:] += self.lr * np.dot(self.X.T, _error)
self.w[0] += self.lr * _error.sum()
error.append((_error**2).sum()/2.0)
return error
def activation(self,X):
return X
def predict(self,X):
'''
Input:
X: (N,2)
Output:
result: (N,1) -- 1 or -1
'''
result = np.dot(X, self.w[1:]) + self.w[0]
return np.where(result >= 0.0, 1, -1)
比较不同学习率的结果:
adal = AdalineGD(X=x, Y=y, lr=0.01,epoch=50)
error1 = adal.fit()
np.log10(error1)
plt.plot(np.arange(1, len(error1)+1), error1, marker="o")
plt.xlabel("epoch")
plt.ylabel("error")
plt.title("lr=0.01")
plt.show()
ada2 = AdalineGD(X=x, Y=y, lr=0.0001)
error2 = ada2.fit()
plt.plot(np.arange(1, len(error2)+1), error2, marker="o")
plt.xlabel("epoch")
plt.ylabel("error")
plt.title("lr=0.0001")
plt.show()
数据归一化后进行训练:
# 数据标准化
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()
adal = AdalineGD(X=x_std, Y=y, lr=0.01,epoch=10)
error1 = adal.fit()
# np.log10(error1)
plt.plot(np.arange(1, len(error1)+1), error1, marker="o")
plt.xlabel("epoch")
plt.ylabel("error")
plt.title("lr=0.01")
plt.show()