[머신러닝]비지도학습

김태경 SMARCLE·2024년 11월 25일

머신러닝

목록 보기
9/9

핸즈온 9.1챕터 전체

스터디 과제와 네이버 블로그 작성을 동시에 처리하겠다던 내 2학기 계획은 그렇게 처참하게 박살났다.
방학때의 내가 수습하겠지...아마도...

이번주도 스터디 못나감
학술제 때문에 미치겠어요 살려줘요 빨리 완성해버리고 싶어요

https://www.kaggle.com/code/smarcle/taekyung-9
이 와중에 용케 코드는 작성해놨음

9.1 클러스터링

비지도학습에서 가장 중요한 개념이라면 바로 '클러스터'다.
클러스터 = 성질이 비슷한 값들끼리 모여있는 그룹

비지도학습은 이 클러스터를 모델 나름의 기준에 맞춰 만드는게 핵심이다.

k-평균

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

X, y = make_blobs()

k=5
kmeans = KMeans(n_clusters=k, random_state=42)
y_pred = kmeans.fit_predict(X)

kmeans.cluster_centers_

결과는
array([[ -8.26247956, 7.18181112],
[ 6.67852844, 6.63914339],
[-10.15272054, 6.34607844],
[ 3.67942945, 4.16140461],
[ 8.35706346, 7.69708494]])

라고 한다.

k가 찾고자 하는 클러스터 수, 그리고 그 수만큼 클러스터의 중심을 찾아 반환해준 것.

k평균은 원하는 수만큼의 클러스터를 만들고 그 중심을 찾아 결정 경계를 설정한다.

중심을 초기화하면서 성능을 올리기

good_init = np.array([[-3, 3], [-3, 2], [-3, 1], [-1, 2], [0, 2]])
kmeans2 = KMeans(n_clusters = 5, init = good_init, n_init = 1, random_state=42)
kmeans2.fit(X)

미니배치와 속도 개선

from sklearn.cluster import MiniBatchKMeans

mnbt_kmeans = MiniBatchKMeans(n_clusters=5, random_state=42)
mnbt_kmeans.fit(X)

미니배치를 만들어 그것들을 학습시키고 종합하는 방식.

실루엣 스코어

from sklearn.metrics import silhouette_score
silhouette_score(X, kmeans2.labels_)

최선의 클러스터 수를 찾는 지표 중 하나로, 데이터 점마다 -1~1 사이의 값을 할당하는데 이 값이 -1이면 잘못된 클러스터에 가 있다는 뜻.
반대로 1이면 제대로 분류한 것.

한계

교재처럼 타원형 클러스터인 경우 잘 작동하지 않는다.

이미지 분할하기

이 파트는 이미지를 넣지 않고 코드만 작성했다.
filepath에 이미지 경로 넣으면 된다.

import PIL
image = np.asarray(PIL.Image.open(filepath))

X = image.reshape(-1, 3)
kmeans3 = KMeans(n_clusters=8, random_state=42).fit(X)
sgmtd_img = kmeans3.cluster_centers_[kmenas3.labels_]
sgmtd_img = sgmtd_img.reshape(image.shape)

이미지를 원하는 수의 색으로 분할하는 코드.
예를 들어, 여기서 n_clusters가 8이므로 이미지 내 부분을 전체 색 중 총 8가지 색으로 묶는다.

여기서는 색으로 분할했지만, 시맨틱 분할이나 인스턴스 분할도 가능하다고 한다.

준지도 학습

from sklearn.datasets import load_digits
X_digits, y_digits = load_digits(return_X_y=True)
X_train, y_train = X_digits[:1400], y_digits[:1400]
X_test, y_test = X_digits[1400:], y_digits[1400:]

from sklearn.linear_model import LogisticRegression

n_labeled = 50
log_reg = LogisticRegression(max_iter=10_000)
log_reg.fit(X_train[:n_labeled], y_train[:n_labeled])

log_reg.score(X_test, y_test)

