์ด๋ฒ ์ธ์ ์์๋ ์ฌ์ดํท๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํด์ ํผ์ ํธ๋ก ์ ํ๋ จํด๋ด์ผ๋ก์จ ์ฌ์ดํท๋ฐ์ ์์ํ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด๋ฒ ์ธ์ ๋ ์ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ๋ Google Colab์ผ๋ก ์ค์ตํฉ๋๋ค. Colab์๋ ์ด๋ฏธ ์ฌ์ดํท๋ฐ์ด ์ค์น๋์ด์์ผ๋ฏ๋ก ๋ณ๋์ ์ค์น์์ด ์ฌ์ฉํ์๋ฉด ๋ฉ๋๋ค!
https://colab.research.google.com
1. ๋ฐ์ดํฐ ์ฃผ์ ๊ณผ ํ์คํ
์ด๋ฒ ์ธ์ ์์๋ ์ธ์ 4์ 5์์ ๊ตฌํํ ๊ฒ๊ณผ ๋น์ทํ ํผ์ ํธ๋ก ๋ชจ๋ธ์ ์ฌ์ฉํ ๊ฒ์ ๋๋ค. ์ฌ์ฉํ ๋ถ๊ฝ ๋ฐ์ดํฐ ์ ์ ์ด๋ฏธ ์ฌ์ดํท๋ฐ์ ํฌํจ๋์ด์์ผ๋ฏ๋ก, ๋ฐ๋ก ๋ค์ด๋ฐ์ ํ์๋ ์์ต๋๋ค.
๊ฝ ์ํ ์ค์ ๊ฝ์ ๊ธธ์ด์ ๋๋น๋ฅผ ํ๋ ฌ X์, ๊ฝ ํ์ข ์ ๋ฒกํฐ Y์ ํ ๋นํฉ๋๋ค.
from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target
print('class label', np.unique(y))
np.uniqueํจ์๋ iris.target์ ์๋ ์ธ ๊ฐ์ ๋ถ๊ฝ ์ข ๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค. ๊ฒฐ๊ณผ๋ก class label [0 1 2] ๋ผ๋ ๋ด์ฉ์ด ๋์ค๊ณ , ๊ฝ์ ๋ผ๋ฒจ์ด 0๊ณผ 1๊ณผ 2๋ผ๋ ๊ฒ์ ํ์ธํ ์ ์์ฃ . ๊ฐ๊ฐ Iris-setasa, Iris-versicolor, Iris-virginica ์ ๋๋ค. ์ฌ์ดํท๋ฐ์ ํจ์์ ํด๋์ค ๋ฉ์๋๋ค์ ๋ฌธ์์ด ํํ์ ํด๋์ค ๋ ์ด๋ธ๋ค์ ๋ค๋ฃฐ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ๋๋๋ ๋ฐ์ ์ ์ํํ(0, 1, 2์ฒ๋ผ)๊ฐ ๊ถ์ฅ๋๋ ์ด์ ๋ ์ค์๋ฅผ ํผํ ์ ์๊ณ , ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
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('label count of y: ', np.bincount(y))
print('label count of y_train: ', np.bincount(y_train))
print('label count of y_test: ', np.bincount(y_test))
์ฌ์ดํท๋ฐ์ model_selection ๋ชจ๋์ train_test_split ํจ์๋ฅผ ์ด์ฉํด X์ y์ ๋ฐฐ์ด์ ๋๋คํ๊ฒ ๋๋๊ณ , 30%๋ ํ ์คํธ ๋ฐ์ดํฐ๋ก, 70%๋ ํ๋ จ ๋ฐ์ดํฐ๋ก ๋๋์ด์ฉ๋๋ค. ๋ฐฐ์ด์ ๋๋คํ๊ฒ ๋๋๋ ์ด์ ๋ ๊ฐ๋จํฉ๋๋ค. ๋ฐฐ์ด์ ์์ง์๊ณ ํธ๋ก๋ก ๋๋ ค๋ฒ๋ฆฌ๋ฉด ํ ์คํธ ๋ฐ์ดํฐ๋ setasa๋ง์ผ๋ก, ํ๋ จ ๋ฐ์ดํฐ๋ ๋ค๋ฅธ ๋ ๊ฝ๋ค๋ง์ผ๋ก ๋๋ ์๊ฐ ์์ต๋๋ค. ๊ทธ๋ผ ํ์ต์ด ์ ๋๋ก ์ด๋ฃจ์ด์ง์ง ์๊ฒ ์ฃ ?
stratify = y๋ ๊ณ์ธตํ๋ฅผ ์๋ฏธํฉ๋๋ค. ๊ณ์ธตํ๋ train_test_split ํจ์๊ฐ ๋๋ ๋์ ํด๋์ค ๋ ์ด๋ธ ๋น์จ์ ์ ๋ ฅ ๋ฐ์ดํฐ ์ ๊ณผ ๋์ผํ๊ฒ ๋ง์ถ๋ ๊ณผ์ ์ ๋๋ค. numpy์ ์๋ bincountํจ์๋ฅผ ์ด์ฉํ๋ฉด ๋ฐฐ์ด์ ์๋ ๊ฐ์ ๋ฑ์ฅ ํ์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ์ ์ฝ๋๋ฅผ ๋๋ ค๋ณด์ธ์!
์ด์ ์ธ์ ์์ ์ด์ผ๊ธฐํ๋ ๊ฒ์ฒ๋ผ ์ต์ ํ ์๊ณ ๋ฆฌ์ฆ์ ํน์ฑ ์ค์ผ์ผ์ ์กฐ์ ํด์ฃผ์ด์ผํฉ๋๋ค. ์ด ๊ณผ์ ์ ํ์คํ๋ผ๊ณ ํฉ๋๋ค. ์๋ ์ฝ๋๋ฅผ ์ด์ฉํด์ ํน์ฑ์ ํ์คํํด๋ด ์๋ค.
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)
processing ๋ชจ๋์์ standard scaler ํด๋์ค๋ฅผ ๋ก๋ํ ๋ค์ ์๋ก์ด ๊ฐ์ฒด standard scaler์ sc๋ก ํ ๋นํฉ๋๋ค. ์ด๋ ํ๊ธฐ์ ๊ฐํธํ๋ฅผ ์ํ ์์ ์ด๊ธฐ๋ ํฉ๋๋ค. fit๋ฉ์๋๋ฅผ ์ด์ฉํด์ ๊ฐ ํน์ฑ ์ฐจ์๋ง๋ค ์ํ ํ๊ท ๊ณผ ํ์คํธ์ฐจ๋ฅผ ๊ณ์ฐํ๊ณ , ์ด ๋๊ฐ์ง๋ฅผ transform์์ ํ๋ จ์ธํธ ํ์คํ๋ฅผ ์ค์ํฉ๋๋ค. ํ๋ จ๊ณผ ํ ์คํธ ์ธํธ์ ์ํ์ด ์๋ก ๊ฐ์ ๋น์จ๋ก ํ์คํํด์ฃผ์ฃ .
2. ํ๋ จ!
๋ฐ์ดํฐ ํ์คํ ์ดํ์ ๋๋์ด! ํผ์ ํธ๋ก ๋ชจ๋ธ์ ํ๋ จ์ํต๋๋ค. ์ฌ์ดํท๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ถ๋ถ OvR(one-versus-rest)๋ฐฉ์์ ์ฑํฑํ์ฌ ๋ค์ค๋ถ๋ฅ๋ฅผ ์ง์ํฉ๋๋ค. ์๋ ์ฝ๋๋ ์ธ ๊ฐ์ ๋ถ๊ฝ ํด๋์ค๋ฅผ ํ ๋ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ๋ฃ์ต๋๋ค.
from sklearn.linear_model import Perceptron
ppn = Perceptron(max_iter = 40, eta0 = 0.1, tol = 1e-3, random_state = 1)
ppn.fit(X_train_std, y_train)
์ฌ์ดํท๋ฐ์ ํฌํจ๋ ํผ์ ํธ๋ก ์ ์์ ์ธ์ ์์ ์ง์ ๊ตฌํํ ํผ์ ํธ๋ก ๊ณผ ๊ฑฐ์ ์ ์ฌํฉ๋๋ค. linear_model์์ ํผ์ ํธ๋ก ํด๋์ค๋ฅผ ๋ก๋ํ ๋ค์, ppn ๋ณ์์ ํผ์ ํธ๋ก ์ ๋ด์์ผ๋ก์จ ๊ฐ์ฒด๋ด ์์ฑํ ํ fit ๋ฉ์๋๋ฅผ ํตํด์ ํผ์ ํธ๋ก ๋ชจ๋ธ์ ํ๋ จํฉ๋๋ค. eta๋ ํ์ต๋ฅ ์, max_iter์ epoch๋ฅผ ๋ปํ๋๋ค. tol์ ์ข ๋ฃ์กฐ๊ฑด์ ์ง์ ํ๋ ์ด๋ ๊ฒฝ๊ณ ๋ฉ์ธ์ง๋ฅผ ํผํ๊ธฐ ์ํจ์ด๋ฏ๋ก ๊ตณ์ด ๊น๊ฒ ์ ํ์๋ ์์ต๋๋ค.
๊ทธ ๋ค์์ predict ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ์์ธก์ ๋ง๋ค์ด๋ ๋๋ค. ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
y_pred = ppn.predict(X_test_std)
print('์๋ชป ๋ถ๋ฅ๋ ์ํ ๊ฐ์ : %d' %(y_test != y_pred).sum())
from sklearn.metrics import accuracy_score
print('์ ํ๋ : %.2f' %accuracy_score(y_test, y_pred))
์ด ๊ฒฝ์ฐ ์๋ชป ๋ถ๋ฅ๋ ์ํ์ ํ๋๊ฐ ๋๊ณ , ์ ํ๋๋ 0.98, 98%๊ฐ ๋์ต๋๋ค. ์ฌ์ดํท๋ฐ์ ๋ถ๋ฅ๊ธฐ(classfier)๋ ์ ํ๋๋ฅผ ๊ณ์ฐํ๋ score ๋ฉ์๋๋ฅผ ๊ฐ๊ณ ์์ต๋๋ค. ์ด๋ฅผ ์ด์ฉํ๋ฉด ์๋์ ๊ฐ์ด๋ ์ธ ์ ์์ต๋๋ค.
print('์ ํ๋ : %.2f' % ppn.score(X_test_std, y_test))
3. ๊ทธ๋ํ์ ๊ฒฐ์ ๊ฒฝ๊ณ๋ฅผ ํตํ ์๊ฐํ
์์ ์ธ์ ์์ ๋ง๋ plot_decision_regions ํจ์๋ฅผ ์ด์ฉํด์ ๊ทธ๋ํ๋ฅผ ์๊ฐํํ๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ค๋ฅธ ์ ์ ์ฌ๊ธฐ์๋ ์ํ์ ์์ ์์ผ๋ก ํ์ํ๋ ๊ฒ ๋ฟ์ ๋๋ค.
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):
# ๋ง์ปค์ ์ปฌ๋ฌ๋งต์ ์ค์ ํฉ๋๋ค.
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
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, 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')
# ํ
์คํธ ์ํ์ ๋ถ๊ฐํ์ฌ ๊ทธ๋ฆฝ๋๋ค.
if test_idx:
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')
์์ ๋ ํจ์์ ํ์ํ ํ ์คํธ ์ํ ์ธ๋ฑ์ค๋ฅผ ์๋์ ๊ฐ์ด ์ง์ ํด์ค๋๋ค.
X_combined_std = np.vstack((X_train_std, X_test_std))
y_combined = np.hstack((y_train, y_test))
plot_decision_regions(X=X_combined_std, y=y_combined,
classifier=ppn, test_idx=range(105, 150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
์ด๋ ๊ฒ ์์๊ฐ์ด ์์ ์ ํ๊ฒฐ๊ณ ๊ทธ๋ํ๊น์ง ์ฌ์ดํท๋ฐ์ ํตํด์ ์์ฑํด๋ณด์์ต๋๋ค. ์์์๋ ์ด์ผ๊ธฐํ๋ฏ ๋ชจ๋ ์ฝ๋๋ฅผ ์ดํดํ ํ์๋ ์์ผ๋, ์ธ๊ธ๋ ํจ์์ ์ฐ์ ์ ๋๋ ๊ผญ ์์๋์๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค! ๋ค์ ์๊ฐ์๋ ๋ก์ง์คํฑ ํ๊ท๋ฅผ ์๊ฐํ๊ณ , ๊ตฌํํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค! ๋ค์ ์๊ฐ์ ๋ดฌ์! :)