시뮬레이터는 누군가 미리 만들어 둔 것입니다. 이제 코드로 갑니다.
아래 프로그램은 304줄이지만 겁먹을 것 없습니다.
k-평균 알고리즘 자체는 [B] 구역의 87줄이고,
나머지는 데이터를 만들고 화면에 그리고 실험을 돌리는 부분이라 이미 다 채워져 있습니다.
여러분이 채울 자리는 다섯 곳(????? 여섯 칸)뿐입니다.
⚠️ 빈칸 다섯 곳은 전부 개념 절에 나왔다
① dist2() — 두 점 사이 거리의 제곱.
가로 차이의 제곱 + 세로 차이의 제곱. 뿌리는 씌우지 않습니다(개념 2).
② assign() — 거리 목록 d에서 가장 작은 값이 몇 번째인지.
min(d)만 쓰면 거리 값이 나오지 번호가 안 나옵니다. 가장 자주 걸리는 자리입니다.
③ move() — 붙은 점들의 가로 평균과 세로 평균 두 칸(개념 2의 6명 계산).
④ inertia() — 각 점에서 가장 가까운 중심까지의 거리 제곱.
'가장 가까운'이 곧 min입니다(개념 3).
⑤ kmeans() — 멈추는 조건. 새 중심 목록과 지금 중심 목록을 견줍니다(개념 3).
⑤를 잘못 채워도 탭은 멎지 않습니다. MAX_ITER = 20이 끊어 주거든요.
대신 "20회 상한에 걸려 멈췄다(수렴 못 함)"이라는 줄이 뜹니다.
제대로 채웠다면 [C] 구역에 개념 3의 표와 똑같은 여섯 줄이 찍힙니다.
329.54 → 202.02 → 58.06 → 27.98 → 25.58 → 그리고
중심이 한 발짝도 움직이지 않았다. 6회에서 끝.
그다음이 진짜입니다. 프로그램은 이어서 이렇게 합니다.
[D] 나뉜 결과를 글자 그림으로 그린다. A · B · C가 무리이고 *가 중심이다.
중심은 그 칸의 점 하나를 덮어쓰니 그림에서 점을 세면 72개가 안 됩니다.
[E] 씨앗만 7로 바꿔 같은 일을 한다. 3회에 멈추고 SSE 68.2336이 나온다.
그림에서 한 덩어리가 통째로 한 글자가 된 것을 눈으로 확인하세요.
[F] 씨앗 1~20을 전부 돌려 성공·실패를 센다.
그리고 실패의 규칙을 프로그램이 스스로 검사해 두 목록이 같은가? True를 찍는다.
[G] K를 1~7로 바꿔 팔꿈치 표를 만든다. 과제 ③에서 손으로 채운 표와 견주세요.
[H] K = 72이면 SSE가 얼마인지 직접 계산해 보여 준다.
💡 다 돌아갔으면 부숴 보세요
코드 맨 아래에 도전 다섯이 주석으로 있습니다. 값 하나씩만 바꿔 보세요.
아래는 미리 돌려 본 답이니, 여러분 화면의 숫자와 맞는지 확인하는 데 쓰세요.
| 무엇을 바꾸나 | 어떻게 되나 |
K를 2 · 4 · 5로 (씨앗 4 고정) |
K=2 → 5회 · 묶음 [24, 48] · SSE 70.2012
K=4 → 9회 · 묶음 [8, 18, 22, 24] · SSE 21.7435
K=5 → 7회 · 묶음 [6, 7, 13, 22, 24] · SSE 19.6703 |
MAX_ITER를 1 · 2 · 3 · 4 · 5로 |
SSE 329.54 → 202.02 → 58.06 → 27.98 → 25.5772
⚠️ 4회와 5회는 묶음이 이미 [22, 24, 26]인데 SSE가 다르다.
6회에야 '수렴 True'가 뜬다. |
move()의 평균을 중앙값으로 |
씨앗 4: SSE 25.5772 → 72.5611
씨앗 7: 68.2336 → 76.5218 · 씨앗 13: 64.4168 → 70.6596
→ 셋 다 나빠진다. |
학생 한 명을 (12.0, 12.0)에 |
셋째 중심 [3.37, 5.19] → [3.74, 5.48]
전체 SSE 25.5772 → 141.2697 (5.5배) |
시작 중심 셋을 거의 같은 자리에 |
2회에 '수렴' · 묶음 [0, 24, 48]
⚠️ 오류도 무한 루프도 아니다. K=3인데 답은 2무리. |