Day39 - 머신러닝(10). 22.10.21.금

류소리·2022년 10월 20일
0

머신러닝

목록 보기
10/14

: int,float
: 범주형


-> o p359


LDA 개요

LDA(Linear Discriminant Analysis)는 선형 판별법으로 불리며, PCA와 매우 유사하게 입력 dataset를 저차원 공간에 투영하여 차원을 축소하는 기법이지만, 중요한 차이는 LDA는 지도학습의 분류(Classification)에서 사용하기 쉽도록 개별 클래스를 분별할 수 있는 기준을 최대한 유지하면서 차원을 축소한다.

즉, PCA는 입력 데이터의 변동성의 가장 큰 축을 찾았지만, LDA는 입력 데이터의 결정 값 클래스를 최대한 분리할 수 있는 축을 찾는다.

LDA는 특정 공간상에서 틀래스 분리를 최대화하는 축을 찾기 위해 클래스 간 분산(between-class scatter)과 클래스 내부 분산(width-class scatter)의 비율을 최대화하는 방식으로 차원을 축소한다.

즉, 클래스간 분산은 최대한 크게 가져가고, 클래스 내부의 분산은 최대한 작게 가져가는 방식이다.

일반적으로 LDA를 구하는 스텝은 PCA와 유사하지만 가장 큰 차이는 공분산 행렬이 아닌 클래스간 분산과 클래스 내부 분산 행렬을 생성한 뒤, 이 행렬에 기반해 교유벡터를 구하고 입력 데이터를 투영한다는 점이다.

사이킷런의 LDA를 이용해 변환하고, 그 결과를 품종별로 시각화해 보겠다.

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris

iris = load_iris()
iris_scaled = StandardScaler().fit_transform(iris.data)

lda = LinearDiscriminantAnalysis(n_components=2)
lda.fit(iris_scaled, iris.target)
iris_lda = lda.transform(iris_scaled)

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

lda_columns=['lda_component_1','lda_component_2']
irisDF_lda = pd.DataFrame(iris_lda,columns=lda_columns)
irisDF_lda['target']=iris.target

#setosa는 세모, versicolor는 네모, virginica는 동그라미로 표현
markers=['^', 's', 'o']

#setosa의 target 값은 0, versicolor는 1, virginica는 2. 각 target 별로 다른 shape으로 scatter plot
for i, marker in enumerate(markers):
    x_axis_data = irisDF_lda[irisDF_lda['target']==i]['lda_component_1']
    y_axis_data = irisDF_lda[irisDF_lda['target']==i]['lda_component_2']

    plt.scatter(x_axis_data, y_axis_data, marker=marker,label=iris.target_names[i])

plt.legend(loc='upper right')
plt.xlabel('lda_component_1')
plt.ylabel('lda_component_2')
plt.show()

사이킷런 TruncatedSVD 클래스를 이용한 변환 p424

사이킷런의 TruncatedSVD 클래스는 PCA 클래스와 유사하게 fit()과 transform()을 호출해 몇 개의 주요 component로 차원을 축소하여 변환한다. iris dataset을 이용하여 변환해 보겠다.

from sklearn.decomposition import TruncatedSVD
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
%matplotlib inline

iris = load_iris()
iris_ftrs = iris.data
# 2개의 주요 component로 TruncatedSVD 변환
tsvd = TruncatedSVD(n_components=2)
tsvd.fit(iris_ftrs)
iris_tsvd = tsvd.transform(iris_ftrs)

# Scatter plot 2차원으로 TruncatedSVD 변환 된 데이터 표현. 품종은 색깔로 구분
plt.scatter(x=iris_tsvd[:,0], y= iris_tsvd[:,1], c= iris.target)
plt.xlabel('TruncatedSVD Component 1')
plt.ylabel('TruncatedSVD Component 2')

  • TruncatedSVD로 변환된 iris dataset도 PCA의 경우와 유사하게 변환되며 어느 정도 클러스터링이 가능할 정도로 각 변환되었다. 이번엔 스케일링을 한 뒤에 TruncatedSVD와 PCA 변환을 비교해보겠다.
from sklearn.preprocessing import StandardScaler

# iris 데이터를 StandardScaler로 변환
scaler = StandardScaler()
iris_scaled = scaler.fit_transform(iris_ftrs)

# 스케일링된 데이터를 기반으로 TruncatedSVD 변환 수행 
tsvd = TruncatedSVD(n_components=2)
tsvd.fit(iris_scaled)
iris_tsvd = tsvd.transform(iris_scaled)

