Last active
December 22, 2018 13:45
-
-
Save darden1/671bcd9098ba768a82ebb3e6275b9b76 to your computer and use it in GitHub Desktop.
StudyMachineLearning_Adaline.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import sys | |
import numpy as np | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
from matplotlib.colors import ListedColormap | |
def main(): | |
# ---アヤメデータの取得 | |
df = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data", header=None) | |
y = df.iloc[0:100, 4].values | |
y = np.where(y == "Iris-setosa", -1, 1) | |
X = df.iloc[0:100, [0, 2]].values | |
# ---学習実施(学習率:0.01 最大エポック数:20) | |
ada = Adaline(eta=0.01, numEpoch=20) | |
ada.fit(X, y) | |
plotResult(ada,X,y,"Normal") | |
# ---学習実施(学習率:0.0001 最大エポック数:20) | |
ada = Adaline(eta=0.0001, numEpoch=20) | |
ada.fit(X, y) | |
plotResult(ada,X,y,"Normal") | |
# ---学習実施(学習率:0.0001 最大エポック数:400) | |
ada = Adaline(eta=0.0001, numEpoch=400) | |
ada.fit(X, y) | |
plotResult(ada,X,y,"Normal") | |
# ---学習実施(学習率:0.01 最大エポック数:20 (特徴量を標準化)) | |
X[:, 0] = (X[:, 0] - X[:, 0].mean()) / X[:, 0].std() | |
X[:, 1] = (X[:, 1] - X[:, 1].mean()) / X[:, 1].std() | |
ada = Adaline(eta=0.01, numEpoch=20) | |
ada.fit(X, y) | |
plotResult(ada,X,y,"Standardization") | |
def plotResult(ada,X,y,trainSampleState): | |
#---プロットのプロパティ | |
markers = ('s', 'o', 'x', '^', 'v') | |
colors = ('green', 'yellow','red', 'blue', 'lightgreen', 'gray', 'cyan') | |
cmap = ListedColormap(colors[:len(np.unique(y))]) | |
labels = ('setosa', 'versicolor') | |
fig = plt.figure(figsize=(12, 10)) | |
plt.clf() | |
ax1 = fig.add_subplot(221) | |
ax2 = fig.add_subplot(222) | |
ax3 = fig.add_subplot(223) | |
ax4 = fig.add_subplot(224) | |
# ---エポック数と重みのプロット | |
epochTimes = np.array(range(0, ada.numEpoch + 1)) | |
ada.W_ = np.array(ada.W_) | |
ax1.plot(epochTimes, ada.W_[:, 0].T[0], color="blue", label="w0") | |
ax1.plot(epochTimes, ada.W_[:, 1].T[0], color="red", label="w2") | |
ax1.plot(epochTimes, ada.W_[:, 2].T[0], color="green", label="w1") | |
ax1.legend(loc="upper left") | |
ax1.set_xlabel('Epochs') | |
ax1.set_ylabel('Weight') | |
ax1.set_title("Epochs and weight") | |
ax1.set_xlim(0, ada.numEpoch) | |
# ---ax1.set_xticks(range(0,numEpoch+1,1)) | |
ax1.grid() | |
# ---エポック数と正答率のプロット | |
epochTimes = range(1, ada.numEpoch + 1) | |
ax2.plot(epochTimes, np.array(ada.correctAnswerRateEachEpoch_) * 100, color="blue", marker="o", | |
label="Correct answer rate") | |
# ---ax2.legend(loc="upper left") | |
ax2.set_title("Epochs and correct answer rate") | |
ax2.set_xlabel('Epochs') | |
ax2.set_ylabel('Correct answer rate[%]') | |
ax2.set_xlim(0, ada.numEpoch) | |
ax2.grid() | |
plt.xlim(0, ada.numEpoch) | |
# ---エポック数とコスト関数のプロット | |
epochTimes = range(1, ada.numEpoch + 1) | |
ax3.plot(epochTimes, np.array(ada.J_)[:, 0][:, 0], color="blue", marker="o", | |
label="Cost function values") | |
# ---ax3.legend(loc="upper left") | |
ax3.set_title("Epochs and cost function values") | |
ax3.set_xlabel('Epochs') | |
ax3.set_ylabel('Cost function values') | |
ax3.set_xlim(0, ada.numEpoch) | |
ax3.grid() | |
# ---ax3.set_xticks(range(0,numEpoch+1,1)) | |
# ---決定領域のプロット | |
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1 | |
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1 | |
dx = 0.02 | |
X1 = np.arange(x1_min, x1_max, dx) | |
X2 = np.arange(x2_min, x2_max, dx) | |
X1, X2 = np.meshgrid(X1, X2) | |
Z = ada.predict(np.array([X1.ravel(), X2.ravel()]).T) | |
Z = Z.reshape(X1.shape) | |
# ---決定領域 | |
ax4.contourf(X1, X2, Z, alpha=0.5, cmap=cmap) | |
ax4.set_xlim(X1.min(), X1.max()) | |
ax4.set_ylim(X2.min(), X2.max()) | |
# ---アヤメデータ | |
for idx, cl in enumerate(np.unique(y)): | |
ax4.scatter(x=X[y == cl, 0], y=X[y == cl, 1], | |
alpha=1.0, c=cmap(idx), | |
marker=markers[idx], label=labels[idx]) | |
ax4.set_title("Decision regions") | |
ax4.set_xlabel("Sepal length [cm]") # がく片の長さ | |
ax4.set_ylabel("Petal length [cm]") # 花びらの長さ | |
ax4.legend(loc="upper left") | |
ax4.grid() | |
pngFileName=u"ADALINE学習結果_トレーニングサンプル" +trainSampleState + u"_学習率"+str(ada.eta)+u"_最大エポック数"+str(ada.numEpoch)+ ".png" | |
plt.savefig(pngFileName, dpi=300) | |
class Adaline(object): | |
def __init__(self, alpha=1.0, eta=0.01, numEpoch=10): | |
self.alpha = alpha # 活性化関数の定数 | |
self.eta = eta #学習率 | |
self.numEpoch = numEpoch #最大エポック数 | |
self.W_=[] #各エポックごとに重みを保存するリスト | |
self.J_=[] #各エポックごとにコスト関数を保存するリスト | |
self.correctAnswerRateEachEpoch_=[] #各エポックごとに正答率を保存するリスト | |
def __actFunc(self, z): | |
"""活性化関数(__でプライベート関数)""" | |
return self.alpha*z | |
def __quantizer(self, phi): | |
"""量子化器(__でプライベート関数)""" | |
return np.where(np.array(phi) >= 0.0, 1, -1) | |
def predict(self, X): | |
"""予測関数""" | |
X = np.matrix(X) | |
m, n = X.shape | |
X = np.c_[np.matrix(np.ones((m, 1))), X] | |
z=X*self.w_ | |
phi=self.__actFunc(z) | |
return self.__quantizer(phi) | |
def fit(self, X, y): | |
"""学習の実施""" | |
# ---特徴行列 | |
X = np.matrix(X) | |
m, n = X.shape | |
# ---しきい値用に一番左側の列に1を追加 | |
X = np.c_[np.matrix(np.ones((m, 1))), X] | |
# ---教師データベクトル | |
y = np.matrix(y).T | |
# ---重みベクトル(初期化) | |
self.w_ =np.matrix(np.zeros((n+1,1))) | |
# 重みを学習回数ごとに保存 | |
self.W_.append(self.w_.tolist()) | |
for indexEpoch in range(1,self.numEpoch+1): #エポックループ | |
correctAnswer=[] #各トレーニングセットに対する教師データと予測値の正誤表をイニシャライズ | |
# ---特徴行列と重みベクトルの掛け合わせ | |
z = X * self.w_ | |
# ---活性化関数出力ベクトル | |
phi =self.__actFunc(z) | |
# ---教師データと活性化関数出力の残差ベクトル | |
e = y - self.alpha * X * self.w_ | |
# ---コスト関数 | |
J = e.T * e / 2 | |
# ---コスト関数の勾配 | |
gradJ = -self.alpha * X.T * y + self.alpha ** 2 * X.T * X * self.w_ | |
# ---重み更新 | |
dw = - self.eta * gradJ | |
self.w_ = self.w_ + dw | |
# 重みをエポックごとに保存 | |
self.W_.append(self.w_.tolist()) | |
# コスト関数をエポックごとに保存 | |
self.J_.append(J.tolist()) | |
#--正答表 | |
correctAnswer = np.where(np.array(y == self.__quantizer(phi)) == True, 1, 0) | |
#各エポックごとに正誤表から正答率算出し保存 | |
self.correctAnswerRateEachEpoch_.append(float(sum(correctAnswer))/len(correctAnswer)) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment