-
#13 : KT_AIVLE_SCHOOL : DX_4th : 7주차 : 머신러닝-비지도학습KT_AIVLE_SCHOOL_DX_4th 2023. 9. 24. 23:33
지난 시간에는 머신러닝 지도학습에 대해 배웠다 (https://datawithu.tistory.com/23)
이번에는 2일 동안 머신러닝 비지도학습에 대해 배운다.
교육은 한기영강사님이 진행해주셨다.
비지도학습은 지도학습과는 다른부분은 정답이 주어지지 않은 채로 학습을 한다 것이다.
또한 비지도학습의 경우 후속작업들이 필요하다
- 1일차 : 차원축소 후에는 시각화, 지도학습으로 연계를 하거나
- 2일차 : 클러스터링 (군집)후에는 각 군집의 특성을 도출하기 위한 추가분석
- 2일차 : 이상탐지에서는 어떤 범위를 이상치로 판정할 것인지
# Intro 강의을 들으면서의 고민
우선 나는 비지도학습에 대해서는 말로는 안다고 자부했었다.
실제로도 Kmeans의 경우 한두어번은 써보았던 기억은 있었다.
그러나, 인간의 기억은 (그게 장기기억이든, 단기기억이든) 꺼내보지 않으면 사라지다는 것을
또 망각하던 나를 발견 !!!했고,
내가 아는 것이 오로지 '단어' 밖에 없었을 때, 상당히 당혹스러웠다.
그래서, 강의에서 살짝 아쉬운 부분들이 있었는데,
강의 일수가 2일정도여서,,, 비지도학습에 대해 살짝 맛소금정도 뿌린 느낌이었다.
이게 왜 아쉽냐면, 8월 강의를 듣기 시작했을때는 "와 6개월이나 해야한다고" 였는데
막상 들어보니, 너무 일수가 부족하다는 것을 체감 할 수 밖에 없었다.
알아야 할 부분 多 + 학습해야할 분량 多 + 강의력이 좋음(진짜임..)이 섞여서 그렇다.
한편으로 이번강의에서 좋았던 부분은,
한기영 강사님은 상당히 복습을 많이 해주신다. 시작할 때와 마무리 할 때,
덕분에 매번 아 그랬지 하는 부분이 상기되어서 참 좋다.
무엇보다 기억에 남고, 가끔 아 강사님이 이부분 주의하랬지 떠오르기 때문이다.
비지도학습에서 차원축소를 한다는 말이 처음에는 무슨 의미인지 와닿지 않았다.
왜냐하면, 오직 책으로만 공부를 했던 부분이었고, 차원을 줄인다는게 내가 생각는 '그' 차원일까도 있었고
데이터의 차원이라는 것이 무엇인지 다시 고민하기도 했었다.
주성분 분석이나, t-SNE는 낯설었지만, 의외로 괜찮았다.
그러나, 여전히 isolation_forest는 어렵다.
한기영 강사님이 시각화 과정을 보여주셨는데 음... 모르겠어서 지금도 고민중이다.
1. 차원축소
차원을 축소한다는 것은 최대한 특성을 살리면서 고차원->저차원으로 바꾸는것이다
주로 시각화와 지도학습을 연계하는 방식으로 후속작업을 한다.
- PCA:주성분 분석의 경우
- 고차원의 특징-분산을 최대한 유지하면서 차원을 저차원으로
- 비선형방식
- 스케일링 필요
- 단, 저차원의 특징을 잘 담아내지 못함 => tSNE를 사용
- t-SNE의 경우
- 고차원의 특징- 유사도맵(점들의 거리의 비)을 최대한 유지하면서 2-3로 축소
- 비선형방식
- 스케일링 권장
- 학습 시간이 오래걸림
1-1) 주성분분석 PCA
- PCA : principal Component Analysis
- PCA는 고차원의 데이터를 저차원으로 줄이는 것이다.
- 방법은 수학에서 공간을 압축하는 방식을 생각해보면된다.
- => N차원을 N-1차원 평면으로 압축할때의 점들과의 직교거리들의 분산이 유지되겠끔
불러오는 코드는 다음과 같다.
from sklearn.preprocessing import StandardScaler, MinMaxScaler # 스케일링 처리하기 #주성분 분석 from sklearn.decomposition import PCA pca = PCA(n_components= n ) # n은 최대 feature수 많큼할 수 있다. => tsne경우는 2-3만 됨 # fit & transform x_train_pc = pca.fit_transform(x_train) #fit은 x_train만하기 x_val_pc = pca.transform(x_val) ##결과는 numpy array
문제는 주성분의 개수가 몇 개일때가 원본 데이터의 분산 특성을 잘 유지하는 것인가 인데??
이때는 시각화를 하여, Elbow Method를 사용한다 => 그래프에서 팔쿰치같은 모양이 보이는 부근에서 결정
# import matplotlib.pyplot as plt pca_n = pca .explained_variance_ ratio_ # 뒤에 붙은 _ 언더바는 값을 의미한다고 한다 ! #시각화 plt.plot( range(1, n+1), pca_n, marker='*') plt.xlabel('주성분 갯수') plt.grid() plt.show()
위의 시각화를 하면 아래와 같은 형태로 나타나는데
요기서 급격하게 굽혀진 부근에서 주성분의 갯수를 정하면된다.
1-2) T-SNE
- 여기서 t는 t분포를 말하며,
- 유클리드 거리계산하고, T-분포로 유사도를 계산한후, 유사도 맵을 만들고
- 그걸 저차원에서 유사도 맵들간의 오차를 계산하여 조정하면서 유사도 맵을 만는 방식이다.
#스케일링 권장 from sklearn.preprocessing import StandardScaler, MinMaxScaler #t-sne 불러오기 fromsklearn.manifold import TSNE # 2차원으로 축소하기: 보통 2-3으로만 축소한다 기억하기 tsne = TSNE(n_components =2 ) x_tsne = tsne.fit_transform(x)
2.클러스터링 / 군집분석
- k-means 는
- 주로 옹기종이 모여있는 덩어리형태
- k군집의 수는 인간이 정해줘야함
- DBSCAN 는
- 덩어리 형태가 아니라 연속적인 것도 가능
- 연속적으로 묶은 반경(epsilon)은 인간이 정해줘야함
2-1) k-means
k개의 평균으로 부터 거리를 계산하여 가까운 평균끼리 묶어 군집을 형성하는 방식
- 클러스터 갯수 지정= K (우리 인간이 정해줌 )
- 각 그룹의 중심점(평균:mean)이 무작위로 컴터가 선택
- 그 중심점과 각 점들간의 거리를 계산후 가까운 그룹으로 넣고,
- 중심점이 변화 없어질때까지 무한 반복 하는 방식
이때 사용하는 알고리즘은 다음과 같다
#불러오고 from sklearn.cluster import KMeans # 모델 선언 & 학습 # n_init :초기값은 무작위로 지정하기 'auto' 옵션은 데이터크기와 군집수에 맞게 알아서 지정하는 것 model = KMeans(n_clusters=k, n_init='auto') model.fit(x) #예측하기 # 학습은 비지도학습이므로 X만 학습 k_pred = model.predict(x) #확인하기 print(k_pred)
여기서도 차원축소와 마찬가지로 어떻게 적절한 K 값(클러스터의 )을 찾을까가 관건이다.
이때는 Inertia value : 각 중심점에서 군집의 데이터 간의 거리의 합산한 값으로 이값들(즉 거리의 합)이 작아지는 방향에서 적정한 k값을 찾는 것이 좋다.
# 반복문 만들어주기 k값 = range(1, 10) inertias = [] for k in k값: model = KMeans(n_clusters=k, n_init = 'auto') model.fit(x) inertias.append(model.inertia_) # 시각화하기 plt.plot(k값, inertias, '*') plt.xlabel('클러스터수') plt.ylabel('거리합') plt.grid() plt.show()
이걸 하면 마찬가지로 그래프로 적절한 갯수를 찾아주기 = elbow method
2-2)DBSCAN :
Density - Based Spatial Clustering of Applications with Noise : 밀도 기반 공간 군집
k-mean의 경우는 덩어리진 형태의 군집에는 잘 맞지만 그외에의 요상한 선모양들에는 DBSCAN을 사용한다.
- 임의의 한 점으로 인간이 정한 반경범위내에서 연속적으로 군집을 형성
- 반복
from sklearn.neighbors import NearestNeighbors from sklearn.cluster import DBSCAN model = DBSCAN(eps=0.1, min_samples=3) model.fit(x) # 모델의 lables_ 값이 찾아낸 군집 종류들을 의미 clusters = model.labels_ # 시각화 하기 plt.scatter(x['x1'], x['x2'], c=clusters, alpha=0.5) plt.show()
이때도 역시 적정한 원거리(반경/범위)는 인간이 정해줘햐아는데
KNN알고리즘으로 부터 각점과의 근처N개의 점과의 평균거리를 계산해서 그래프를 그리고
급격히 그래프가 올라가는 epsilon을 을 찾으면 된다.
##KNN을 활용 from sklearn.neighbors import NearestNeighbors # 각 점과 근처의 n개의 점들과의 평균거리를 계산하고, n = 3 knnDist = NearestNeighbors(n_neighbors = n+1).fit(x) distances, _ = knnDist.kneighbors(x) # 평균거리 계산후 정렬 # 열의 첫번째값은 자기자신과의 거리라서 0이므로 인덱싱은 1부터 dist = np.mean(distances[:, 1:], axis = 1) dist = np.sort(dist) #시각화 plt.plot(dist) plt.grid()
이때 그래프에서 x가 급격하게 커질때의 eps값(Y축의 값)을 반경으로 정하면 된다.
3.이상탐지 (Anomaly Detection)
비정상적인 값을 찾기 라고 보면된다, 흔히 말하는 이상치?
특이한 점은 우리가 가지고있는 문제점은 지도학습중 분류에 해당하는데, 모델의 학습은 비지도학습에 가깝다는 부분이다.
- 1> 모델을 만들과 정상과 비정상을 구분해야함 => Target, label,y. 정답이 있어야함 : 모델평가는 지도학습
- 2> 그러나 비정상 데이터부족 => 정상데이터로 어디까지가 정상인지 추정해야함 : 학습은 비지도학습
그래서 두가지 문제점이 여기서 도출된다
- 1. 어떻게 y. target, 정답을 확보하지??
- 2. 비정상 데이터가 부족한데, 성능이 낮아질텐데???
평가지표는 recall&precision을 두가지 다 봐야하는 F1_score를 사용한다.
알고리즘은 :Isolation Forest를 사용한다.
# 앙상블모델에서 불러옵니당 from sklearn.ensemble import IsolationForest # 모델을 학습시키고 예측하기 # contamination 이상치로 간주할 비율 # n_estimators 는 이상치를 분리하기위한 Tree 갯수 model = IsolationForest(contamination = 0.1, n_estimators = 50 ) model.fit(X_train) #시각화는 어려워서 패스..ㅜㅜ ## 예측및 평가하기 I_pred = model.predict(x_val) # 결과는 np.where사용하기 I_pred = np.where(I_pred == 1, 0, 1) # 평가하기 from sklearn.metrics import * confusion_matrix(y_val, I_pred) classification_report(y_val, I_pred) #여기서 recall, precision, f1_score를 봅니다.
지도학습과 비지도학습이 끝났으니
다음시간에는 미니프로젝트 3차가 기다리고 있다 ... 으아아악////
'KT_AIVLE_SCHOOL_DX_4th' 카테고리의 다른 글
#15 : KT_AIVLE_SCHOOL : DX_4th : 딥러닝 (2) 2023.10.18 #14 : KT_AIVLE_SCHOOL : DX_4th : 미니 프로젝트 3차 (1) 2023.10.04 #12 : KT_AIVLE_SCHOOL : DX_4th : 6주차 : 머신러닝-지도학습 (0) 2023.09.19 #11: KT_AIVLE_SCHOOL : DX_4th : DX분반에서는.... (0) 2023.09.11 #10: KT_AIVLE_SCHOOL : DX_4th : 5주차 : 미니 프로젝트 2차 (1) 2023.09.11