# 스케일링된 데이터를 기반으로 PCA 변환 수행 
pca = PCA(n_components=2)
pca.fit(iris_scaled)
iris_pca = pca.transform(iris_scaled)

# TruncatedSVD 변환 데이터를 왼쪽에, PCA변환 데이터를 오른쪽에 표현 
fig, (ax1, ax2) = plt.subplots(figsize=(9,4), ncols=2)
ax1.scatter(x=iris_tsvd[:,0], y= iris_tsvd[:,1], c= iris.target)
ax2.scatter(x=iris_pca[:,0], y= iris_pca[:,1], c= iris.target)
ax1.set_title('Truncated SVD Transformed')
ax2.set_title('PCA Transformed')

print((iris_pca - iris_tsvd).mean())
print((pca.components_ - tsvd.components_).mean())

  • n_components의 설정에 따라 차원수가 다르게 분해되며, Truncated SVD로 분해할 경우 완벽하지 않고 근사적으로 복원되는 것을 볼 수 있다.
  • 결과적으로 두 변환 방법이 서로 동일한 것을 알 수 있다. 즉, 스케일링을 통해 데이터의 중심이 동일해지면 SVD와 PCA는 동일한 변환을 수행한다.
    이는 PCA가 SVD 기반의 알고리즘이기 떄문이다.
    하지만 PCA는 밀집 행렬(Dense Matrix)에 대한 변환만 가능하며, SVD는 희소 행렬(Sparse Matrix)에 대한 변환도 가능하다.
    희소 행렬은 값의 대부분이 0으로 이루어진 행렬을 말한다.

SVD는 PCA와 유사하게 컴퓨터 비전 영역에서 이미지 압축을 통한 패턴 인식과 신호 처리 분야에 사용된다.
또한 텍스트의 토픽 모델링 기법인 LSA(Latent Semantic Analysis)의 기반 알고리즘이다.


군집화 p431

K-평균 알고리즘 (K-Means Clustering)

: 데이터 내에 숨어있는 패턴, 그룹을 파악하여 서로 묶는 것이라고 할 수 있다.

  • K-평균은 군집화(Clustering)에서 가장 일반적으로 사용되는 알고리즘이다.
  • K-평균은 군집 중심점(centroid)이라는 특정한 임의의 지점을 선택해 해당 중심에 가장 가까운 포인트들을 선택하는 군집화 기법이다.
  • 군집 중심점은 선택된 포인트의 평균 지점으로 이동하고 이동된 중심점에서 다시 가까운 포인트를 선택, 다시 중심점을 평균 지점으로 이동하는 프로세스를 반복적으로 수행한다.
  • 모든 데이터 포인트에서 더이상 중심점의 이동이 없을 경우에 반복을 멈추고 해당 중심점에 속하는 데이터 포인트들을 군집화하는 기법이다.

<K-평균>

    1. 먼저, 군집화의 기준이 되는 중심을 구성하려는 군집화 개수만큼 임의의 위치에 가져다 놓는다.
    • 전체 데이터를 2개로 군집화하려면 2개의 중심을 임의의 위치에 가져다 놓는 것이다.
    • 임의의 위치에 군집 중심점을 가져다 놓으면 반복적인 이동 수행을 너무 많이 해서 수행 시간이 오래 걸리기 때문에 초기화 알고리즘으로 적합한 위치에 중심점을 가져다 놓지만, 여기서는 설명을 위해 임의의 위치로 가정한다.
    1. 각 데이터는 가장 가까운 곳에 위치한 중심점에 소속된다.
    1. 이렇게 소속이 결정되면 군집 중심점을 소속된 데이터의 평균 중심으로 이동한다.
    1. 중심점이 이동했기 때문에 각 데이터는 기존에 속한 중심점보다 더 가까운 중심적이 있다면 해당 중심점으로 다시 소속을 변경한다.
    1. 다시 중심을 소속된 데이터의 평균 중심으로 이동한다.
    1. 중심점을 이동했는데 데이터의 중심점 소속 변경이 없으면 군집화를 종료한다.
    • 그렇지 않다면 다시 4번 과정을 거쳐서 소속을 변경하고 이 과정을 반복한다.

<그림 설명>

