머신러닝 알고리즘 : 비지도 학습 본문

파이썬 머신러닝

머신러닝 알고리즘 : 비지도 학습

꼬마곰 2021. 8. 2. 16:00
반응형
비지도 학습은 정답이 없는 상태에서 훈련시키는 방식입니다.
비지도 학습으로는 군집과 차원 축소가 있습니다.

 

1. K-mean ciustering(k-평균 군집화)

군집화는 데이터를 그룹화하고 사용자의 관심분야에 따라 그룹화하여 마케팅에 활용됩니다.

 

평균군집화는 데이터를 받아 소수의 그룹으로 묶습니다.

학습과정으론

 

 1. 중심점 선택 : 랜덤 하게 초기 중심점을 선택합니다.

 2. 클러스터 할당 : 중심점들과 각각의 데이터 간의 거리를 측정한 후 가장 가까운 중심점을 기준으로 데이터를 할당합니다. 이때 클러스터가 구성됩니다.

 3. 새로운 중심점 선택 : 클러스터마다 새로운 중심점을 계산합니다.

 4. 범위확인 : 선택된 중심점에 더 이상의 변화가 없다면 진행을 멈춥니다. 계속 변화한다면 1~3번 과정을 반복합니다.

 

이 있습니다.

 

하지만 상황(비선형데이터, 다른 군집 크기, 밀집도와 다른 거리)에 따라 데이터 분류가 원하는 결과와 다르게 나올 수 있으므로 사용하지 않는 것이 좋습니다.

비선형 데이터

https://www.kaggle.com/binovi/wholesale-customers-data-set

 

Wholesale customers Data Set

Annual spending in monetary units of clients of a wholesale distributor

www.kaggle.com

UCI 고객 데이터셋

 

import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from google.colab import files 
file_uploaded=files.upload()

data = pd.read_csv('Wholesale customers data.csv')
data.head()

categorical_features = ['Channel', 'Region'] 
continuous_features = ['Fresh', 'Milk', 'Grocery', 'Frozen', 'Detergents_Paper', 'Delicassen']
 # 연속형 자료(값이 연속적)
for col in categorical_features:
    dummies = pd.get_dummies(data[col], prefix=col)
    data = pd.concat([data, dummies], axis=1)
    data.drop(col, axis=1, inplace=True)
data.head()

mms = MinMaxScaler() # 데이터 전처리
mms.fit(data)
data_transformed = mms.transform(data)
Sum_of_squared_distances = []
K = range(1,12) # k에 1~12까지 적용
for k in K:
    km = KMeans(n_clusters=k) # 1~12
    km = km.fit(data_transformed) # 모델 훈련
    Sum_of_squared_distances.append(km.inertia_)

plt.plot(K, Sum_of_squared_distances, 'bx-')
plt.xlabel('k')
plt.ylabel('Sum_of_squared_distances')
plt.title('Optimal k')
plt.show()

2. 밀도 기반 군집 분석

데이터의 간소화 하고 데이터 압축, 중요한 속성을 보이는 데 사용됩니다.
사전에 클러스터의 수를 알지 못할 때 사용하면 유용합니다.
이상치가 많이 포함된 데이터에 사용하면 좋습니다.

 

k-mean clustering에 비해 연산량은 많지만 k-mean clustering이 잘 처리하지 못하는 오목하거나 볼록한 부분 처리에 유용하며, 노이즈에 영향을 받지 않습니다.

 

 

Density-Based Spatial Clustering of Applications with Noise, DBSCAB 은 일정 밀도 이상을 가진 데이터를 기준으로 군집을 형성하는 방법입니다.

 

노이즈는 주어진 데이터셋과 무관하거나 무작위성 데이터로 전처리 과정에서 제거해야 합니다. 
이상치는 관측된 데이터 범위에서 많이 벗어난 아주 큰 값이나 아주 작은 값입니다.

 

1단계 : 엡실론 내 점 개수 확인 및 중심점 결정

 - p1이라는 점이 있다고 가정할 때 점 p1에서 거리 엡실론(epsilon) 내에 점이 m(minPts) 개 있으면 하나의 군집으로 인식한다 하였을 때 이때 엡실론 내에 점 m개를 가지고 있는 점 p1을 중심점이라고 합니다.

ex) minPts = 3이라면 점 p1을 중심으로 반경 엡실론 내에 점이 세 개 이상 있으면 하나의 군집으로 판단할 수 있습니다.

 

2단계 : 군집 확장

 - 처음에 새로운 군집을 생성하였고 이번에는 주어진 데이터를 가지고 두 번째 군집을 생성해 보겠습니다. 데이터 밀도 기반으로 군집을 생성하기 때문에 밀도가 높은 지역에서 중심점을 만족하는 데이터가 있다면 그 지역을 포함하여 새로운 군집을 생성합니다. 예를 들어 p1 밑에 점을 중심점 p2로 설정하면 minPis=3을 만족하기 때문에 새로운 군집을 생성할 수 있습니다.

 

군집생성                                                                                           군집확장           

이후 에는 군집 두 개를 군집 하나로 확대합니다.

 

 

군집확대

3단계 : 1 ~ 2단계 반복

 - 데이터가 밀집된 밀도가 높은 지역에서 더 이상 중심점을 정의할 수 없을 때까지 1 ~ 2를 반복 수행합니다.

 

4단계 : 노이즈 정의

 - 데이터가 어떤 군집에도 포함되지 않았다면 노이즈로 정의합니다.

 

3. PCA(principal component analysis, 주성분 분석)

 

데이터의 간소화에 사용됩니다.
특성이 많은 데이터를 2 ~ 3개 정도로 압축해서 데이터를 시각화하여 살펴보고 싶을 때 유 용합 나디.

