인공지능 AI
주로 데이터의 패턴과 형태를 분석하는 것이 중요하다.
unsupervied learning은 대표적인 것이 "군집"인데, 다양한 알고리즘을 통해 군집화를 할 수 있다.
ex) K means , density estimation, expectation maximization, parzen window, DBSCAN, 차원 축소
그림의 왼쪽과 같이, 라벨이 없는 데이터의 feature들을 파악하여, 왼쪽과 같은 형태의 cluster를 형성하는 것이 목적이다.
4~5번 과정을 더 이상 centroid가 갱신이 되지 않을 때까지 반복한다.
생각해야할 issue들
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
k = 5 ## 사전에 정해야한다.
kmeans = KMeans(n_clusters=k, random_state=42)
y_pred = kmeans.fit_predict(X)
hard clustering : 하나의 데이터가 정확히 하나의 군집에 할당soft clustering : 하나의 데이터가 다수의 군집에 할당하는 것
K -means의 경우, hard clustering에 해당한다.
모든 데이터가 다수의 clsuter에 중복으로 해당하는 것이 아닌, 단 하나의 cluser에 할당하도록 만든다.
Hard clustering은 특히 "가장 가까운 centroid"선택 : 거리 계산을 해야한다.
kmeans.transform(X_new)
array([[2.81093633, 0.32995317, 2.9042344 , 1.49439034, 2.88633901],
[5.80730058, 2.80290755, 5.84739223, 4.4759332 , 5.84236351],
[1.21475352, 3.29399768, 0.29040966, 1.69136631, 1.71086031],
[0.72581411, 3.21806371, 0.36159148, 1.54808703, 1.21567622]])
4개의 sample(X_new)에 대해, 5개의 군집, 즉 5개의 centroid에 대한 거리 결과물을 저장한다.
이는 "유클리안 거리"를 이용한 것이다.
inertia_ "군집화 이후에, 각 centroid에서 군집 내, 데이터 간의 거리를 합산, 즉 군집의 응집도를 표현"
"작을 수록 응집도가 높게 된 것 이므로, 군집화가 잘 됐다고 할 수 있다."
kmeans.inertia_
211.5985372581684
kmenas.transform :각 데이터의 5개 centroid 별로 거리 값들을 모두 계산한 것들을 반환해준다
X_dist = kmeans.transform(X) ##계산된 centorid와의 거리값들
X_dist ##cluster index 별로 거리들
array([[0.46779778, 3.04611916, 1.45402521, 1.54944305, 0.11146795],
[0.07122059, 3.11541584, 0.99002955, 1.48612753, 0.51431557],
[3.81713488, 1.32016676, 4.09069201, 2.67154781, 3.76340605],
...,
[0.92830156, 3.04886464, 0.06769209, 1.40795651, 1.42865797],
[3.10300136, 0.14895409, 3.05913478, 1.71125 , 3.23385668],
[0.22700281, 2.8625311 , 0.85434589, 1.21678483, 0.67518173]])
score() 매서드는 "큰 값이 좋은 것"이라는 가정이 있기에, 이를 만족하기 위해, 각 sample들의 centroid에 대한 거리들을 모두 음수로 만든다. 즉 거리가 제일 작은 것이 제일 큰 것이 되고, 이를 합산하니 음수로 출력이 된다.
kmeans.score(X)
-211.59853725816836
kmeans_iter1 = KMeans(n_clusters=5, init="random", n_init=1,
algorithm="full", max_iter=1, random_state=0)
kmeans_iter2 = KMeans(n_clusters=5, init="random", n_init=1,
algorithm="full", max_iter=2, random_state=0)
kmeans_iter3 = KMeans(n_clusters=5, init="random", n_init=1,
algorithm="full", max_iter=3, random_state=0)
kmeans_iter1.fit(X)
kmeans_iter2.fit(X)
kmeans_iter3.fit(X)
그림 설명 : 가장 맨 윗줄의 오른쪽이 반복 횟수 1번이다. 두번째 행은 왼쪽이 반복횟수 1번, 오른쪽이 반복횟수 2번이다. 세번째 행은 왼쪽이 반복횟수 2번, 오른쪽이 반복횟수 3번이다.
반복 횟수 1~3으로 갈수록, centroid의 위치도 조정이 되고, 결정경계도 점점 정확해 져가는 것을 관찰할 수 있다.
kmeans_rnd_init1 = KMeans(n_clusters=5, init="random", n_init=1,algorithm="full", random_state=2)
kmeans 클래스의 default 매개변수를 살펴보면 다음과 같다.
init : "random"
kmeans_rnd_init1 = KMeans(n_clusters=5, init="random", n_init=1,
algorithm="full", random_state=2)
kmeans_rnd_init2 = KMeans(n_clusters=5, init="random", n_init=1,
algorithm="full", random_state=5)
초기 centroid를 잡는 방법은 random으로 하기 때문에, random seed가 바뀌면 다른 결과가 나온다.
따라서 random seed를 고정했다고 해서, 그것이 정답이 아닐 수도 있다!!
그렇다면 어떻게 해결해야할까?
해결 방법은 다음과 같이 대표적으로 2가지가 있다.
n_init : 1 이상
n_init이 1 이상이라는 것은 초기 centroid를 무작위로 5개를 뽑는 시도를 여러번 하는 것이다.
여러번 시도 후, 제일 좋은 것의 결과물을 선택한다.
이때는 random_state가 같기에, 최종 결과물이 같게 나오지만,
n_init = 1과 비교했을 때, 더 나은 성능을 보인다.
kmeans_rnd_10_inits = KMeans(n_clusters=5, init="random", n_init=10,
algorithm="full", random_state=2)
kmeans_rnd_10_inits.fit(X)
kmeans_rnd_init1.inertia_
219.43539442771396
kmeans_rnd_10_inits.inertia_
211.5985372581684
실제로 성능이 더 나아진 것을 볼 수 있다.
이번에는 centroid를 단순 무작위로 추출하는 것이 아니라, sample과의 거리를 고려하여
확률적, stochastic한 방법으로 centroid를 추출하는 방법을 사용해보자.
결과적으로, 이전에 선택한 centroid와 거리가 큰 점이 높은 확률로 선택되도록 한다.단순, 랜덤으로 추출한 k개의 centroid는 전체 분포를 고려하지 못하고 몰릴 수 있는 문제를 가지고 있다.
kmeans_rnd_10_inits = KMeans(n_clusters=5, init="k-means++", n_init=10,
algorithm="full", random_state=2)
k 값에 따라 군집되는 정도가 달라지는데, 이는 데이터 분포를 보고 사용자가 정할 수 밖에 없다.
즉, hyperparameter로 tunning의 대상이 된다.
k값에 따른 군집화 비교
앞서 k=5에 비해, k=3은 너무 군집화가 되지 않았고, 8일때는 너무 자세하게 나누어, 굳이 나누지 않아도 될 군집도 나누어졌다.
print("k3_inertia : ",kmeans_k3.inertia_, "|","k8_inertia", kmeans_k8.inertia_)
k3_inertia : 653.216719002155 | k8_inertia 119.11983416102879
단순하게 inertia값만 보면 k 값이 커질 수록, 전체 데이터 분포에 centorid 개수가 증가하는 것이기 때문에,
centroid에 대한 데이터들의 가장 가까운 거리의 합이 감소하기 마련이다.
단순하게 작아지는 inertia만 보고 k값을 정할 수 없다.
작아지는 변화 양항을 관찰해야한다.
Elbow Graph
k = 4일 때가 elbow인데, 이보다 더 커지면 inertia값이 작아지는 기울기가 그리 크지 않다.
이는 k값에 증가에 따른 성능 향상 효과가 효율적이지 않다는 것이다.
눈으로 관찰했을 때는 k = 4가 적당하나, 실제로 데이터 분포를 보면 k = 5가 더 좋은 것 같다.
다른 방법으로 k값을 정해보자
Silhouette coefficient
각 데이터 포인트와 주위 데이터 간의 거리 계산을 통해 얻은 값
centroid와의 거리를 이용한 inertia와 다르게 주위 데이터 분포, 거리를 이용하기에 응집도를 더 구체적으로 표현이 가능하다.
군집 내 비유사성("wthin" dissimilarites)은 작고, 군집 간 비유사성("between" dissimilarities)은 커야 생성된 클러스터의 품질이 좋다고 할 수 있다.
Peter J.Rousseeuw (1987), Silhouettes: a graphical aid to the interpretation and validation of cluster analysis , Computational and Applied Mathematics 20: 53-65
계산 : (b-a)/ max(a,b)
장점 : 군집화 이후에 계수를 구하기에, 군집화 알고리즘에 영향을 받지 않는다.
단점 :
실루엣 계산 자체가 거리들의 평균을 이용하기에 원형 클러스터를 대표할 수 있지만
원형이 아닌 클러스터일 경우, 클러스터에서 가장 멀리 떨어진 데이터에 영향을 받기 쉽다.
but, 이 역시도 cluster 모양이 "원형"이라는 가정에 기반한다.
원형이 아니라면 맞지 않는다.
군집을 사용한 이미지 분활
군집을 사용한 전처리
군집을 사용한 준비지도 학습
[분류 예측 스터디] Faster R-CNN - Towards Real-Time Object Detection with Region Proposal Networks (0) | 2022.05.29 |
---|---|
[분류/예측 스터디] ImageNet Classification with Deep ConvolutionalNeural Networks (0) | 2022.05.29 |
[분류 예측 스터디] 핸즈온 8장 차원축소 (0) | 2022.05.12 |
[분류/예측 스터디] BERT (0) | 2022.05.12 |
[분류 예측 스터디] A Tutorial on Principal Component Analysis (0) | 2022.05.11 |
댓글 영역