2025년 이후 미래의 취업 전쟁에서 연봉10억 이상을 꿈꾸십니까?
그렇다면 파이선 코딩을 배우는 초보자라도 바로 이 머신 러닝에
독학으로 한번 도전해 보세요. 왜냐구요? 그다지 어렵지 않으니까요!
인공 지능을 배우려는 파이선 코딩 초보자들이 가지게 될 확률이 높은 의문점들을
하나하나 찾아내어 실제 풀어보고 결과를 확인해볼 수 있는 머신 러닝!
인터넷 교보문고에서 450페이지19900원에 판매중입니다.
________________________________________________________________________________________________________________________
2차원적인 예제와 4차원적인 특징 데이터를 가지는 붓꽃 데이터에 관해서 Linear Discriminant Analysis 기법을 이미 검토하였으나 그 과정에 오류가 있었던 것은 아니지만 정확한 지적을 하지 못하고 넘어간 부분들이 군데군데 눈에 띄었으므로 이러한 점들을 명확히 밝혀 보도록 하자. 아래의 url 은 이미 게재했던 관련 내용 사이트이다.
https://steemit.com/kr/@codingart/5-15-fisher-linear-discriminant-analysis-i
https://steemit.com/kr/@codingart/5-16-fisher-linear-discriminant-analysis-ii
https://steemit.com/kr/@codingart/5-17-fisher-linear-discriminant-analysis-iii
이미 까마득한 옛날로 볼 수도 있는 1936년 지금 머신 러닝의 원조로도 볼 수 있는 Iris flowers dataset 이 출현하게 되었다. 그 중심인물인 Fisher 교수는 하바드에서 연구차 방문한 Anderson 교수와 함께 농장에서 열심히 붓꽃 데이터 베이스 즉 Iris flowers dataset을 함께 만들었다. 바이오 통계학 전문가였던 Fisher 교수가 프로젝트를 주도했겠지만 Anderson 교수의 업적 또한 그에 버금간다. Anderson 교수는 식물들의 씨앗 상태부터 발아 성장 과정에 이르기까지 연구하는 발생학 연구자로서 붓꽃을 처음부터 세밀하게 실제 관찰하여 데이터베이스를 완성시키는 기여를 하였다. 즉 머신 러닝을 공부함에 있어서 믿고 쓸만한 유일한 값진 자료다.
붓꽃 데이터 베이스를 주도해서 만들었던 Fisher 교수는 영국이 나은 현대통계학의 창시자로서 그의 유전학 분야 연구는 통계수학에 의해 멘델의 유전학과 다윈의 진화론을 결합하는 눈부신 업적을 낳았다. 여기에 소개하는 LDA 가 바로 그 대표작 중에 하나일 수 있을 것이다. 머신 러닝과 연관된 천재적인 인물로서는 Softmax 명령과 연관된 물리학자 Boltzmann을 들 수 있는데 Fisher 교수의 업적도 거의 필적하지 않나 하는 생각이 든다. 이런 사실을 잘 모르고 있었다는 사실은 나 자신뿐만 아니라 우리나라의 인공지능 연구가 얼마나 척박한 환경에 있는지 잘 보여주는 듯하다.
붓꽃 데이터는 꽃받침의 길이와 폭 꽃잎의 길이와 폭 즉 4개의 독립적인 파라메터로 기술되며 “Setosa”, “Versicolor”, “Virginica” 의 3개의 종 즉 3개의 class 로 구성된다. 4개 중 어느 2개를 택하여 작도해 보아도 대부분 2개의 종이 서로 섞이는 영역이 있어 3개의 종이 명확하게 Classification 이 안 된다는 점이 확인 가능하다. 다음 작도는 꽃받침 길이와 꽃잎 길이 데이터를 사용하여 작도한 경우이다. 0,1,2 는 각각 “Setosa”, “Versicolor”, “Virginica”를 뜻한다. “Versicolor”와 “Virginica”의 학습 데이터도 섞여 있고 테스트 데이터도 섞여 있으며 87% 의 Classification 정확도를 보여 준다.
Fisher 교수와 Anderson 교수가 준비했던 Iris 데이터라면 어떤 통계적인 마법을 쓰던간에 100% 인식율을 보여 줄 수 있어야 할 것이다
.
왜냐하면 그들이 준비했던 붓꽃 데이터는 Anderson 교수의 Inspection을 통해 4개의 파라메터를 사용하여 엄격한 발생학적인 관점에서 Class 가 결정되었기 때문에 이 4개의 데이터라는 것이 현재 우리가 Classificationj 에 혼선이 있을 수 있으나 이미내재적으로 Class 값을 결정할 수 있는 잠재적인 가능성을 내포하고 있으리라 보는데 그 방법이 바로 Fisher 교수의 LDA 기법이라고 생각된다.
아무튼 대부분의 현대적인 머신 러닝 기법을 사용해도 ∼97% 가 한계로서 테스트 데이터 15개 중 하나가 틀리는게 보통이며 100% 가 쉽지 않다는 점을 지적해 둔다. 하지만 필자가 최근에 발견한 바에 의하면 Fisher의 기법을 사용하여 100% 가 가능하다는 점을 보여주도록 하겠다. LDA 기법을 연구하면서 우연하게 100% 가 가능하다는 점을 알게 되었지만 Fisher 교수의 통계학적 안목은 거의 1세기기 되어가지만 과연 통계학의 천재다운 면모가 여실하다 것을 깨닫는 계기가 되었다.
#mixing_01.py
from sklearn import __version__ as sklearn_version
from sklearn import datasets
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Perceptron
from sklearn.metrics import accuracy_score
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
iris = datasets.load_iris()
X = iris.data[:, [0, 2]]
y = iris.target
print('Class labels:', np.unique(y))
# Splitting data into 70% training and 30% test data:
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))
# Standardizing the features:
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:
ppn = Perceptron(n_iter=40, eta0=0.1, random_state=1)
ppn.fit(X_train_std, y_train)
# - You can replace `Perceptron(n_iter, ...)` by `Perceptron(max_iter, ...)` in scikit-learn >= 0.19. The `n_iter` parameter is used here deriberately, because some people still use scikit-learn 0.18.
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))
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')
# Training a perceptron model using the standardized training data:
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('sepal length [standardized]')
plt.ylabel('petal length [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()