https://blog.mathpresso.com/mathpresso-%EB%A8%B8%EC%8B%A0-%EB%9F%AC%EB%8B%9D-%EC%8A%A4%ED%84%B0%EB%94%94-9-%EA%B5%B0%EC%A7%91%ED%99%94-clustering-542390bb4b74

<K-평균의 장점>

  • 일반적인 군집화에서 가장 많이 활용되는 알고리즘이다.
  • 알고리즘이 쉽고 간결하다.

<K-평균의 단점>

  • 거리 기반 알고리즘으로 속성의 개수가 매우 많을 경우 군집화 정확도가 떨어진다. 이를 위해 PCA로 차원 감소를 적용해야 할 수도 있다.
  • 반복을 수행하는데, 반복 횟수가 많을 경우 수행시간이 매우 느려진다.
  • 몇 개의 군집(cluster)을 선택해야 할지 가이드하기가 어렵다.

K-평균을 이용한 iris dataset 군집화

  • iris dataset을 이용하여 K-평균 군집화를 해보겠다. sepal length와 petal length에 따라 각 데이터의 군집화가 어떻게 결정되는지 확인해 보고, 분류 값과 비교해 보겠다.
  • 3개 그룹으로 군집화하기 위해 n_cluster는 3, 초기 중심 설정 방식은 defalut 값인 k-means++, 최대 반복 횟수도 defalut 값인 max_iter=300으로 설정하여 KMeans 객체를 만들어 수행해보겠다.
## p433

from sklearn.preprocessing import scale
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
import numpy as np
import pandas as pd


iris = load_iris()

# 보다 편리한 데이터 Handling을 위해 DataFrame으로 변환
irisDF = pd.DataFrame(data=iris.data, columns=['sepal_length','sepal_width','petal_length','petal_width'])
#irisDF.head(3)

# 3개를 군집화 해보겠다.
# n_clusters=3 : 3군집
# init='k-means++' : 초기중심설정 방식 , 디폴트값
# max_iter=300 : 최대 반복 횟수 , 디폴트값
kmeans = KMeans(n_clusters=3, init='k-means++', max_iter=300,random_state=0)
kmeans.fit(irisDF)
print(kmeans.labels_)

# PCA를 가져와 군집을 줄여줍시다.
from sklearn.decomposition import PCA

# 2개로 줄일것이다.
pca = PCA(n_components=2)
pca_transformed = pca.fit_transform(iris.data)
pca_transformed

kmeans = KMeans(n_clusters=3, init='k-means++', max_iter=300,random_state=0)
kmeans.fit(pca_transformed)
print(kmeans.labels_)


군집평가 p441

  • iris dataset의 target과 군집화 결과를 비교하여 군집화가 얼마나 효율적으로 됬는지 확인하였다.
  • 하지만 대부분의 군집화 dataset은 target label을 가지고 있지 않으며, 군집화는 분류와 유사해 보일 수 있으나 성격이 많이 다르다.
  • 데이터 내의 숨어 있는 별도의 그룹을 찾아서 의미를 부여하거나 동일한 분류 값에 속하더라도 그 안에서 더 세분화된 군집화를 추구하거나 서로 다른 분류 값의 데이터도 더 넓은 군집화 레벨화 등의 영역을 가지고 있다.
  • 따라서 군집화를 평가하는 지표로는 label을 사용하지 않으며, 실루엣 분석이라는 방법을 대표적으로 사용한다.

