Detecting Patterns with Unsupervised Learning

oyoi·2024년 3월 28일

What is unsupervised learning?

비지도 학습이란 레이블이 없는 학습 데이터로 머신 러닝 모델을 만드는 기법이다. 비지도 학습은 시장 세분화, 주식 시장 분석, 자연어 처리, 컴퓨터 비전을 비롯한 다양한 분야에서 활용된다. 비지도 학습 알고리즘은 주어진 데이터 집합에 담긴 데이터 유사도에 따라 소그룹으로 나누는 방식으로 학습 모델을 만든다.

Clustering data with K-Means algorithm

1 군집화

군집화는 유사도 또는 비유사도 측정 기준에 따라 서로 비슷한 원소끼리 소그룹으로 묶는 일종의 데이터 조직화 과정을 말한다. 군집화를 하기 위해서는 개별 데이터들을 하나의 그룹으로 묶는 고유한 속성을 찾아야 한다.

2 K-평균 알고리즘

K-평균 알고리즘은 중심점의 첫 위치가 매우 중요하다. 결과에 직접적으로 영향을 미치기 때문이다. 첫 중심점을 기준으로 모든 데이터를 분류하고 나면 각 군집들의 중심점을 다시 계산한다. 그리고는 데이터를 다시 분류하고 중심점을 계산하기를 반복한다.

import numpy as np 
import matplotlib.pyplot as plt 
from sklearn.cluster import KMeans 
from sklearn import metrics 

# Load input data 
X = np.loadtxt('data_clustering.txt', delimiter=',') 

num_clusters = 5 

# Plot input data 
plt.figure() 
plt.scatter(X[:,0], X[:,1], marker='o', facecolors='none',  
        edgecolors='black', s=80) 
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 
plt.title('Input data') 
plt.xlim(x_min, x_max) 
plt.ylim(y_min, y_max) 
plt.xticks(()) 
plt.yticks(()) 

# Create KMeans object  
kmeans = KMeans(init='k-means++', n_clusters=num_clusters, n_init=10)

# Train the KMeans clustering model 
kmeans.fit(X) 

# Step size of the mesh 
step_size = 0.01 

# Define the grid of points to plot the boundaries 
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 
x_vals, y_vals = np.meshgrid(np.arange(x_min, x_max, step_size), 
        np.arange(y_min, y_max, step_size)) 

# Predict output labels for all the points on the grid  
output = kmeans.predict(np.c_[x_vals.ravel(), y_vals.ravel()]) 

# Plot different regions and color them  
output = output.reshape(x_vals.shape) 
plt.figure() 
plt.clf() 
plt.imshow(output, interpolation='nearest', 
           extent=(x_vals.min(), x_vals.max(),  
               y_vals.min(), y_vals.max()), 
           cmap=plt.cm.Paired,  
           aspect='auto',  
           origin='lower') 
           
# Overlay input points 
plt.scatter(X[:,0], X[:,1], marker='o', facecolors='none',  
        edgecolors='black', s=80)
        
# Plot the centers of clusters 
cluster_centers = kmeans.cluster_centers_ 
plt.scatter(cluster_centers[:,0], cluster_centers[:,1],  
        marker='o', s=210, linewidths=4, color='black',  
        zorder=12, facecolors='black') 
 
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 
plt.title('Boundaries of clusters') 
plt.xlim(x_min, x_max) 
plt.ylim(y_min, y_max) 
plt.xticks(()) 
plt.yticks(()) 
plt.show()

Estimating the number of clusters with Mean Shift algorithm

평균 이동 알고리즘은 비모수적 기법으로서 중심점의 위치를 찾는 것을 목적으로 한다. 윈도우를 정의하고 각 윈도우의 중심점을 계산한다. 다시 윈도우를 지정하고 중심점을 갱신하는 것을 반복한다.

import numpy as np 
import matplotlib.pyplot as plt 
from sklearn.cluster import MeanShift, estimate_bandwidth 
from itertools import cycle 

# Load data from input file 
X = np.loadtxt('data_clustering.txt', delimiter=',') 

# Estimate the bandwidth of X 
bandwidth_X = estimate_bandwidth(X, quantile=0.1, n_samples=len(X)) 

# Cluster data with MeanShift 
meanshift_model = MeanShift(bandwidth=bandwidth_X, bin_seeding=True) 
meanshift_model.fit(X) 

# Extract the centers of clusters 
cluster_centers = meanshift_model.cluster_centers_ 
print('\nCenters of clusters:\n', cluster_centers) 

# Estimate the number of clusters 
labels = meanshift_model.labels_ 
num_clusters = len(np.unique(labels)) 
print("\nNumber of clusters in input data =", num_clusters) 

# Plot the points and cluster centers 
plt.figure() 
markers = 'o*xvs' 
for i, marker in zip(range(num_clusters), markers): 
    # Plot points that belong to the current cluster
    plt.scatter(X[labels==i, 0], X[labels==i, 1], marker=marker, color='black') 
    
    # Plot the cluster center 
    cluster_center = cluster_centers[i] 
    plt.plot(cluster_center[0], cluster_center[1], marker='o',  
            markerfacecolor='black', markeredgecolor='black',  
            markersize=15) 
 
plt.title('Clusters') 
plt.show() 

