Skip to content

Instantly share code, notes, and snippets.

@darden1
Last active December 22, 2018 13:45
Show Gist options
  • Save darden1/19427cf418bbf8c1fe8572a4627f7528 to your computer and use it in GitHub Desktop.
Save darden1/19427cf418bbf8c1fe8572a4627f7528 to your computer and use it in GitHub Desktop.
StudyMachineLearning_AdalineSGD.py
# -*- 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 (特徴量を標準化,シャッフルオフ,バッチ勾配降下法))
Xstd = np.copy(X)
Xstd[:, 0] = (X[:, 0] - X[:, 0].mean()) / X[:, 0].std()
Xstd[:, 1] = (X[:, 1] - X[:, 1].mean()) / X[:, 1].std()
ada = Adaline(eta=0.01, numEpoch=20, shuffle=False)
ada.fit(Xstd, y)
plotResult(ada,Xstd,y,"Standardization","Off","GD")
# ---学習実施(学習率:0.01 最大エポック数:20 (特徴量を標準化,シャッフルオフ,確率的勾配降下法))
Xstd = np.copy(X)
Xstd[:, 0] = (X[:, 0] - X[:, 0].mean()) / X[:, 0].std()
Xstd[:, 1] = (X[:, 1] - X[:, 1].mean()) / X[:, 1].std()
ada = Adaline(eta=0.01, numEpoch=20, shuffle=False)
ada.fitSGD(Xstd, y)
plotResult(ada, Xstd, y, "Standardization", "Off", "SGD")
# ---学習実施(学習率:0.01 最大エポック数:20 (特徴量を標準化,シャッフルオン,確率的勾配降下法))
Xstd = np.copy(X)
Xstd[:, 0] = (X[:, 0] - X[:, 0].mean()) / X[:, 0].std()
Xstd[:, 1] = (X[:, 1] - X[:, 1].mean()) / X[:, 1].std()
ada = Adaline(eta=0.01, numEpoch=20, shuffle=True)
ada.fitSGD(Xstd, y)
plotResult(ada, Xstd, y, "Standardization", "On", "SGD")
# ---学習実施(学習率:0.01 最大エポック数:20 (特徴量を標準化,シャッフルオン,最小二乗法))
Xstd = np.copy(X)
Xstd[:, 0] = (X[:, 0] - X[:, 0].mean()) / X[:, 0].std()
Xstd[:, 1] = (X[:, 1] - X[:, 1].mean()) / X[:, 1].std()
ada = Adaline(eta=0.01, numEpoch=20, shuffle=True)
ada.fitLS(Xstd, y)
plotResult(ada, Xstd, y, "Standardization", "On", "LS")
def plotResult(ada,X,y,trainSampleState,shuffeled,fitAlgorism):
#---プロットのプロパティ
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"_シャッフル"+shuffeled+u"_Fitアルゴリズム"+fitAlgorism+ 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, shuffle=True, random_state=None):
self.alpha = alpha # 活性化関数の定数
self.eta = eta #学習率
self.numEpoch = numEpoch #最大エポック数
self.shuffle = shuffle #トレーニングサンプルをシャッフルする?
if random_state:
np.random.seed(random_state)
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 __shuffle(self, X, y):
"""トレーニングサンプルのシャッフル(__でプライベート関数)"""
r = np.random.permutation(len(y))
return X[r], y[r]
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):
"""バッチ勾配降下法による学習の実施"""
# ---トレーニングサンプルのシャッフル
if self.shuffle:
X, y = self.__shuffle(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))
def fitSGD(self, X, y):
"""確率的勾配降下法による学習の実施"""
# ---トレーニングサンプルのシャッフル
if self.shuffle:
X, y = self.__shuffle(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 = [] # 各トレーニングセットに対する教師データと予測値の正誤表をイニシャライズ
for xi, yi in zip(X, y): # トレーニングセットループ
# ---コスト関数の勾配
gradJi = -self.alpha * xi.T * yi + self.alpha ** 2 * xi.T * xi * self.w_
# ---重み更新
dwi = - self.eta * gradJi
self.w_ = self.w_ + dwi
# ---特徴行列と重みベクトルの掛け合わせ
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))
def fitLS(self, X, y):
"""最小二乗法による学習の実施"""
# ---トレーニングサンプルのシャッフル
if self.shuffle:
X, y = self.__shuffle(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 = [] # 各トレーニングセットに対する教師データと予測値の正誤表をイニシャライズ
# ---コスト関数を最小にする重みを一発で算出
self.w_ = np.linalg.inv(X.T*X)*X.T*y /self.alpha
# ---特徴行列と重みベクトルの掛け合わせ
z = X * self.w_
# ---活性化関数
phi = self.__actFunc(z)
# ---教師データと活性化関数出力の残差ベクトル
e = y - self.alpha * X * self.w_
# ---コスト関数
J = e.T * e / 2
# 重みをエポックごとに保存
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