실루엣 분석의 개요 p442

  • 군집화 평가 방법 중 하나인 실루엣 분석은 각 군집 간의 거리가 얼마나 효율적으로 분리돼 있는지를 나타낸다.

  • 여기서 효율적으로 분리되어 있다는 것은 다른 군집과의 거리는 떨어져 있고 동일 군집끼리의 데이터는 서로 가깝게 잘 뭉쳐 있다는 의미이다.

  • 실루엣 분석은 실루엣 계수(silhouette coefficient)를 기반으로 하고, 개별 데이터가 가지는 군집화 지표이다.

  • 개별 데이터가 가지는 실루엣 계수는 해당 데이터가 같은 군집 내의 데이터와 얼마나 가깝게 군집화돼 있고, 다른 군집에 있는 데이터와는 얼마나 멀리 분리돼 있는지를 나타내는 지표이다.

  • 특정 데이터 포인트의 실루엣 계수 값은 해당 데이터 포인트와 같은 군집 내에 있는 다른 데이터 포인트와의 거리를 평균한 값 a(i),

  • 해당 데이터 포인트가 속하지 않은 군집 중 가장 가까운 군집과의 평균 거리 b(i)를 기반으로 계산된다.

  • 두 군집 간의 거리는 b(i) - a(i)이며 이 값을 정규화하기 위해 MAX(a(i), b(i)) 로 나눈다.

  • 이렇게 i번째 데이터 포인트의 실루엣 계수 값 s(i)를 계산한다.

  • i: 각 데이터 포인트에 대한 인덱스
  • si: 실루엣 계수
  • ai: 해당 데이터 포인트와 같은 군집 내에 있는 다른 데이터 포인트와의 거리를 평균한 값
  • bi: 해당 데이터 포인트가 속하지 않은 군집 내에 있는 데이터 포인트와의 거리를 군집 별로 평균을 낸 후, 그 중 작은 값 (해당 데이터 포인트와 평균적으로 가장 가까운 군집과의 거리)

  • 실루엣 계수는 -1에서 1 사이의 값을 가지며, 1로 가까워질수록 근처 군집과 더 멀리 떨어져 있는 것이고 0에 가까워질수록 근처 군집과 가까운 것이다.
    • 값은 아예 다른 군집에 데이터 포인트가 할당된 것을 의미한다.
  • 실루엣 분석은 각 군집 간의 거리가 얼마나 효율적으로 분리돼 있는지를 나타낸다. 여기서 "효율"은 다른 군집과의 거리는 떨어져 있고 동일 군집 간의 데이터는 서로 가깝게 잘 뭉쳐있음을 의미한다. 군집화가 잘 될수록 군집 내의 거리는 가깝고, 군집 간의 거리는 멀 것이다.

  • 실루엣 분석은 실루엣 계수(silhouette coefficient)를 기반으로 하는데, 개별 데이터는 각각 실루엣 계수를 가진다. 이때 개별 데이터가 가지는 실루엣 계수는 해당 데이터가 같은 군집 내의 데이터와 얼마나 가깝게 군집화되어 있고, 다른 군집에 있는 데이터와는 얼마나 멀리 분리되어 있는지를 나타내는 지표이다.

< 사이킷런은 이러한 실루엣 분석을 위해 제공하는 method가 있다. > p443

  • sklearn.metrics.silhouette_samples(X, labels, ...) : 각 데이터 포인트의 실루엣 계수를 계산해 반환.

  • sklearn.metrics.silhouette_score(X, labels, ...) : 전체 데이터의 실루엣 계수 값을 평균해 반환. np.mean(silhouette_samples())와 동일.
    일반적으로 높은 silhouette_score를 가질수록 군집화가 잘되었다고 판단 가능하나 보장되는 것은 아니다.

<일반적으로 좋은 군집화가 되기 위한 조건으로 제시하는 것>

  • 전체 실루엣 계수의 평균값이 0~1사이의 값을 가지며, 1에 가까울 수록 좋음.
  • 전체 실루엣 계수의 평균값과 더불어, 개별 군집의 실루엣 계수 평균값의 편차가 크지 않아야 함.
    즉, 개별 군집의 실루엣 계수 평균값이 전체 실루엣 계수의 평균값에서 크게 벗어나지 않는 것이 중요함.
    만약 전체 실루엣 계수의 평균값은 높지만, 특정 군집의 실루엣 계수 평균값만 유난히 높고 나머지 군집의 실루엣 계수 평균값이 낮다면 좋은 군집화라고 할 수 없을 것. (평균의 역설을 생각해보자)

from sklearn.metrics import silhouette_samples, silhouette_score

iris = load_iris()
kmeans = KMeans(n_clusters= 2, init="k-means++", max_iter= 300, random_state= 0)
kmeans.fit(iris.data)

# kmeans.labels_

# silhouette_score(iris.data, kmeans.labels_)

# silhouette_samples(iris.data, kmeans.labels_)


elbow 효과

  • k-평균 군집 분석 결저방법 중,
    : 군집내에서 얼마나 밀집되어있는지를 나타내는지 통계량의 합을 기준으로 크기 변화 작아지는 지점.
    -> elbow 효과

군집화 알고리즘 테스트르 위한 데이터 생성 p437,make_blobs

from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples= 200, n_features= 2, centers= 3, cluster_std= .8, random_state= 0)
sns.scatterplot(x = X[:,0], y = X[:,1])


평균 이동의 개요 p449

평균 이동(Mean Shift)은 K-평균과 유사하게 중심을 군집의 중심으로 지속적으로 움직이면서 군집화를 수행한다.