Estimating the quality of clustering with silhouette scores

1 실루엣 기법

실루엣 기법이란 데이터에 존재하는 군집의 일관성을 검사하는 방법이다. 실루엣 지수란 특정한 데이터가 다른 군집에 비해 자신이 속한 군집에 얼마나 가까운지를 측정하는 지표다.

2 실루엣 지수

silhouette score = (p - q) / max(p, q)

여기서 p는 현재 데이터가 속하지 않은 군집 중에서 가장 가까운 군집에 있는 점들 사이의 거리에 대한 평균이고, q는 자신이 속한 군집에 있는 모든 점과 다른 군집 사이의 거리에 대한 평균이다.

score = metrics.silhouette_score(X, kmeans.labels_, 
	metric='euclidean', sample_size=len(X))
    
print("\nNumber of clusters =", num_clusters) 
print("Silhouette score =", score) 
                     
scores.append(score)

# Plot silhouette scores 
plt.figure() 
plt.bar(values, scores, width=0.7, color='black', align='center') 
plt.title('Silhouette score vs number of clusters') 

# Extract best score and optimal number of clusters 
num_clusters = np.argmax(scores) + values[0] 
print('\nOptimal number of clusters =', num_clusters) 

# Plot data 
plt.figure() 
plt.scatter(X[:,0], X[:,1], color='black', s=80, marker='o', facecolors='none') 
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 
plt.title('Input data') 
plt.xlim(x_min, x_max) 
plt.ylim(y_min, y_max) 
plt.xticks(()) 
plt.yticks(()) 
 
plt.show()

What are Gaussian Mixture Models?

혼합 모델이란 데이터 여러 개의 성분 분포를 따른다고 가정하는 확률 밀도 모델이다. 이때 각 성분 분포가 가우시안 분포인 모델을 가우시안 혼합 모델이라고 한다.

Building a classifier based on Gaussian Mixture Models

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib import patches 
 
from sklearn import datasets 
from sklearn.mixture import GMM 
from sklearn.cross_validation import StratifiedKFold

# Load the iris dataset 
iris = datasets.load_iris() 

# Split dataset into training and testing (80/20 split) 
indices = StratifiedKFold(iris.target, n_folds=5)

# Take the first fold 
train_index, test_index = next(iter(indices)) 
 
# Extract training data and labels 
X_train = iris.data[train_index] 
y_train = iris.target[train_index] 
 
# Extract testing data and labels 
X_test = iris.data[test_index] 
y_test = iris.target[test_index]

# Extract the number of classes 
num_classes = len(np.unique(y_train)) 

# Build GMM 
classifier = GMM(n_components=num_classes, covariance_type='full',  
        init_params='wc', n_iter=20)
        
# Initialize the GMM means  
classifier.means_ = np.array([X_train[y_train == i].mean(axis=0) 
                              for i in range(num_classes)])
                              
# Train the GMM classifier  
classifier.fit(X_train) 

# Draw boundaries 
plt.figure() 
colors = 'bgr' 
for i, color in enumerate(colors): 
    # Extract eigenvalues and eigenvectors 
    eigenvalues, eigenvectors = np.linalg.eigh( 
            classifier._get_covars()[i][:2, :2]) 
            
    # Normalize the first eigenvector 
    norm_vec = eigenvectors[0] / np.linalg.norm(eigenvectors[0]) 
    
    # Extract the angle of tilt 
    angle = np.arctan2(norm_vec[1], norm_vec[0]) 
    angle = 180 * angle / np.pi  
    
    # Scaling factor to magnify the ellipses 
    # (random value chosen to suit our needs) 
    scaling_factor = 8 
    eigenvalues *= scaling_factor 
    
    # Draw the ellipse 
    ellipse = patches.Ellipse(classifier.means_[i, :2],  
            eigenvalues[0], eigenvalues[1], 180 + angle,  
            color=color) 
    axis_handle = plt.subplot(1, 1, 1) 
    ellipse.set_clip_box(axis_handle.bbox) 
    ellipse.set_alpha(0.6) 
    axis_handle.add_artist(ellipse)
    
# Plot the data  
colors = 'bgr' 
for i, color in enumerate(colors): 
    cur_data = iris.data[iris.target == i] 
    plt.scatter(cur_data[:,0], cur_data[:,1], marker='o',  
            facecolors='none', edgecolors='black', s=40,  
            label=iris.target_names[i]) 
    test_data = X_test[y_test == i] 
    plt.scatter(test_data[:,0], test_data[:,1], marker='s',  
            facecolors='black', edgecolors='black', s=40,  
            label=iris.target_names[i]) 
            
# Compute predictions for training and testing data 
y_train_pred = classifier.predict(X_train) 

accuracy_training = np.mean(y_train_pred.ravel() == y_train.ravel()) * 100 
print('Accuracy on training data =', accuracy_training) 
 
y_test_pred = classifier.predict(X_test) 
accuracy_testing = np.mean(y_test_pred.ravel() == y_test.ravel()) * 100 
print('Accuracy on testing data =', accuracy_testing) 
 
plt.title('GMM classifier') 
plt.xticks(()) 
plt.yticks(()) 
 
plt.show() 

Finding subgroups in stock market using Affinity Propagation model

Segmenting the market based on shopping patterns

profile
오이

0개의 댓글