1-6 Sigmoid 함수를 사용한 Logistic Binary Classification과 퍼셉트론 비교
Iris flowers data set을 사용하여 Sigmoid 함수에 의한 Binary classification 문제를 코딩해 보고 퍼셉트론과 결과를 비교해 보자. 150개의 샘플들로 구성되는 Iris flowers data set은 3종류 즉 setosa, versicolor 및 verginica 로 구성되며 이들을 불러내어 각각 “0”, “1”, “2” 로 각각 라벨 명을 부여하였다.
150개로 이루어진 Iris flowers data set을 7:3의 비율로 즉 test_size = 0.3으로 학습용 데이터와 테스트용 데이터로 쪼개도록 한다. 특히 stratify=y 는 특히 라벨 명 측면에서 데이터를 학습용과 테스트용으로 쪼개는 과정에서 어느 한가지나 두가지 샘플 비중을 높이지 않으면서 쪼개기 전의 비율을 그대로 유지한다는 의미이다.
“0”, “1”, “2” 로 각각 라벨 명이 부여된 데이터 중에서 라벨 명이 “0”, “1”인 학습 데이터를 X_train_01_subset으로 둔다. 앞 장에서 테스트 데이터를 30%로 하였으므로 학습용 데이터는 70% 105개 이며 그 중 라벨 명이 “0”, “1”인 학습 데이터는 70개가 된다.
테스트할 데이터가 준비되었으면 라이브러리로 준비된 Sigmoid 함수를 불러 학습을 시키도록 하자. Sigmoid 함수를 사용하기 위한 object 는 learning rate eta 값, 학습횟수 n_iter 이며 항상 동일한 결과를 출력해 보기위한 random_state 값들이다.
class LogisticRegreesionGD()에 의해 fit()을 실행시켜 학습을 끝낸 후 plot_decision_regions에 의해 decision boundary를 그래픽 처리하자.
커버 그림에서 살펴보면 퍼셉트론 방식에 의해서 처리된 결과와 Sigmoid 함수를 사용하는 Logistic regression 비교 결과 classification 작업은 제대로 이루어졌지만 decision boundary는 petal length 가로 좌표축에서 관찰해보면 상당히 큰 차이가 있으며 높이 방향 세로 좌표축에도 다소 차이가 있음을 관찰할 수 있다.
#ch03_data_read_1.4.py
from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target
print('Class labels:', np.unique(y))
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=1, stratify=y)
print('Labels counts in y:', np.bincount(y))
print('Labels counts in y_train:', np.bincount(y_train))
print('Labels counts in y_test:', np.bincount(y_test))
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
## Training a perceptron via scikit-learn
Redefining the plot_decision_region
function from chapter 2:
from sklearn.linear_model import Perceptron
from sklearn.metrics import accuracy_score
ppn = Perceptron(n_iter=40, eta0=0.1, random_state=1)
ppn.fit(X_train_std, y_train)
y_pred = ppn.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
print('Accuracy: %.2f' % ppn.score(X_test_std, y_test))
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):
# setup marker generator and color map
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
# plot the decision surface
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, resolution),
np.arange(x2_min, x2_max, resolution))
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y == cl, 0],
y=X[y == cl, 1],
alpha=0.8,
c=colors[idx],
marker=markers[idx],
label=cl,
edgecolor='black')
# highlight test samples
if test_idx:
# plot all samples
X_test, y_test = X[test_idx, :], y[test_idx]
plt.scatter(X_test[:, 0],
X_test[:, 1],
c='',
edgecolor='black',
alpha=1.0,
linewidth=1,
marker='o',
s=100,
label='test set')
class LogisticRegressionGD(object):
"""Logistic Regression Classifier using gradient descent.
Parameters
------------
eta : float
Learning rate (between 0.0 and 1.0)
n_iter : int
Passes over the training dataset.
random_state : int
Random number generator seed for random weight
initialization.
Attributes
-----------
w_ : 1d-array
Weights after fitting.
cost_ : list
Logistic cost function value in each epoch.
"""
def __init__(self, eta=0.05, n_iter=100, random_state=1):
self.eta = eta
self.n_iter = n_iter
self.random_state = random_state
def fit(self, X, y):
""" Fit training data.
Parameters
----------
X : {array-like}, shape = [n_samples, n_features]
Training vectors, where n_samples is the number of samples and
n_features is the number of features.
y : array-like, shape = [n_samples]
Target values.
Returns
-------
self : object
"""
rgen = np.random.RandomState(self.random_state)
self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
self.cost_ = []
for i in range(self.n_iter):
net_input = self.net_input(X)
output = self.activation(net_input)
errors = (y - output)
self.w_[1:] += self.eta * X.T.dot(errors)
self.w_[0] += self.eta * errors.sum()
# note that we compute the logistic `cost` now
# instead of the sum of squared errors cost
cost = -y.dot(np.log(output)) - ((1 - y).dot(np.log(1 - output)))
self.cost_.append(cost)
return self
def net_input(self, X):
"""Calculate net input"""
return np.dot(X, self.w_[1:]) + self.w_[0]
def activation(self, z):
"""Compute logistic sigmoid activation"""
return 1. / (1. + np.exp(-np.clip(z, -250, 250)))
def predict(self, X):
"""Return class label after unit step"""
return np.where(self.net_input(X) >= 0.0, 1, 0)
# equivalent to:
# return np.where(self.activation(self.net_input(X)) >= 0.5, 1, 0)
X_train_01_subset = X_train[(y_train == 0) | (y_train == 1)]
y_train_01_subset = y_train[(y_train == 0) | (y_train == 1)]
print('Class labels:', np.unique(y_train_01_subset))
lrgd = LogisticRegressionGD(eta=0.05, n_iter=1000, random_state=1)
lrgd.fit(X_train_01_subset,
y_train_01_subset)
plot_decision_regions(X=X_train_01_subset,
y=y_train_01_subset,
classifier=lrgd)
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
from sklearn.linear_model import Perceptron
ppn = Perceptron(n_iter=1000, eta0=0.05, random_state=1)
ppn.fit(X_train_01_subset,
y_train_01_subset)
plot_decision_regions(X=X_train_01_subset,
y=y_train_01_subset,
classifier=ppn)
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
짱짱맨 호출에 응답하여 보팅하였습니다.
Congratulations @codingart! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word
STOP
To support your work, I also upvoted your post!