하지만 K-평균이 중심에 소속된 데이터의 평균 거리 중심으로 이동하는 데 반해, 평균 이동은 중심을 데이터가 모여 있는 밀도가 가장 높은 곳으로 이동시킨다.

평균 이동 군집화는 데이터의 분포도를 이용하여 군집 중심적을 찾는다. 군집 중심점은 데이터 포인트가 모여있는 곳이라는 생각에서 착안한 것이며 이를 위해 확률 밀도 함수(probability density function)를 이용한다.

가장 집중적으로 데이터가 모여있어 확률 밀도 함수가 피크인 점을 군집 중심점으로 선정하며 일반적으로 주어진 모델의 확률 밀도 함수를 찾기 위해서 KDE(Kernel Density Estimation)를 이용한다.

KDE(Kernel Density Estimation)는 Kernal 함수를 통해 어떤 변수의 확률 밀도 함수를 추정하는 대표적인 방법이다.
관측된 데이터 각각에 커널 함수를 적용한 값을 모두 더한 뒤 데이터 건수로 나눠 확률 밀도 함수를 추정한다.

확률 밀도 함수 PDF는 확률 변수의 분포를 나타내는 함수로, 널리 알려진 정규분포 함수를 포함하여 감마 분포, t-분포 등이 있으며 대표적으로 가우시안 분포 함수를 사용한다.

확률 밀도 함수를 알면 특정 변수가 어떤 값을 갖게 될지에 대한 확률을 알게 되므로 이를 통해 변수의 특성, 확률 분포 등 변수의 많은 요소를 알 수 있다.

  • K는 커널 함수,
  • x는 확률 변수값,
  • xi는 관측값,
  • h는 대역폭(bandwidth)이다.

대역폭 h는 KDE 형태를 부드러운 형태로 평활화(Smoothing)하는 데 적용되며, 이 h를 어떻게 설정하느냐에 따라 확률 밀도 추정 성능을 크게 좌우할 수 있다.

아래 그림은 h를 작은 값에서 큰 값으로 증가하면서 KDE가 어떻게 변화하는지 본 것이다.
h가 작을 경우엔 좁고 뾰족한 KDE를 가지게 되며, 이는 변동성이 큰 방식으로 확률 밀도 함수를 추정하므로 과적합(over-fitting)하기 쉽다.

반대로 매우 큰 h값은 과도하게 smoothing 된 KDE로 인해 지나치게 단순화된 방식으로 확률 밀도 함수를 추정하며 결과적으로 과소적합(under-fitting)하기 쉽다.

따라서 적절한 KDE의 대역폭 h를 계산하는 것은 KDE 기반의 평균 이동(Mean Shift) 군집화에서 매우 중요하다.

평균 이동 군집화는 대역폭 설정에 따라 군집 중심정의 개수가 달라지며, 따로 개수를 지정하지 않는다.
사이킷런은 평균 이동 군집화를 위해 MeanShift 클래스를 제공한다.

대역폭 크기 설정이 군집화의 품질에 큰 영향을 미치기 때문에 사이킷런은 최적의 대역폭 계산을 위해 estimate_bandwidth() 함수를 제공한다.

make_blobs()로 3개의 군집 데이터를 만든 후 bandwidth에 따라 군집을 생성해보겠다.

import numpy as np

bandwidth가 0.8로 작게 설정되었을 경우 6개의 군집으로 분류되었지만 1로 설정하자 3개의 군집으로 잘 군집화되었다.

from sklearn.cluster import estimate_bandwidth

bandwidth = estimate_bandwidth(X)
print('bandwidth 값:', round(bandwidth,3))

DBSCAN 개요

DBSCAN(Density Based Spatial Clustering of Applications with Noise)는 밀도 기반 군집화의 대표적인 알고리즘이다. DBSCAN은 간단하고 직관적인 알고리즘임에도 데이터의 분포가 기하학적으로 복잡한 dataset에도 효과적인 군집화가 가능하다.

