Skip to content

Commit

Permalink
week6 first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jgzkan committed Aug 27, 2024
1 parent 31b4382 commit 6f5a4d3
Show file tree
Hide file tree
Showing 16 changed files with 338 additions and 1 deletion.
2 changes: 1 addition & 1 deletion _posts/2024-08-14-[ML기초세션]_5주차.md
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ print(np.mean(scores['train_score']), np.mean(scores['test_score']))

## 발표 내용 by 이찬 ##

['출처: 쿠다 ML기초 5주차 심화 발표, by 이찬'](https://colab.research.google.com/drive/1Xa67KmpBo0aul2erQNGg9dcDrzIzwjjA?usp=drive_link)
[출처: 쿠다 ML기초 5주차 심화 발표, by 이찬](https://colab.research.google.com/drive/1Xa67KmpBo0aul2erQNGg9dcDrzIzwjjA?usp=drive_link)

- 앙상블 학습의 종류
- 부스팅 계열 모델 : CatBoost, LightGBM
Expand Down
337 changes: 337 additions & 0 deletions _posts/2024-0826-[ML기초세션]_6주차.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
---
layout: post
title: "[ML기초세션]_4주차"
published: true
date: 2024-08-13
math: true
categories:
tags: KHUDA ML
---


# 세션 전 학습 내용 #

교재: p.286 ~ p. 337

## [6-1] 군집 알고리즘 ##

>**핵심 키워드: 비지도 학습, 히스토그램, 군집**

### 과일 사진 데이터 준비하기 ###

```python
!wget https://bit.ly/fruits_300_data -O fruits_300.npy
```
> 코랩의 코드 셀에서 '!'로 시작하면 코랩은 이후 명령을 파이썬 코드가 아니라 리눅스 셸(shell) 명령으로 이해한다. wget 명령은 원격 주소에서 데이터를 다운로드 하여 저장한다.

이렇게 가져온 파일에서 데이터를 로드해보자.

```python
import numpy as np
import matplotlib.pyplot as plt

fruits = np.load('fruits_300.npy')

print(fruits.shape)
# (300, 100, 100) -> 300개 샘플, 100(h)x100(w) 크기의 이미지
```
fruits는 넘파이 배열이고 fruits_300.npy 파일에 들어 있는 모든 데이터를 담고 있다.

- imshow(): 넘파이 배열로 저장된 이미지를 쉽게 그릴 수 있다.
```python
plt.imshow(fruits[0], cmap = 'gray')
plt.show()
```
['img1'](assets/img/ML_week6/img1.png)

알고리즘이 어떤 출력을 만들기 위해 곱셈, 덧셈을 한다. 픽셀값이 0이면 출력도 0이 되어 의미가 없다. 픽셀값이 높으면 출력값도 커지기 때문에 의미를 부여하기 좋다.
만약 눈에 보기 좋게 출력하려면 cmap 매개변수를 'gray_r'로 지정한다.


바나나와 파인애플도 출력해보자.
- subplots(): 여러 개의 그래프를 배열처럼 쌓을 수 있도록 도와준다. 이 함수의 두 매개변수는 그래프를 쌓을 행과 열을 지정한다.
```python
fig, axs = plt.subplots(1,2)
axs[0].imshow(fruits[100], cmap='gray_r')
axs[1].imshow(fruits[200], cmap='gray_r')
plt.show()
```
['img2'](assets/img/ML_week6/img2.png)


### 픽셀값 분석하기 ###

100 x 100 이미지를 펼쳐서 길이가 10,000인 1차원 배열로 만들어보자.
이렇게 펼치면 이미지로 출력하긴 어렵지만 배열을 계산할 때 편리하다.

['img3'](assets/img/ML_week6/img3.png)

fruits 배열에서 순서대로 100개씩 선택하기 위해 슬라이싱 연산자를 사용한다. 그다음 reshape() method를 사용해 두 번째 차원(100)과 세 번째 차원(100)을 10,000으로 합친다. 첫 번째 차원을 -1로 지정하면 자동으로 남은 차원을 할당한다. 여기서는 첫 번째 차원이 샘플 개수다.

```python
apple = fruits[0:100].reshape(-1, 100*100)
pineapple = fruits[100:200].reshape(-1, 100*100)
banana = fruits[200:300].reshape(-1, 100*100)
```

이제 apple, pineapple, banana 배열의 크기는 (100, 10000)이다.

이번엔 넘파이의 mean() method를 사용해 apple, pineapple, banana 배열에 들어있는 샘플의 픽셀 평균값을 계산해보자.

axis=0으로 설정하면 첫 번째 축인 행을 따라 계산한다.

axis=1으로 지정하면 두 번째 축인 열을 따라 계산한다.

['img4'](assets/img/ML_week6/img4.png)

샘플은 모두 가로로 값을 나열했으니 axis=1으로 지정하여 평균을 계산해보자.
평균을 계산하는 넘파이 np.mean() 함수를 사용해도 되지만 넘파이 배열은 이런 함수들을 method로도 제공한다. apple 배열의 mean() method로 각 샘플의 픽셀 평균값을 계산해보자.

```python
print(apple.mean(axis=1))
```

사과 샘플 100개에 대한 픽셀 평균값을 맷플롯립의 hist() 함수를 이용하여 히스토그램으로 나타내보자.

```python
plt.hist(np.mean(apple, axis=1), alpha=0.8)
plt.hist(np.mean(pineapple, axis=1), alpha=0.8)
plt.hist(np.mean(banana, axis=1), alpha=0.8)
plt.legend(['apple', 'pineapple', 'banana'])
plt.show()
```

['img5'](assets/img/ML_week6/img5.png)

평균 픽셀값으로 바나나는 구별되는 것으로 보이지만 사과와 파인애플은 겹쳐 있어서 구분하기가 어려워 보인다.

샘플의 평균값이 아니라 픽셀별 평균값을 비교해보자.

```python
fig, axs = plt.subplots(1, 3, figsize=(20, 5))
axs[0].bar(range(10000), np.mean(apple, axis=0))
axs[1].bar(range(10000), np.mean(pineapple, axis=0))
axs[2].bar(range(10000), np.mean(banana, axis=0))
plt.show()
```

['img6'](assets/img/ML_week6/img6.png)

왼쪽부터 순서대로 사과, 파인애플, 바나나 그래프다.

픽셀 평균값을 100 x 100 크기로 바꿔서 이미지처럼 출력하여 위 그래프와 비교하면 더 좋다.

```python
apple_mean = np.mean(apple, axis=0).reshape(100, 100)
pineapple_mean = np.mean(pineapple, axis=0).reshape(100, 100)
banana_mean = np.mean(banana, axis=0).reshape(100, 100)

fig, axs = plt.subplots(1, 3, figsize=(20, 5))
axs[0].imshow(apple_mean, cmap='gray_r')
axs[1].imshow(pineapple_mean, cmap='gray_r')
axs[2].imshow(banana_mean, cmap='gray_r')
plt.show()
```

['img7'](assets/img/ML_week6/img7.png)


### 평균값과 가까운 사진 고르기 ###

abs_diff는 (300, 100, 100) 크기의 배열이다. 따라서 각 샘플에 대한 평균을 구하기 위해 axis에 2,3번째 차원 지정한다. 이렇게 계산한 abs_mean은 각 샘플의 오차 평균이므로 크기가 (300,)인 1차원 배열이다.

```python
abs_diff = np.abs(fruits - apple_mean)
abs_mean = np.mean(abs_diff, axis=(1,2))
print(abs_mean.shape)
# (300,)

# 값이 작은 순서대로 100개를 골라보자. 이중 처음 100개를 선택해 10 x 10 격자로 이루어진 그래프를 그리자.
apple_index = np.argsort(abs_mean)[:100]
fig, axs = plt.subplots(10, 10, figsize=(10,10))
for i in range(10):
for j in range(10):
axs[i, j].imshow(fruits[apple_index[i*10 + j]], cmap='gray_r')
axs[i, j].axis('off')
```
['img8'](assets/img/ML_week6/img8.png)

>코드 설명: **1.** subplots()로 10 x 10, 총 100개의 서브 그래프를 만든다. **2.** 그래프가 많기에 전체 그래프 크기를 figsize=(10,10)으로 조금 크게 지정(기본값은 (8,6)). **3.** 2중 for문을 순회하며 10개의 행과 열에 이미지를 출력한다. **4.** axs는 (10,10) 크기의 2차원 배열이므로 i, j 두 첨자를 사용해서 서브 그래프 위치 지정한다. **5.** 깔끔하게 이미지만 그리기 위해 axis('off')를 사용하여 좌표축 그리지 않음.
- np.argsort(): 작은 것에서 큰 순서대로 나열한 abs_mean 배열의 인덱스를 반환한다.

- 군집: 비슷한 샘플끼리 그룹으로 모으는 작업, 대표적인 비지도 학습 작업 중 하나

- 클러스터: 군집 알고리즘에서 만든 그룹

우리는 이미 사과, 파인애플, 바나나가 있다는 것을 알고 있었기에, 타깃값을 알고 있었기에 각 타깃의 사진 평균값을 계산해 가장 가까운 과일을 찾을 수 있었다.
반면, 실제 비지도 학습에서는 타깃값을 모르기에 이처럼 샘플의 평균값을 미리 구할 수 없다.

<br/>

### 키워드 ###

- 비지도 학습: 머신러닝의 한 종류로, 훈련 데이터의 타깃이 없다. 타깃이 없기에 외부의 도움 없이 스스로 유용한 무언가를 학습해야 한다. 대표적인 예시로 군집, 차원 축소 등이 있다.

- 히스토그램: 구간별로 값이 발생한 빈도를 그래프로 표시한 것. 보톡 x축이 값의 구간(계급)이고 y축은 발생 빈도(도수)다.

- 군집: 비슷한 샘플끼리 하나의 그룹으로 모으는 대표적인 비지도 학습 작업이다. 군집 알고리즘으로 모은 샘플 그룹을 클러스터라고 부른다.


<br/>


## [6-2] k-means ##

>**핵심 키워드: k-평균, 클러스터 중심, 엘보우 방법**
### k-means 알고리즘 소개 ###

k-means 알고리즘 작동 방식
1. 무작위로 k개의 클러스터 중심 정하기
2. 각 샘플에서 가장 가까운 클러스터 중심을 찾아 해당 클러스터의 샘플로 지정
3. 클러스터에 속한 샘플의 평균값으로 클러스터 중심을 변경
4. 클러스터 중심에 변화가 없을 때까지 2번으로 돌아가 반복

['img9'](assets/img/ML_week6/img9.png)
클러스터의 순서나 번호는 의미가 없다


### KMeans 클래스 ###

```python
!wget https://bit.ly/fruits_300_data -O fruits_300.npy

import numpy as np
# 3차원 배열을 2차원 배열로 변경
fruits = np.load('fruits_300.npy')
fruits_2d = fruits.reshape(-1, 100*100)

# KMeans 클래스에서 클러스터 개수 3개 지정, 훈련 시킬 때 타깃 데이터 없음
from sklearn.cluster import KMeans

km = KMeans(n_clusters=3, random_state=42)
km.fit(fruits_2d)

# 레이블 0, 1, 2로 모은 샘플의 개수 확인
print(np.unique(km.labels_, return_counts=True))
# (array([0, 1, 2], dtype=int32), array([111, 98, 91]))
```

```python
import matplotlib.pyplot as plt

def draw_fruits(arr, ratio=1):
n = len(arr) # n은 샘플 개수입니다
# 한 줄에 10개씩 이미지를 그립니다. 샘플 개수를 10으로 나누어 전체 행 개수를 계산합니다.
rows = int(np.ceil(n/10))
# 행이 1개 이면 열 개수는 샘플 개수입니다. 그렇지 않으면 10개입니다.
cols = n if rows < 2 else 10
fig, axs = plt.subplots(rows, cols,
figsize=(cols*ratio, rows*ratio), squeeze=False)
for i in range(rows):
for j in range(cols):
if i*10 + j < n: # n 개까지만 그립니다.
axs[i, j].imshow(arr[i*10 + j], cmap='gray_r')
axs[i, j].axis('off')
plt.show()
```

```python
draw_fruits(fruits[km.labels_==0])
```
!['img10'](assets/img/ML_week6/img10.png)

```python
draw_fruits(fruits[km.labels_==1])
```
!['img11'](assets/img/ML_week6/img11.png)

```python
draw_fruits(fruits[km.labels_==2])
```
!['img12'](assets/img/ML_week6/img12.png)

타깃 데이터를 제공하지 않았음에도 k-평균 알고리즘이 비슷한 샘플들을 어느정도 잘 모았다.



### 클러스터 중심 ###

KMeans 클래스가 최종저긍로 찾은 클러스터 중심은 cluster_centers_ 속성에 저장되어 있다.
이 배열은 fruits_2d 샘플의 클러스터 중심이기 때문에 이미지로 출력하려면 100 x 100 크기의 2차원 배열로 바꿔야 한다.

```python
draw_fruits(km.cluster_centers_.reshape(-1, 100, 100), ratio=3)
```
!['img13'](assets/img/ML_week6/img13.png)


- transform(): 훈련 데이터 샘플에서 클러스터 중심까지 거리로 변환 -> StandardScaler처럼 특성값을 변환하는 도구로 사용할 수 있다는 의미

```python
# 훈련 데이터 샘플과 클러스터 중심 사이 거리 출력, 1개 샘플만 전달했기에 크기가 (1, 클러스터 개수)인 2차원 배열 출력
print(km.transform(fruits_2d[100:101]))
# [[3393.8136117 8837.37750892 5267.70439881]]

# 가장 가까운 클러스터 중심 예측
print(km.predict(fruits_2d[100:101]))
# [0]

# 인덱스가 100인 해당 데이터 출력
draw_fruits(fruits[100:101])
# (파인애플 이미지)

# 알고리즘이 최적의 클러스터를 찾으면서 반복한 횟수
print(km.n_iter_)
# 4
```

### 최적의 k 찾기 ###

> k-평균 알고리즘의 단점 중 하나는 클러스터 개수를 사전에 지정해야 한다는 것이다.
실전에서는 몇 개의 클러스터가 있는지 미리 알 수 없다.

적절한 k 값을 찾기 위한 완벽한 방법은 없지만 가장 대표적인 **엘보우 방법**에 대해 알아보자.

- 이너셔(inertia): k-평균 알고리즘에서 측정한 클러스터 중심과 샘플 사이 거리의 제곱 합, 클러스터에 속한 샘플이 얼마나 가깝게 모여 있는지를 나타내는 값.

일반적으로 클러스터 개수가 늘어나면 클러스터 개개의 크기는 줄어들기 때문에 이너셔도 줄어든다.

- 엘보우 방법: 클러스터 개수를 늘려가면서 이너셔의 변화를 관찰하여 최적의 클러스터 개수를 찾는 방법

!['img14'](assets/img/ML_week6/img14.png)


> k-평균 알고리즘의 클러스터 중심까지 거리를 특성으로 사용할 수도 있다. 그렇게 함으로써 훈련 데이터의 차원을 크게 줄일 수 있다. 데이터셋의 차원을 줄이면 지도 학습 알고리즘의 속도를 크게 높일 수 있다.
**클러스터 중심**: k-평균 알고리즘이 만든 클러스터에 속한 샘플의 특성 평균값. centroid라고도 불리며 최근접 클러스터 중심을 또 다른 특성으로 사용하거나 새로운 샘플에 대한 예측으로 활용할 수 있다.

<br/>

### 핵심 패키지와 함수 ###

> scikit-learn
- **KMeans**: k-평균 알고리즘 클래스다.
- n_clusters에는 클러스터 개수 지정, 기본값은 8. 처음에 랜덤하게 센트로이드를 초기화하기에 여러 번 반복하여 이너셔를 기준으로 가장 좋은 결과를 선택한다.
- n_init은 반복 횟수를 지정한다. 기본값은 10.
- max_iter는 k-평균 알고리즘의 한 번 실행에서 최적의 센트로이드를 찾기 위해 반복할 수 있는 최대 횟수다. 기본값은 200.


<br/>

## [6-3] 주성분 분석 ##

> **핵심 키워드: 차원 축소, 주성분 분석, 설명된 분산**






# 발표 내용 복습 #

# Q&A 복습 #
Binary file added assets/img/ML_week6/img1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img14.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/ML_week6/img9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 6f5a4d3

Please sign in to comment.