2개의 LD(Linear Discriminant)가 결정되고 이에 따라 작도가 이루어졌다. LDA기법에서의 Classification 이란 결정된 LD 축을 따른 분포를 고려하는 것이다. 아래 그림을 보면 eigenvalue 의 큰 값에 해당하는 LD1 축을 따라서 Classification 이 가능하다는 것을 알 수 있다. 즉 eigenvalue 가 가장 클 때에 가장 informative 하다는 점을 알 수 있다.
LDA 오픈 소스를 사용하여 차원이 4인 붓꽃 데이터를 차원이 2인 데이터로 변환하였으며 아래 그림의 오른쪽 편이 그 결과이다. 오픈소스란 eigenvalue 계산까지 이르는 과정을 각론으로 쪼개어 기술했던 #iris_lda_Classifiers_01.py 코드를 의미한다. 반면에 scikit-learn 라이브러리에서 제공하는 LDA 전용 명령을 사용하면 왼쪽 그림의 결과가 얻어진다. 양 그래프의 패턴 자체는 동일하나 LD1, LD2 의 스케일이 다르다.
아래는 LDA 오픈소스인 Iris_lda_Classifiers_01.py 코드에서 각론으로 들어 있는 꽤 긴 분량의 LDA 과정이 하나의 LDA 전용 명령으로 대체되는 부분이다. 물론 입력 데이터를 준비하는 부분은 그대로 활용이 된다.
아울러 특기할 점은 LDA 명령에서 n_components=2로 설정하는데 사실 변환 작업 해보기 전에는 유효 eigenvalue 가 2개가 나올지 3개가 나올지 알 수 없는데 미리 2개로 설정한다는 점이다. 실제 코드에서 n_components=3으로 두고 코드를 실행해도 동일한 결과를 생성한다. 즉 LDA에서는 eigenvalue 가 원래 있는 만큼 계산되므로 아무런 문제가 되지 않는다.
아울러 이미 LDA에 의해서 데이터가 상당히 잘 분류되었기 때문에 LDA+Classifiers 처리과정에 의해서도 모두 100%의 정확도를 확인할 수 있다.
#iris_sklearn_lda_Classifiers_01.py
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
import math
s1 = 'sepal length cm'
s2 = 'sepal width cm'
s3 = 'petal length cm'
s4 = 'petal width cm'
feature_dict = {i:label for i,label in zip(range(4),( s1, s2, s3, s4))}
df = pd.io.parsers.read_csv(filepath_or_buffer=
'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data',
header=None,sep=',',)
df.columns = [l for i,l in sorted(feature_dict.items())] + ['class label']
df.dropna(how="all", inplace=True) # to drop the empty line at file-end
df.tail()
from sklearn.preprocessing import LabelEncoder
X=df[[ s1, s2, s3, s4]].values
y = df['class label'].values
enc = LabelEncoder()
label_encoder = enc.fit(y)
y = label_encoder.transform(y) + 1
label_dict = {1: 'Setosa', 2: 'Versicolor', 3:'Virginica'}
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
# LDA
sklearn_lda = LDA(n_components=2)
X_lda_sklearn = sklearn_lda.fit_transform(X, y)
print(X_lda_sklearn)
def plot_scikit_lda(X, title):
ax = plt.subplot(111)
for label,marker,color in zip(
range(1,4),('^', 's', 'o'),('blue', 'red', 'green')):
plt.scatter(x=X[:,0][y == label],
y=X[:,1][y == label] * -1, #flip the figure
marker=marker,
color=color,
alpha=0.5,
label=label_dict[label])
plt.xlabel('LD1')
plt.ylabel('LD2')
leg = plt.legend(loc='upper right', fancybox=True)
leg.get_frame().set_alpha(0.5)
plt.title(title)
#hide axis ticks
plt.tick_params(axis="both", which="both", bottom="off", top="off",
labelbottom=on", left="off", right="off", labelleft=on")
#remove axis spines
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
ax.spines["left"].set_visible(False)
plt.grid()
plt.tight_layout
plt.show()
plot_scikit_lda(X_lda_sklearn, title='Default LDA via scikit-learn')
#
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_lda, 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
from sklearn.linear_model import Perceptron
from sklearn.metrics import accuracy_score
ppn = Perceptron(n_iter=50, eta0=0.1, random_state=1)
ppn.fit(X_train_std, y_train)
y_pred = ppn.predict(X_test_std)
print('\nLDA+Perceptron')
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')
# 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('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
# Training a LogisticRegression model using the standardized training data:
from sklearn.linear_model import LogisticRegression
X_combined_std = np.vstack((X_train_std, X_test_std))
y_combined = np.hstack((y_train, y_test))
lr = LogisticRegression(C=100.0, random_state=1)
lr.fit(X_train_std, y_train)
y_pred = lr.predict(X_test_std)
print('\nLDA+LogisticRegression: C=100.0: OvR')
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
print('Accuracy: %.2f' % lr.score(X_test_std, y_test))
plot_decision_regions(X=X_combined_std, y=y_combined,
classifier=lr, test_idx=range(105, 150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.show()
from sklearn.svm import SVC
#C=1.0 OK 'linear'
svm = SVC(kernel='linear', C=1.0, random_state=1)
svm.fit(X_train_std, y_train)
y_pred = svm.predict(X_test_std)
print('\nLDA+Support Vector Machine SVM(linear): C=100.0')
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
print('Accuracy: %.2f' % svm.score(X_test_std, y_test))
plot_decision_regions(X_combined_std,
y_combined,
classifier=svm,
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()
#C=1.0, 10.0, 100.0 OK 'RBF'
svm = SVC(kernel='rbf', random_state=1, gamma=0.2, C=100.0)
svm.fit(X_train_std, y_train)
y_pred = svm.predict(X_test_std)
print('\nLDA+Support Vector Machine SVM(RBF): gamma=0.2,C=100.0')
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
print('Accuracy: %.2f' % svm.score(X_test_std, y_test))
plot_decision_regions(X_combined_std, y_combined,
classifier=svm, test_idx=range(105, 150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.show()
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.tree import export_graphviz
tree = DecisionTreeClassifier(criterion='gini',
max_depth=None,
random_state=1)
tree.fit(X_train, y_train)
y_pred = tree.predict(X_test)
print('\nLDA+Decision Tree')
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
print('Accuracy: %.2f' % tree.score(X_test, y_test))
X_combined = np.vstack((X_train, X_test))
y_combined = np.hstack((y_train, y_test))
plot_decision_regions(X_combined, y_combined,
classifier=tree, test_idx=range(105, 150))
plt.xlabel('petal length [cm]')
plt.ylabel('petal width [cm]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
forest = RandomForestClassifier(criterion='gini',
n_estimators=25,
random_state=1,
n_jobs=2)
forest.fit(X_train, y_train)
y_pred = forest.predict(X_test)
print('\nLDA+Random Forests')
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
print('Accuracy: %.2f' % forest.score(X_test, y_test))
plot_decision_regions(X_combined, y_combined,
classifier=forest, test_idx=range(105, 150))
plt.xlabel('petal length [cm]')
plt.ylabel('petal width [cm]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
'머신러닝' 카테고리의 다른 글
Anaconda3 PyTorch CIFAR-10 이미지 인식 Jupyter Notebook 예제 (0) | 2019.06.02 |
---|---|
5G 시대의 개막: 구글 Colaboratory에 의한 GPU 머신 러닝 (0) | 2019.06.01 |
경기 꿈의 대학 여섯째주: 블루투스 RC카 주행 (0) | 2019.05.29 |
Revision of Linear Discriminant Analysis To Iris Flowers Dataset III (0) | 2019.05.27 |
Fisher교수의 Linear Discriminant Analysis 기법 Revision II (0) | 2019.05.25 |