DBSCAN을 구성하는 가장 중요한 파라미터는 epsilon으로 표기하는 주변 영역과 이 입실론 주변 영역에 포함되는 최소 데이터의 개수 min points이다. 입실론 주변 영역 내에 포함되는 최소 데이터 개수를 충족시키는지 아닌지에 따라 데이터 포인트를 구분하여 정의한다.

  • 핵심 포인트(Core Point) : 주변 영역 내에 최소 데이터 개수 이상의 타 데이터를 가지고 있을 경우 해당 데이터를 핵심 포인트라고 한다.
  • 이웃 포인트(Neighbor Point) : 주변 영역 내에 위치한 타 데이터를 이웃 포인트라고 한다.
  • 경계 포인트(Border Point) : 주변 영역 내에 최소 데이터 개수 이상의 이웃 포인트를 가지고 있지 않지만 핵심 포인트를 이웃 포인트로 가지고 있는 데이터를 경계 포인트라고 한다.
  • 잡음 포인트(Noise Point) : 최소 데이터 개수 이상의 이웃 포인트를 가지고 있지 않으며, 핵심 포인트도 이웃 포인트로 가지고 있지 않는 데이터를 잡음 포인트라고 한다.

  • 특정 입실론 반경 내에 포함될 최소 dataset를 정한다.
  • 데이터들을 하나씩 입실론 반경 내에 포한된 데이터가 min points 이상인지 확인하고 해당되면 core point로 정한다.
  • core point의 반경 내의 이웃 포인트가 core point일 경우 서로 직접 연결이 가능하며, 하나의 군집으로 구성할 수 있다.
  • 그 다음 나머지 포인트들 중 경계 포인트와 잡읍 포인트를 정한다.
  • DBSCAN을 적용할 떄는 특정 군집 개수로 군집을 강제하지 않고 적절한 eps과 min_samples 파라미터를 통해 최적의 군집을 찾는 것이 중요하다.

  • 그리고 일반적으로 eps의 값을 크게 하면 반경이 커져 포함하는 데이터가 많아지므로 노이즈 데이터 개수가 작아지고, min_samples를 크게 하면 주어진 반경 내에서 더 많은 데이터를 포함시켜야 하므로 노이즈 데이터 개수가 커지게 된다.


DBSCAN 적용하기 - make_circles() dataset

이번엔 make_circles() 함수를 이용하여 내부 원과 외부 원 형태로 되어 있는 2차원 dataset을 만들어보겠다.

from sklearn.datasets import make_circles

X, y = make_circles(n_samples=1000, shuffle=True, noise=0.05, random_state=0, factor=0.5)
clusterDF = pd.DataFrame(data=X, columns=['ftr1', 'ftr2'])
clusterDF['target'] = y

visualize_cluster_plot(None, clusterDF, 'target', iscenter=False)

그 다음 K-평균과 GMM, DBSCAN이 어떻게 이 dataset을 군집화하는지 확인해보겠다.

# KMeans로 make_circles( ) 데이터 셋을 클러스터링 수행. 
from sklearn.cluster import KMeans

kmeans = KMeans(n_clusters=2, max_iter=1000, random_state=0)
kmeans_labels = kmeans.fit_predict(X)
clusterDF['kmeans_cluster'] = kmeans_labels

visualize_cluster_plot(kmeans, clusterDF, 'kmeans_cluster', iscenter=True)

K-평균은 위와 아래로 반반씩 군집화하였다. 거리 기반의 군집화로는 데이터가 특정 형태로 지속해서 이어지는 부분을 찾아내기 어렵다.

# GMM으로 make_circles( ) 데이터 셋을 클러스터링 수행. 
from sklearn.mixture import GaussianMixture

gmm = GaussianMixture(n_components=2, random_state=0)
gmm_label = gmm.fit(X).predict(X)
clusterDF['gmm_cluster'] = gmm_label

visualize_cluster_plot(gmm, clusterDF, 'gmm_cluster', iscenter=False)

GMM도 일렬로 늘어선 dataset에서는 효과적으로 군집화 적용이 가능했으나, 내부와 외부의 원형으로 구성된 더 복잡한 형태의 dataset에서는 군집화가 원하는 방향으로 되지 않는다.

# DBSCAN으로 make_circles( ) 데이터 셋을 클러스터링 수행. 
from sklearn.cluster import DBSCAN

dbscan = DBSCAN(eps=0.2, min_samples=10, metric='euclidean')
dbscan_labels = dbscan.fit_predict(X)
clusterDF['dbscan_cluster'] = dbscan_labels

visualize_cluster_plot(dbscan, clusterDF, 'dbscan_cluster', iscenter=False)

  • DBSCAN으로 군집화를 적용해 원하는 방향으로 정확히 군집화가 된 것을 알 수 있다.

출처:

profile
새싹 빅테이터 개발자

0개의 댓글