머신러닝

1-10 Moon Decision Boundary Classification: SVC vs TensorFlow Cubic

coding art 2020. 1. 13. 15:06
728x90

Moon data는 데이터의 기하학적인 특성으로 인해 특히 고난이도의 클러스트링 알고리듬이 필요하다. K-means Agglomerative 클러스트링 기법으로도 처리가 안되며 DBSCAN 클러스트링이나 SVC 알고리듬이 대안이다. 이에 더하여 필자가 제안한 다항식 기법을 추가로 하되 기존의 2차식 모양(직선, 포물선, 쌍곡선)Hyperplane 표현만 가능했던 Covariance hypothesis 에서 차수가 하나 더 높은 Skew hypothesis를 사용하기로 하자. Covariance Skew 는 통계학적 개념이지만 한편 Hyperplane 곡선의 기하학적인 측면에서 Covariance 2차형이라면 Skew3차형이 된다.

 Sklearndatasets에서 지원하는 make_moons 루틴을 사용하여 반원형 호가 수평으로 어긋나서 상호 근접한 형상의 hyperplane 예제를 다루어 보자.


헤더 영역에서 sklearn.datasets를 불러들이면 make_moons 루틴 사용이 가능하다. noise=0.0 이면 깔끔한 원 모양이 되며 noise 값이 0.1 이상이면 호를 중심으로 편차가 있는 Moon 데이터가 출력된다.


SVC Classification 과 비교하되 다항식 기법에서 hypothesis를 다음과 같이 3세트의 랜덤 웨이트와 바이아스 세트를 사용하여 Skew 형으로 수정하도록 한다.



다음은 noise 값이 0.1 일 경우의 결과이다. SVC에서 Support Vector 1개가 추가로 misclassification 되었음을 알 수 있다.


다음은 noise 값이 0.2 일 경우의 결과이다. SVC에서 Support Vector 2개가 추가로 misclassification 되었음을 알 수 있다.

  


Support Vector들 간의 Marginregularization 알고리듬에 의해 최대화 시키는 SVC 알고리듬이 사실 가장 정밀한 것으로 알려져 있으나 위 그림의 두 결과를 관찰해 보면 오히려 통계학적 인텍스를 사용하는 다항식 기법의 Support Vector 처리가 noise=0.3 이내에서는 우수할 수도 있음을 알 수 있다.

 

#Moons_SVM_softmax_cubic_01.py

from sklearn import __version__ as sklearn_version
from sklearn.svm import SVC
from sklearn.datasets import make_moons
import numpy as np
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt


def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.01):

    # 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
    #print(x1_min.shape)
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))
    #print('xx1,xx2=',xx1,xx2)
    P=np.array([xx1.ravel(), xx2.ravel()])
    #print('P=',P.T)
    #print(classifier)
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    #print('Z.shape=',Z.shape)
    #print('Z=',Z)
    Z = Z.reshape(xx1.shape)
    #print('Z.reshape',Z)
    plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)
    plt.grid(True)
    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')


np.random.seed(1)
pts = 200
X_xor, y_xor = make_moons(n_samples=pts, noise=0.3, random_state=0)


plt.scatter(X_xor[:,0], X_xor[:, 1])
plt.show()

#Support Vector Machine "RBF"
svm = SVC(kernel='rbf', degree=2, random_state=0, gamma=2.0, C=1.0)
svm.fit(X_xor, y_xor)
plot_decision_regions(X_xor, y_xor,classifier=svm)

plt.legend(loc='upper left')
plt.tight_layout()
plt.show()

#Following is method to convert numpy array to tensor
import tensorflow as tf
import time

start_time = time.time()

def fn(X,W0,b0,W1,b1,W2,b2):
   
    hypothesis = (tf.matmul(X, W2) + b2)*(tf.matmul(X, W1) + b1)
    hypothesis = tf.nn.softmax(hypothesis*(tf.matmul(X, W0) + b0))
    return hypothesis


def tf_plot_decision_regions(X_xor, y, hypothesis, predicted, test_idx=None, resolution=0.01):
   
    # 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_xor[:, 0].min() - 1, X_xor[:, 0].max() + 1
    x2_min, x2_max = X_xor[:, 1].min() - 1, X_xor[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))
    print(xx1.shape)
    XX = np.array([xx1.ravel(), xx2.ravel()]).T
    #print(XX.shape)
    h, p = sess.run([hypothesis, predicted], feed_dict={X: XX })

    #print(p)
    p = p.reshape(xx1.shape)
    plt.contourf(xx1, xx2, p, alpha=0.3, cmap=cmap)
    plt.grid(True)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X_xor[y == cl, 0],
                    y=X_xor[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_xor[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 Data
Y_xor = np.zeros([pts,2])
Y_xor[y_xor == 0] = [1., 0.]
Y_xor[y_xor == 1] = [0., 1.]
#print(Y_xor)

X_xor = np.float32(X_xor)
Y_xor = np.float32(Y_xor)
#print(Y_xor)

#print(X_xor.shape)
#print(Y_xor.shape)

#hyperparameter
learning_rate = 0.0001
training_epochs = 40000
display_steps = 10000

#Network parameters
n_input = 2
dof1 = 2
#Graph Nodes
X = tf.placeholder("float", [None, n_input])
Y = tf.placeholder("float", [None, dof1])

#Weights and Biases, model, loss and optimizer
W0 = tf.Variable(tf.random_normal([n_input, dof1], stddev=0.01))
b0 = tf.Variable(tf.random_normal([dof1], stddev=0.01))
W1 = tf.Variable(tf.random_normal([n_input, dof1], stddev=0.01))
b1 = tf.Variable(tf.random_normal([dof1], stddev=0.01))
W2 = tf.Variable(tf.random_normal([n_input, dof1], stddev=0.01))
b2 = tf.Variable(tf.random_normal([dof1], stddev=0.01))

#hypothesis
hypothesis = fn(X,W0,b0,W1,b1,W2,b2)

# cost/loss function
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits
                      (logits=hypothesis, labels=Y))

#optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(cost)
optimizer = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(cost)

predicted = tf.cast(hypothesis[:, 0] < 0.5, dtype=tf.float32)
print(predicted.shape)

#predicted =  tf.cast(hypothesis > 0.5, dtype=tf.float32)

accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(hypothesis,1), tf.argmax(Y,1)), dtype=tf.float32))

#Initializing global variables
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
   
    for epoch in range(training_epochs):
        _, c, w1, B1, w2, B2 = sess.run([optimizer, cost, W1, b1, W2, b2], feed_dict={X: X_xor, Y: Y_xor})
        #if(epoch + 1) % display_steps == 0:
            #print( "Epoch: ", (epoch+1), "Cost: ", c, w1, B1, w2, B2 )
    print("Optimization Finished!")

    # Accuracy report
    h, p, a = sess.run([hypothesis, predicted, accuracy],feed_dict={X: X_xor, Y: Y_xor})

    #print("\nHypothesis:\n", h, "\nCorrect:\n", p, "\nAccuracy: ", a)
    #print(p.shape)
    p = p.reshape(pts,1)
    #print(p)
    tf_plot_decision_regions(X_xor, y_xor, hypothesis, predicted)
    plt.legend(loc='upper left')
    plt.tight_layout()
    plt.show()


sess.close()

end_time = time.time()
print( "\nCompleted in ", end_time - start_time , " seconds")