k = 50
kmeans4 = KMeans(n_clusters=k, random_state=42)
X_digits_dist = kmeans4.fit_transform(X_train)
rp_digit_idx = np.argmin(X_digits_dist, axis=0)
X_rp_digits = X_train[rp_digit_idx]
y_rp_digits = np.array([
    1, 3, 6, 0, 7, 9, 2, 4, 8, 9,
    5, 4, 7, 1, 2, 6, 1, 2, 5, 1,
    4, 1, 3, 3, 8, 8, 2, 5, 6, 9,
    1, 4, 0, 6, 8, 3, 4, 6, 7, 2,
    4, 1, 0, 7, 5, 1, 9, 9, 3, 7
])

log_reg2 = LogisticRegression(max_iter=10_000)
log_reg2.fit(X_rp_digits, y_rp_digits)
log_reg2.score(X_test, y_test)

첫 번째 log_reg는 0.7481108312342569, 두번째 log_reg2는 0.8488664987405542로 점수가 나온다.

일부 데이터에 대해서만 레이블이 있는 경우를 만든 것으로, 저 50개만 레이블을 붙였을 때 나머지에 대해 비지도학습으로 레이블을 붙인 것.

1번은 앞 50개에 대해 레이블이 존재하고, 2번은 각 클러스터의 중심 데이터 50개에 대해 레이블이 붙은 것이다.
2번의 데이터를 대표 이미지라고 칭하며, 이것만 넣고 돌려도 성능이 높아지는 것을 볼 수 있다.

DBSCAN

간단하게, 빠르게 쓸 수 있는 비지도학습 모델.
특히나 각각의 클러스터가 클러스터가 아닌 지역과 잘 구분될 경우 탁월하다.

from sklearn.cluster import DBSCAN
from sklearn.datasets import make_moons

X, y = make_moons(n_samples=1000, noise=0.05)
dbscan = DBSCAN(eps=0.05, min_samples=5)
dbscan.fit(X)

from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier(n_neighbors=50)
knn.fit(dbscan.components_, dbscan.labels_[dbscan.core_sample_indices_])

X_new2 = np.array([[-0.5, 0], [0, 0.5], [1, -0.1], [2, 1]])
knn.predict(X_new2)

knn.predict_proba(X_new2)

X_new2에 대한 결과는 array([2, 1, 0, 4]).

기타

  • 병합 군집
    클러스터 계층을 밑바닥부터 쌓아올라가는 특징을 가지는 알고리즘.

  • BIRCH
    컬럼 수가 적고 데이터량이 많은 경우에 특화되어있으며, 훈련 과정에서 샘플들을 트리로 분류해 사용한다.

  • 평균 - 이동
    각 샘플별로 원을 그려서 그 원 안에 있는 샘플들의 평균을 구하고 그곳으로 중심을 이동하는 방식의 알고리즘.
    모든 원이 움직이지 않으면 작동 완료.

  • 유사도 전파
    모든 샘플에 대해 자신을 대표할 다른 샘플을 선택하는 방식.
    이렇게 선출된 샘플과 그걸 선출한 다른 샘플들이 클러스터로 묶인다.

  • 스펙트럼 군집
    샘플 사이의 유사도 행렬을 받아 저차원 임베딩을 만드는 알고리즘.

대충 이런 것들이 있다고 한다.
나중에 한번 코드 찾아봐도 재밌을듯.

스터디 후기

2학기에 다들 바쁘기도 하고, 이런저런 일이 많아 페어프로그래밍도 4회(나는 더 바빠서 2회)밖에 못 해봤지만 그래도 머신러닝 개념을 좀 근본부터 배울 수 있었던 스터디였다.

사실 여름에 핸즈온으로 미리 한번 스터디를 돌려봤는데, 그때는 앙상블까지만 해서 비지도학습까지는 이번에 새로 하는데 꽤나 재밌었다.
나중에 velog에 쓴 내용들 기반으로 더 자세히 조사해 새로 글 쓰거나 사용해봐도 괜찮을듯.

모르겠고 빨리 종강하면 좋겠어요 자고 싶어요 흑흑

profile
네이버 블로그 업로드 전 개념정리용

0개의 댓글