변수가 많은 고차원 데이터의 경우 중요하지 않은 변수로 처리해야 할 데이터양이 많아지고 성능 또한 나빠지는 경향이 있습니다. 이러한 문제를 해결하고자 고차원 데이터를 저 차원으로 축소시켜 데이터가 가진 대표 특성만 추출한다면 성능은 좋아지고 작업도 좀 더 같편해집니다. 이때 사용하는 대표적인 알고리즘이 PCA입니다. 

 

PCA는 여러 데이터가 모여 하나의 분포를 이룰 때 이 분포의 주성분을 분석하는 방법입니다.

 

https://www.kaggle.com/ecedolen/machine-l-on-credit-card-customer-segmentation/data?select=CC+GENERAL.csv 

 

Machine L. on Credit Card Customer Segmentation

Explore and run machine learning code with Kaggle Notebooks | Using data from Credit Card Dataset for Clustering

www.kaggle.com

데이터 셋 다운로드

 

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 

from sklearn.cluster import DBSCAN 
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import normalize
from sklearn.decomposition import PCA
from google.colab import files 
file_uploaded=files.upload()

df = pd.read_csv('CC GENERAL.csv') 
df = df.drop('CUST_ID', axis = 1) # CUST_ID 열 삭제
df.fillna(method ='ffill', inplace = True) # 결측값을 이전 값들로 채움
print(df.head())

scaler = StandardScaler()
df_scaled = scaler.fit_transform(df) 
# 평균이0, 표준편차가 1이 되도록 데이터 크기를 조정
df_normalized = normalize(df_scaled) 
# 데이터가 가우스 분포를 따르도록 정규화
df_normalized = pd.DataFrame(df_normalized)
# 넘파이 배열을 데이터프레인으로 변환
pca = PCA(n_components = 2)
# 차원축소 = 2차원으로
df_principal = pca.fit_transform(df_normalized)
# 차원축소 적용
df_principal = pd.DataFrame(df_principal) 
df_principal.columns = ['P1', 'P2'] 
print(df_principal.head())

db_default = DBSCAN(eps = 0.042, min_samples = 3).fit(df_principal)
# 모델 생성 및 훈련

labels = db_default.labels_
# 각 데이터 포인트에 할당 된 모든 클러스터 레이블의 넘파이 배열을 labels에 저장​
colours = {} 
colours[0] = 'm'
colours[1] = 'g'
colours[2] = 'r'
colours[-1] = 'k'
  
cvec = [colours[label] for label in labels] # 색상 백터 생성
  
r = plt.scatter(df_principal['P1'], df_principal['P2'], color ='m'); 
g = plt.scatter(df_principal['P1'], df_principal['P2'], color ='g'); 
b = plt.scatter(df_principal['P1'], df_principal['P2'], color ='r'); 

k = plt.scatter(df_principal['P1'], df_principal['P2'], color ='k'); 
#범례구성
  
plt.figure(figsize =(7, 7)) 
plt.scatter(df_principal['P1'], df_principal['P2'], c = cvec) 
# X축에 P1, Y축에 P2 플로딩
  
plt.legend((r, g, b, k), ('Label 0', 'Label 1', 'Label 2', 'Label -1'))
# 범례구축
plt.show()

DBSCAN모델을 실행하여 시각화

출력 결과 클러스터링에 대한 튜닝이 필요해 보입니다.

 

minPts의 하이퍼 파라미터를 50으로 수정한 후 시각화 부분을 수정하겠습니다.

 

db = DBSCAN(eps = 0.042, min_samples = 50).fit(df_principal) 
labels1 = db.labels_

colours1 = {} 
colours1[0] = 'r'
colours1[1] = 'c'
colours1[2] = 'g'
colours1[3] = 'b'
colours1[4] = 'm'
colours1[5] = 'y'
colours1[-1] = 'k'
  
cvec = [colours1[label] for label in labels1] 
colors1 = ['r', 'c', 'g', 'b', 'm', 'y', 'k' ] 
  
r = plt.scatter(
    df_principal['P1'], df_principal['P2'], marker ='o', color = colors1[0]) 
g = plt.scatter( 
    df_principal['P1'], df_principal['P2'], marker ='o', color = colors1[1]) 
b = plt.scatter( 
    df_principal['P1'], df_principal['P2'], marker ='o', color = colors1[2]) 
c = plt.scatter( 
    df_principal['P1'], df_principal['P2'], marker ='o', color = colors1[3]) 
y = plt.scatter( 
    df_principal['P1'], df_principal['P2'], marker ='o', color = colors1[4]) 
m = plt.scatter( 
    df_principal['P1'], df_principal['P2'], marker ='o', color = colors1[5]) 
k = plt.scatter( 
    df_principal['P1'], df_principal['P2'], marker ='o', color = colors1[6]) 
  
plt.figure(figsize =(9, 9)) 
plt.scatter(df_principal['P1'], df_principal['P2'], c = cvec) 
plt.legend((r, g, b, c, y, m, k), 
           ('Label 0', 'Label 1', 'Label 2', 'Label 3', 'Label 4', 'Label 5', 'Label -1'), 
           scatterpoints = 1, 
           loc ='upper left', 
           ncol = 3, 
           fontsize = 8) 
plt.show()

앞 서해 본 코드보다 군집이 잘 표현되었습니다.

 

이처럼 모델에서 하이퍼 파라미터 영향에 따라 클러스터 성능이 달라지므로, 최적의 성능을 내려면 하이퍼 파라미터를 이용한 튜닝이 중요합니다.

반응형