강은 덩어리가 공 모양이라고 가정했고, 강은 아무 가정도 안 했습니다. 이 강의는 셋째 길로 갑니다.
자료가 정규분포 여럿을 섞어 뽑은 것이라고 봅니다. 먼저 어느 덩어리인지 뽑고, 그 다음 그 분포에서 점을 뽑습니다. 강의 최대우도를 그대로 쓰면 됩니다.
그 하나 때문에 닫힌 해가 사라집니다. 이 강의의 절반은 안 보이는 것을 다루는 일반적인 방법이고, 그 방법은 군집을 훨씬 넘어서 쓰입니다.
문제. 혼합모형을 세웁니다.
() 평균과 무엇이 다른지 정리하세요.
() 안 보이는 표시가 왜 어려운지 보세요.
() 표시를 알 때와 모를 때의 추정을 견주세요.
생각의 실마리. 강에서 덩어리는 점 하나였습니다. 여기서는 분포 하나입니다. 그러면 "얼마나 퍼졌는지"와 "어느 방향으로 퍼졌는지"까지 적을 수 있습니다.
풀이. () 정리합니다.
| 무엇 | 평균 | 혼합모형 |
|---|---|---|
| 덩어리가 무엇인가 | 중심 하나 | 정규분포 하나 |
| 배정 | 가장 가까운 하나 | 확률로 나눠 가짐 |
| 모양 | 언제나 공 | 공분산이 정함 |
| 크기 차이 | 못 다룸 | 섞임 비율로 다룸 |
| 무엇을 최대화 | 제곱합 최소 | 우도 최대 |
() 안 보이는 표시가 왜 어려운지 봅니다.
| 무엇 | 표시를 알면 | 표시를 모르면 |
|---|---|---|
| 우도 | 곱이 갈라짐 | 합이 로그 안에 |
| 최대우도 | 닫힌 해 | 닫힌 해가 없음 |
| 풀이 | 그냥 평균과 공분산 | 번갈아 풀기 |
| 무엇이 문제 | 없음 | 로그 안의 합 |
로그 안에 합이 있어 미분해도 안 풀립니다. 표시를 알면 로그가 합 바깥으로 나가 갈래별로 갈라지는데, 모르면 그게 안 됩니다.
() 표시를 알 때와 모를 때의 추정을 견줍니다.
| 무엇 | 첫 평균 | 둘째 평균 | 참값과의 거리 |
|---|---|---|---|
| 표시를 알 때 | |||
| 표시를 모를 때 | |||
| 참값 |
표시를 몰라도 거의 같은 자리를 찾습니다. 참값과의 거리가 와 으로 퍼센트 차이뿐입니다.
덩어리가 잘 갈리면 안 보이는 표시를 거의 복원할 수 있습니다. 강의 결측자료 문제와 같은 구조이고, 여기서는 모든 관측의 표시가 빠진 극단적인 경우입니다.
이 문제에서 배우는 것. 혼합모형은 관측 안 되는 변수를 모형에 넣는 첫 예입니다. 그 변수를 알면 문제가 쉬워지고, 모르면 어려워집니다. 다음 문제의 절차는 **"알았다고 치고 푸는 것"**입니다.
확인 1-1. 혼합모형에서 덩어리 하나가 무엇인지 쓰세요.
답. 평균과 공분산을 가진 정규분포 하나입니다.
확인 1-2. 표시를 모르면 최대우도가 왜 어려운지 쓰세요.
답. 로그 안에 합이 들어가 미분해도 안 풀리기 때문입니다.
확인 1-3. 검산에서 표시를 알 때와 모를 때의 참값과의 거리를 쓰세요.
답. 와 입니다.
문제. 번갈아 푸는 절차를 세웁니다.
() 두 단계를 정리하세요.
() 우도가 매번 오르는지 보세요.
() 소속 확률이 무엇을 뜻하는지 보세요.
생각의 실마리. 표시를 알면 쉽고 모르면 어렵습니다. 그러면 표시를 확률로 어림잡고 그것으로 모수를 구한 뒤, 그 모수로 다시 표시를 어림잡으면 됩니다.
풀이. () 정리합니다.
| 단계 | 무엇을 고정하고 | 무엇을 구하나 |
|---|---|---|
| E 단계 | 모수를 고정 | 각 점의 소속 확률 |
| M 단계 | 소속 확률을 고정 | 가중 평균과 가중 공분산 |
| 반복 | 우도가 안 오를 때까지 | 반드시 오름 |
강의 배정과 갱신이 여기서는 확률과 가중으로 바뀝니다. 배정이 아니면 이 아니라 과 사이 값입니다.
() 우도가 매번 오르는지 봅니다.
| 반복 | 평균 로그우도 | 앞 반복 대비 | 소속 확률의 최대값 평균 |
|---|---|---|---|
로그우도가 에서 까지 매번 오르고 번째에 멈춥니다.
소속 확률의 최대값 평균도 에서 로 함께 오릅니다. 처음에는 어느 덩어리인지 애매하다가 점점 확실해집니다.
강의 젠센 부등식으로 오른다는 것을 증명합니다. 심화 에서 봅니다. 평균처럼 국소 최대에 갇힐 수 있습니다.
() 소속 확률이 무엇을 뜻하는지 봅니다.
| 어떤 점 | 첫 덩어리 확률 | 둘째 덩어리 확률 | 가장 큰 값 |
|---|---|---|---|
| 가장 애매한 점 | |||
| 중간쯤 점 | |||
| 가장 확실한 점 | |||
| 전체 평균 |
애매한 점은 로 반반이고 확실한 점은 입니다.
평균은 이 값을 아니면 로 강제합니다. 그래서 평균을 굳은 배정 혼합모형이라 부르기도 합니다.
전체 평균의 셋째 열 은 첫 덩어리의 섞임 비율입니다. 참값이 였으므로 잘 맞혔습니다.
이 문제에서 배우는 것. EM은 "모르는 것을 확률로 채우고 아는 척 푼 다음 다시 채우는" 절차입니다. 이 생각은 혼합모형을 훨씬 넘어서 쓰이고, 안 보이는 변수가 있는 어떤 모형에도 같은 꼴로 적용됩니다.
확인 2-1. E 단계와 M 단계가 각각 무엇을 구하는지 쓰세요.
답. 소속 확률과 가중 평균 및 가중 공분산입니다.
확인 2-2. 검산에서 반복 과 의 평균 로그우도를 쓰세요.
답. 와 입니다.
확인 2-3. 검산에서 가장 애매한 점의 두 소속 확률을 쓰세요.
답. 과 입니다.
문제. 두 방법을 잇고 공분산을 봅니다.
() 평균이 특수한 경우인지 확인하세요.
() 공분산 형태별 모수 개수를 세세요.
() 길쭉하고 기울어진 덩어리에서 재세요.
생각의 실마리. 소속 확률이 아니면 이 되려면 분포가 아주 뾰족해야 합니다. 분산을 으로 보내면 가장 가까운 중심의 확률이 이 됩니다.
풀이. () 공분산을 같은 구 모양으로 묶고 분산을 줄여 봅니다.
| 분산 고정값 | 소속 확률의 최대값 평균 | 평균과 같은 배정 비율 | 순도 |
|---|---|---|---|
분산을 줄이면 소속 확률의 최대값이 에서 으로 오릅니다. 으로 보내면 아니면 이 됩니다.
배정도 평균과 거의 같아집니다. 과 에서는 완전히 같습니다.
평균은 혼합모형에서 공분산을 묶고 굳힌 것입니다.
() 공분산 형태별 모수 개수를 셉니다.
| 어떻게 두나 | 모수 개수 | 어떤 모양 | 차원 갈래 이면 |
|---|---|---|---|
| 구 모양 공유 | 같은 크기 공 | ||
| 구 모양 따로 | 크기 다른 공 | ||
| 대각 따로 | 곱하기 | 축에 나란한 타원 | |
| 완전 따로 | 아무 타원 |
모수가 많을수록 유연하고 표본이 많이 필요합니다. 강의 복잡도 손잡이가 여기서는 공분산의 자유도입니다.
() 길쭉한 덩어리에서 잽니다. 가로로 길쭉한 띠 둘을 위아래로 놓았습니다.
| 공분산 형태 | 순도 | 평균 로그우도 | 모수 개수 |
|---|---|---|---|
| 구 모양 | |||
| 대각 | |||
| 완전 | |||
| 평균 | 해당 없음 |
구 모양 가정은 으로 못 나눕니다. 평균과 정확히 같은 값이고 같은 이유입니다.
대각과 완전은 입니다. 축 방향을 다르게 잡을 수 있기 때문이고, 강 문제 의 길쭉한 띠 문제가 공분산으로 풀립니다.
기울어진 덩어리에서는 대각도 모자란지 봅니다.
| 공분산 형태 | 순도 | 평균 로그우도 |
|---|---|---|
| 구 모양 | ||
| 대각 | ||
| 완전 |
도로 기울어진 덩어리는 완전 공분산이라야 잡습니다. 대각은 으로 구 모양보다도 나쁩니다.
대각은 축에 나란한 타원만 그리므로 기울기를 못 씁니다. 강의 주성분이 하는 축 회전을 공분산이 대신합니다.
이 문제에서 배우는 것. 공분산을 어떻게 두느냐가 모형이 그릴 수 있는 모양을 정합니다. 강의 평균은 그 사다리의 가장 아래 칸이고, 위로 올라갈수록 유연해지는 대신 표본이 더 필요합니다.
확인 3-1. 평균이 혼합모형의 어떤 특수한 경우인지 쓰세요.
답. 공분산을 같은 구 모양으로 묶고 분산을 으로 보낸 경우입니다.
확인 3-2. 검산에서 길쭉한 띠의 구 모양과 대각 순도를 쓰세요.
답. 과 입니다.
확인 3-3. 검산에서 기울어진 덩어리의 대각과 완전 순도를 쓰세요.
답. 과 입니다.
문제. 무너지는 경우를 봅니다.
() 문제들을 정리하세요.
() 특이해를 일부러 만들어 보세요.
() 갈래 수를 정보기준으로 고르세요.
생각의 실마리. 정규분포의 밀도는 분산이 으로 가면 무한으로 갑니다. 그러면 점 하나에 덩어리 하나를 얹어 우도를 무한으로 만들 수 있습니다.
풀이. () 정리합니다.
| 무엇 | 무엇이 일어나나 | 어떻게 막나 |
|---|---|---|
| 특이해 | 한 점에 분산 | 공분산에 작은 값 더함 |
| 국소 최대 | 시작점에 딸림 | 여러 번 돌림 |
| 갈래 수 | 우도로는 못 정함 | 정보기준이나 교차검증 |
| 라벨 바꿔치기 | 번호가 뒤바뀜 | 번호는 뜻이 없음 |
| 모양이 정규가 아님 | 억지로 맞춤 | 덩어리를 더 씀 |
() 특이해를 일부러 만들어 봅니다. 한 덩어리의 중심을 점 하나에 두고 분산을 아주 작게 시작합니다.
| 더하는 값 | 가장 작은 분산 | 평균 로그우도 | 그 덩어리가 맡은 유효 개수 |
|---|---|---|---|
더하는 값이 면 분산 바닥이 높아 그 덩어리가 빠져나옵니다. 유효 개수 를 맡고 로그우도도 으로 정상 자리입니다.
이하면 세 점 남짓만 맡은 채 분산 에 갇힙니다. 전체 로그우도가 으로 오히려 낮습니다. 국소 최대에 갇힌 것입니다.
막는 값을 아예 안 두면 분산이 으로 가고 그 점의 밀도가 무한이 됩니다. 강의 벌점과 같은 장치이고, 여기서는 안 갇히게 하는 구실도 합니다.
() 갈래 수를 정보기준으로 고릅니다. 참 갈래가 둘인 자료입니다.
| 평균 로그우도 | 모수 개수 | AIC | BIC | |
|---|---|---|---|---|
로그우도는 를 키우면 에서 까지 계속 오릅니다. 강 문제 의 목적함수와 같습니다.
AIC와 BIC는 모수 개수에 벌을 주므로 에서 최소가 됩니다. BIC가 벌을 더 세게 주므로 대체로 더 작은 를 고릅니다.
덩어리가 정규가 아니면 어떻게 되는지 봅니다. 고리 하나짜리 자료입니다.
| 덩어리 수 | 평균 로그우도 | BIC |
|---|---|---|
BIC가 에서 까지 계속 내려갑니다. 참 군집은 하나인데 정보기준이 여덟 개를 고릅니다.
고리를 정규분포 여럿으로 덮는 것입니다. 덩어리 수가 모양을 대신하므로, 여기서 나온 덩어리는 참 군집이 아니라 밀도 근사 조각입니다.
군집으로 쓸 것인지 밀도로 쓸 것인지를 먼저 정해야 합니다. 밀도가 목적이면 여덟 개가 옳고, 군집이 목적이면 틀린 답입니다.
이 문제에서 배우는 것. 우도를 최대화하는 것이 언제나 원하는 것은 아닙니다. 특이해에서는 우도가 무한인데 쓸모가 없고, 고리에서는 BIC가 여덟 개를 고르는데 군집으로는 틀립니다. 무엇에 쓸지가 답을 정합니다.
확인 4-1. 특이해가 무엇인지 쓰세요.
답. 한 점에 덩어리가 얹혀 분산이 으로 가고 밀도가 무한이 되는 해입니다.
확인 4-2. 검산에서 더하는 값이 와 일 때 그 덩어리가 맡은 유효 개수를 쓰세요.
답. 와 입니다.
확인 4-3. 검산에서 고리 자료의 덩어리 개와 개의 BIC를 쓰세요.
답. 과 입니다.
문제. 실제 쓰임을 봅니다.
() 쓰임을 정리하세요.
() 밀도로 이상점을 찾아 보세요.
() 라벨이 조금 있을 때 함께 써 보세요.
생각의 실마리. 혼합모형은 군집만 하는 것이 아닙니다. 를 통째로 추정하므로 새 점의 밀도를 잴 수 있고, 그 밀도가 여러 곳에 쓰입니다.
풀이. () 정리합니다.
| 쓰임 | 무엇을 쓰나 | 어디서 다시 보나 |
|---|---|---|
| 군집 | 가장 큰 소속 확률 | 이 강의 |
| 밀도 추정 | 혼합 밀도 자체 | 강 이상탐지 |
| 빠진 값 채우기 | 조건부 기댓값 | 강 |
| 자료 만들기 | 뽑아서 새 점 | S 생성모형 |
| 반지도 학습 | 라벨 있는 것과 없는 것 | 이 문제 |
() 밀도로 이상점을 찾아 봅니다.
| 어떤 점 | 로그밀도 | 학습 자료의 몇 퍼센트 아래 |
|---|---|---|
| 학습 자료 퍼센트 자리 | ||
| 가운데쯤 점 | ||
| 멀리 떨어진 점 | ||
| 반대쪽 멀리 |
멀리 떨어진 점의 로그밀도가 로 학습 자료 어느 점보다도 낮습니다.
학습 자료의 밀도 분포에서 몇 퍼센트 자리인지로 이상 여부를 정합니다. 퍼센트 자리가 이므로 그보다 낮으면 이상하다고 볼 수 있습니다.
강에서 이 방법을 제대로 다룹니다.
() 라벨이 조금 있을 때 함께 써 봅니다.
| 라벨이 몇 개 있나 | 라벨만 쓸 때 | 라벨 없는 것도 쓸 때 |
|---|---|---|
라벨이 개뿐이면 라벨만으로는 입니다. 갈래마다 세 개로는 공분산을 못 추정합니다.
라벨 없는 자료로 모양을 잡고 라벨로 이름만 붙이면 입니다. 퍼센트포인트가 오릅니다.
그런데 라벨이 개가 되면 라벨만 쓰는 쪽이 으로 앞섭니다. 라벨 없는 자료를 쓰는 쪽은 에 머무는데, 혼합모형이 정규분포라는 가정에 묶여 있기 때문입니다.
강 문제 에서 본 것과 같습니다. 생성모형은 표본이 적을 때만 이깁니다. 라벨이 넉넉해지면 가정 없는 쪽이 앞섭니다.
세 군집 방법을 한자리에 놓습니다.
| 무엇 | 평균 | 밀도 기반 | 혼합모형 |
|---|---|---|---|
| 배정 | 굳음 | 굳음 | 확률 |
| 모양 | 공 | 아무 모양 | 타원 |
| 개수 | 정함 | 안 정함 | 정보기준 |
| 잡음 | 다 넣음 | 따로 뺌 | 낮은 밀도 |
| 밀도를 주나 | 아니오 | 아니오 | 예 |
마지막 줄이 혼합모형만의 것입니다. 새 점의 밀도를 잴 수 있고, 그것이 이상탐지와 생성모형으로 이어집니다.
이 문제에서 배우는 것. 혼합모형의 진짜 값어치는 군집이 아니라 밀도입니다. 군집만 할 것이면 강이 더 싸고, 가 필요할 때 이 모형을 씁니다.
확인 5-1. 혼합모형이 다른 두 군집 방법과 다른 점 하나를 쓰세요.
답. 새 점의 밀도를 잴 수 있습니다.
확인 5-2. 검산에서 멀리 떨어진 점의 로그밀도를 쓰세요.
답. 입니다.
확인 5-3. 검산에서 라벨 개일 때 두 방법의 정확도를 쓰세요.
답. 과 입니다.
| 유형 | 무엇을 묻나 | 어디를 보나 |
|---|---|---|
| 안 보이는 표시 | 로그 안의 합 | 문제 |
| E 단계 | 소속 확률 | 문제 |
| M 단계 | 가중 평균과 공분산 | 문제 |
| 우도의 단조 증가 | 반드시 오름 | 문제 |
| 평균과의 관계 | 굳힌 특수 경우 | 문제 |
| 공분산 형태 | 그릴 수 있는 모양 | 문제 |
| 특이해 | 분산이 으로 | 문제 |
| 갈래 수 | AIC와 BIC | 문제 |
| 밀도 추정 | 이상점 찾기 | 문제 |
| 반지도 학습 | 라벨 없는 것도 씀 | 문제 |
핵심 식을 한자리에 모읍니다.
| 공분산 | 모수 수 | 언제 쓰나 |
|---|---|---|
| 구 모양 공유 | 표본이 아주 적을 때 | |
| 구 모양 따로 | 크기만 다를 때 | |
| 대각 | 축이 뜻을 가질 때 | |
| 완전 | 표본이 넉넉할 때 |
문제 6. 혼합모형에서 덩어리 하나가 무엇인지 쓰세요.
답. 평균과 공분산을 가진 정규분포 하나입니다.
문제 7. 표시를 모르면 최대우도가 왜 어려운지 쓰세요.
답. 로그 안에 합이 들어가 미분해도 안 풀리기 때문입니다.
문제 8. 검산에서 표시를 알 때와 모를 때의 참값과의 거리를 쓰세요.
답. 와 입니다.
문제 9. E 단계와 M 단계가 각각 무엇을 구하는지 쓰세요.
답. 소속 확률과 가중 평균 및 가중 공분산입니다.
문제 10. 검산에서 반복 과 의 평균 로그우도를 쓰세요.
답. 와 입니다.
문제 11. 검산에서 가장 애매한 점의 두 소속 확률을 쓰세요.
답. 과 입니다.
문제 12. 평균이 혼합모형의 어떤 특수한 경우인지 쓰세요.
답. 공분산을 같은 구 모양으로 묶고 분산을 으로 보낸 경우입니다.
문제 13. 검산에서 길쭉한 띠의 구 모양과 대각 순도를 쓰세요.
답. 과 입니다.
문제 14. 검산에서 기울어진 덩어리의 대각과 완전 순도를 쓰세요.
답. 과 입니다.
문제 15. 검산에서 더하는 값이 와 일 때 그 덩어리가 맡은 유효 개수를 쓰세요.
답. 와 입니다.
문제 16. 검산에서 고리 자료의 덩어리 개와 개의 BIC를 쓰세요.
답. 과 입니다.
문제 17. 검산에서 멀리 떨어진 점의 로그밀도를 쓰세요.
답. 입니다.
문제 18. 검산에서 라벨 개일 때 두 방법의 정확도를 쓰세요.
답. 과 입니다.
심화 1. EM이 왜 우도를 올리는지 증명하세요.
젠센 부등식으로 로그우도의 아래 경계를 만듭니다.
| 단계 | 무엇을 하나 | 결과 |
|---|---|---|
| E 단계 | 로 둠 | 경계가 로그우도와 같아짐 |
| M 단계 | 로 을 최대화 | 경계가 올라감 |
| 따라서 | 로그우도가 경계 이상 | 반드시 오름 |
강의 젠센 부등식이 정확히 여기서 쓰입니다. E 단계에서 경계가 딱 닿게 만들고, M 단계에서 그 경계를 밀어 올립니다. 로그우도는 경계보다 크거나 같으므로 함께 오릅니다.
심화 2. 혼합모형의 라벨 바꿔치기 문제를 정리하세요.
| 무엇 | 결과 |
|---|---|
| 같은 우도를 주는 해 | 개 |
| 최대우도에서 | 문제 없음 |
| 베이즈 사후분포에서 | 봉우리가 개 |
| 여러 번 돌린 결과 평균 | 뜻이 없음 |
덩어리 번호는 아무 뜻이 없습니다. 그래서 여러 번 돌린 결과를 평균 내면 안 되고, 번호를 맞춰 준 뒤에 견줘야 합니다. 검산에서 순도를 쓴 것이 그 때문입니다.
심화 3. 혼합모형과 커널 밀도 추정의 관계를 정리하세요.
| 무엇 | 혼합모형 | 커널 밀도 추정 |
|---|---|---|
| 덩어리 수 | 개 | 개 |
| 중심 | 학습으로 정함 | 자료점 그대로 |
| 폭 | 학습으로 정함 | 손으로 정함 |
| 모수 수 |
커널 밀도 추정은 덩어리를 개 두고 중심을 자료점에 고정한 혼합모형입니다. 강 문제 의 커널 회귀와 같은 식이 밀도에 쓰인 것이고, 혼합모형은 그것을 개로 압축한 것입니다.
심화 4. 무한 혼합모형이 무엇인지 정리하세요.
| 무엇 | 유한 혼합 | 디리클레 과정 혼합 |
|---|---|---|
| 덩어리 수 | 미리 정함 | 자료가 정함 |
| 사전분포 | 디리클레 | 디리클레 과정 |
| 새 점 | 기존 덩어리에만 | 새 덩어리도 가능 |
| 계산 | EM | 표집이나 변분법 |
를 고르는 문제를 모형 안으로 넣은 것입니다. 문제 에서 AIC와 BIC로 밖에서 골랐던 것을, 여기서는 사전분포로 안에서 정하게 합니다. 대신 계산이 훨씬 무거워집니다.
심화 5. EM을 다른 문제에 쓰는 예를 정리하세요.
| 문제 | 안 보이는 것 |
|---|---|
| 혼합모형 | 어느 덩어리인지 |
| 결측자료 | 빠진 값 |
| 은닉 마르코프 모형 | 숨은 상태 |
| 요인분석 | 요인 점수 |
| 절단된 자료 | 잘린 부분의 값 |
다섯 문제가 모두 같은 절차로 풀립니다. "안 보이는 것의 조건부 기댓값을 구하고, 그것으로 모수를 갱신한다"입니다. EM은 혼합모형의 알고리즘이 아니라 안 보이는 변수를 다루는 일반적인 틀입니다.
심화 6. 언제 혼합모형을 쓸지 정리하세요.
| 상황 | 쓰나 | 왜 |
|---|---|---|
| 밀도가 필요함 | 예 | 유일하게 밀도를 줌 |
| 덩어리가 타원 모양 | 예 | 가정에 맞음 |
| 소속이 애매한 점이 많음 | 예 | 확률로 냄 |
| 표본이 적고 차원이 높음 | 아니오 | 공분산을 못 추정 |
| 모양이 정규가 아님 | 아니오 | 강이 나음 |
넷째 줄이 실무의 벽입니다. 완전 공분산은 갈래마다 개를 추정해야 하므로, 차원 이면 갈래 하나에 개입니다. 그때는 대각으로 묶거나 강으로 차원을 먼저 줄입니다.
정답.
| 기호 | 읽는 법 | 뜻 |
|---|---|---|
| 혼합모형 | mixture model | 분포 여럿을 섞어 자료를 설명합니다 |
| 섞임 비율 | mixing proportion | 각 덩어리가 차지하는 몫입니다 |
| 잠재변수 | latent variable | 관측 안 되는 변수입니다 |
| 소속 확률 | responsibility | 한 점이 각 덩어리에 속할 확률입니다 |
| EM 알고리즘 | expectation-maximization | 기댓값 단계와 최대화 단계를 번갈아 합니다 |
| 아래 경계 | evidence lower bound | 젠센 부등식으로 만든 로그우도의 하한입니다 |
| 특이해 | singular solution | 분산이 으로 가 밀도가 무한이 되는 해입니다 |
| 라벨 바꿔치기 | label switching | 덩어리 번호를 바꿔도 같은 모형입니다 |
| 굳은 배정 | hard assignment | 소속을 아니면 로 정합니다 |
| 반지도 학습 | semi-supervised learning | 라벨 있는 것과 없는 것을 함께 씁니다 |
다음은 224강 주성분분석의 활용과 t-SNE입니다. 이 강의까지 세 강의가 점들을 나누는 일을 했습니다. 다음 강의는 나누지 않습니다. 축을 갈아타서 같은 자료를 더 적은 차원으로 적습니다.
import numpy as np
rng = np.random.default_rng(20270110)
def pw(s, n):
k = n - sum(2 if ord(c) > 0x2FFF else 1 for c in str(s))
return str(s) + " " * max(k, 0)
def rw(s, n):
k = n - sum(2 if ord(c) > 0x2FFF else 1 for c in str(s))
return " " * max(k, 0) + str(s)
def logdet_chol(S):
L = np.linalg.cholesky(S)
return 2.0 * float(np.sum(np.log(np.diag(L))))
def log_norm(X, mu, S):
d = X.shape[1]
L = np.linalg.cholesky(S)
z = np.linalg.solve(L, (X - mu).T)
q = (z ** 2).sum(axis=0)
return -0.5 * (d * np.log(2 * np.pi) + logdet_chol(S) + q)
def logsumexp(A):
m = A.max(axis=1, keepdims=True)
return (m[:, 0] + np.log(np.exp(A - m).sum(axis=1)))
def em_fit(X, k, r, iters=200, reg=1e-6, cov="full", init=None, tol=1e-8):
n, d = X.shape
if init is None:
mu = X[r.permutation(n)[:k]].copy()
else:
mu = init.copy()
S = np.stack([np.cov(X.T) + reg * np.eye(d) for _ in range(k)])
pi = np.full(k, 1.0 / k)
hist = []
conf_hist = []
prev = -np.inf
for _ in range(iters):
LG = np.stack([log_norm(X, mu[j], S[j]) + np.log(pi[j])
for j in range(k)], axis=1)
ll = float(logsumexp(LG).mean())
hist.append(ll)
R = np.exp(LG - logsumexp(LG)[:, None])
conf_hist.append(float(np.max(R, axis=1).mean()))
Nk = R.sum(axis=0) + 1e-12
pi = Nk / n
mu = (R.T @ X) / Nk[:, None]
for j in range(k):
Z = X - mu[j]
C = (R[:, j][:, None] * Z).T @ Z / Nk[j]
if cov == "diag":
C = np.diag(np.diag(C))
elif cov == "spherical":
C = np.eye(d) * (np.trace(C) / d)
S[j] = C + reg * np.eye(d)
if ll - prev < tol and _ > 3:
break
prev = ll
LG = np.stack([log_norm(X, mu[j], S[j]) + np.log(pi[j])
for j in range(k)], axis=1)
R = np.exp(LG - logsumexp(LG)[:, None])
return pi, mu, S, R, hist, conf_hist
def purity(lab, z, k):
tot = 0
for j in range(k):
m = lab == j
if m.any():
tot += np.bincount(z[m]).max()
return float(tot / len(z))
def kmeans(X, k, r, tries=15):
best = None
for _ in range(tries):
C = X[r.permutation(len(X))[:k]].copy()
lab = np.zeros(len(X), dtype=np.int64)
for _ in range(200):
D = ((X[:, None, :] - C[None, :, :]) ** 2).sum(axis=2)
new = np.argmin(D, axis=1)
if np.array_equal(new, lab):
break
lab = new
for j in range(k):
m = lab == j
if m.any():
C[j] = X[m].mean(axis=0)
D = ((X[:, None, :] - C[None, :, :]) ** 2).sum(axis=2)
w = float(np.sum(np.min(D, axis=1)))
if best is None or w < best[1]:
best = (lab, w)
return best[0]
# --- 문제 1: 덩어리를 확률분포로 적습니다 --------------------------------
print(" 221강은 모양을 가정했고 222강은 안 가정했습니다")
print(" 이번에는 모양을 확률분포로 적습니다")
print(" %s %s %s"
% (pw("무엇", 22), rw("k 평균", 22), rw("혼합모형", 24)))
for a, b, c in [("덩어리가 무엇인가", "중심 하나", "정규분포 하나"),
("배정", "가장 가까운 하나", "확률로 나눠 가짐"),
("모양", "언제나 공", "공분산이 정함"),
("크기 차이", "못 다룸", "섞임 비율로 다룸"),
("무엇을 최대화", "제곱합 최소", "우도 최대")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 22), rw(c, 24)))
print(" 자료가 정규분포 여럿을 섞어 뽑았다고 봅니다")
print(" 먼저 어느 덩어리인지 뽑고 그 다음 그 분포에서 점을 뽑습니다")
print(" 149강의 최대우도를 그대로 쓰는데 덩어리 표시가 안 보입니다")
print(" 안 보이는 표시가 있으면 왜 어려운지 봅니다")
n1 = 600
z1 = (rng.uniform(0, 1, n1) < 0.35).astype(np.int64)
mu_t = np.array([[0.0, 0.0], [3.0, 2.0]])
S_t = np.stack([np.array([[1.0, 0.7], [0.7, 1.0]]),
np.array([[0.6, -0.3], [-0.3, 1.5]])])
X1 = np.zeros((n1, 2))
for j in [0, 1]:
m = z1 == j
L = np.linalg.cholesky(S_t[j])
X1[m] = mu_t[j] + rng.normal(0, 1, (int(m.sum()), 2)) @ L.T
print(" %s %s %s"
% (pw("무엇", 26), rw("표시를 알면", 24), rw("표시를 모르면", 24)))
for a, b, c in [("우도", "곱이 갈라짐", "합이 로그 안에"),
("최대우도", "닫힌 해", "닫힌 해가 없음"),
("풀이", "그냥 평균과 공분산", "번갈아 풀기"),
("무엇이 문제", "없음", "로그 안의 합")]:
print(" %s %s %s" % (pw(a, 26), rw(b, 24), rw(c, 24)))
print(" 표시를 알면 갈래별로 나눠 평균과 공분산을 그냥 구하면 됩니다")
print(" 모르면 로그 안에 합이 들어가 미분해도 안 풀립니다")
print(" 표시를 알 때와 모를 때의 추정을 견줍니다")
print(" %s %s %s %s"
% (pw("무엇", 26), rw("첫 평균", 18), rw("둘째 평균", 18),
rw("참값과의 거리", 20)))
mu_full = np.stack([X1[z1 == j].mean(axis=0) for j in [0, 1]])
print(" %s %18.6f %18.6f %20.6f"
% (pw("표시를 알 때", 26), mu_full[0, 0], mu_full[1, 0],
float(np.linalg.norm(mu_full - mu_t))))
pi, mu, S, R, hist, ch = em_fit(X1, 2, rng)
o = np.argsort(mu[:, 0])
mu = mu[o]
print(" %s %18.6f %18.6f %20.6f"
% (pw("표시를 모를 때", 26), mu[0, 0], mu[1, 0],
float(np.linalg.norm(mu - mu_t))))
print(" %s %18.6f %18.6f %20.6f"
% (pw("참값", 26), mu_t[0, 0], mu_t[1, 0], 0.0))
print(" 표시를 몰라도 거의 같은 자리를 찾습니다")
print(" 덩어리가 잘 갈리면 안 보이는 표시를 거의 복원할 수 있습니다")
print(" 156강의 결측자료 문제와 같은 구조입니다")
# --- 문제 2: EM 알고리즘 -----------------------------------------------
print(" 번갈아 푸는 절차를 세웁니다")
print(" %s %s %s"
% (pw("단계", 16), rw("무엇을 고정하고", 24), rw("무엇을 구하나", 26)))
for a, b, c in [("E 단계", "모수를 고정", "각 점의 소속 확률"),
("M 단계", "소속 확률을 고정", "가중 평균과 가중 공분산"),
("반복", "우도가 안 오를 때까지", "반드시 오름")]:
print(" %s %s %s" % (pw(a, 16), rw(b, 24), rw(c, 26)))
print(" 221강의 배정과 갱신이 여기서는 확률과 가중으로 바뀝니다")
print(" 배정이 0 아니면 1 이 아니라 0 과 1 사이 값입니다")
print(" 우도가 정말 매번 오르는지 봅니다")
pi2, mu2, S2, R2, hist2, ch2 = em_fit(X1, 2, rng, 40)
print(" %s %s %s %s"
% (pw("반복", 10), rw("평균 로그우도", 20), rw("앞 반복 대비", 18),
rw("소속 확률의 최대값 평균", 26)))
for it in [1, 2, 3, 5, 10, len(hist2)]:
i = min(it, len(hist2)) - 1
dd = 0.0 if i == 0 else hist2[i] - hist2[i - 1]
print(" %s %20.6f %18.6f %26.6f"
% (pw(str(i + 1), 10), hist2[i], dd, ch2[i]))
print(" 로그우도가 매번 오르고 어느 자리에서 멈춥니다")
print(" 132강의 젠센 부등식으로 오른다는 것을 증명합니다. 심화 1 에서 봅니다")
print(" k 평균처럼 국소 최대에 갇힐 수 있습니다")
print(" 소속 확률이 무엇을 뜻하는지 봅니다")
print(" 경계에서 먼 점과 가까운 점의 소속 확률을 봅니다")
conf = np.max(R2, axis=1)
o2 = np.argsort(conf)
print(" %s %s %s %s"
% (pw("어떤 점", 24), rw("첫 덩어리 확률", 20), rw("둘째 덩어리 확률", 20),
rw("가장 큰 값", 16)))
for nm, i in [("가장 애매한 점", o2[0]), ("중간쯤 점", o2[n1 // 2]),
("가장 확실한 점", o2[-1])]:
print(" %s %20.6f %20.6f %16.6f"
% (pw(nm, 24), R2[i, 0], R2[i, 1], conf[i]))
print(" %s %20.6f %20.6f %16.6f"
% (pw("전체 평균", 24), float(R2[:, 0].mean()),
float(R2[:, 1].mean()), float(conf.mean())))
print(" 애매한 점은 0.5 근처이고 확실한 점은 1 에 가깝습니다")
print(" k 평균은 이 값을 0 아니면 1 로 강제합니다")
print(" 그래서 k 평균을 굳은 배정 혼합모형이라 부르기도 합니다")
print(" k 평균이 혼합모형의 특수한 경우인지 확인합니다")
print(" 공분산을 같은 구 모양으로 묶고 분산을 0 으로 보내 봅니다")
print(" %s %s %s %s"
% (pw("분산 고정값", 16), rw("소속 확률의 최대값 평균", 26),
rw("k 평균과 같은 배정 비율", 26), rw("순도", 14)))
kl = kmeans(X1, 2, rng)
for sg in [1.0, 0.3, 0.1, 0.02]:
mu0 = X1[rng.permutation(n1)[:2]].copy()
for _ in range(60):
LG = np.stack([log_norm(X1, mu0[j], sg * np.eye(2))
for j in range(2)], axis=1)
Rq = np.exp(LG - logsumexp(LG)[:, None])
Nk = Rq.sum(axis=0) + 1e-12
mu0 = (Rq.T @ X1) / Nk[:, None]
lab = np.argmax(Rq, axis=1)
agree = max(float(np.mean(lab == kl)), float(np.mean(lab != kl)))
print(" %s %26.6f %26.6f %14.6f"
% (pw("%.2f" % sg, 16), float(np.max(Rq, axis=1).mean()),
agree, purity(lab, z1, 2)))
print(" 분산을 줄이면 소속 확률의 최대값이 0.964052 에서 0.998983 으로 오릅니다")
print(" 0 으로 보내면 0 아니면 1 이 됩니다")
print(" 배정도 k 평균과 거의 같아집니다. 0.30 과 0.02 에서는 완전히 같습니다")
print(" k 평균은 혼합모형에서 공분산을 묶고 굳힌 것입니다")
# --- 문제 3: 공분산이 무엇을 사는가 -------------------------------------
print(" 공분산을 어떻게 두느냐로 모형의 크기가 정해집니다")
print(" %s %s %s %s"
% (pw("어떻게 두나", 20), rw("모수 개수", 20), rw("어떤 모양", 20),
rw("차원 10 갈래 3 이면", 24)))
for a, b, c, d in [("구 모양 공유", "1", "같은 크기 공", "1"),
("구 모양 따로", "k", "크기 다른 공", "3"),
("대각 따로", "k 곱하기 d", "축에 나란한 타원", "30"),
("완전 따로", "k 곱하기 d(d+1)/2", "아무 타원", "165")]:
print(" %s %s %s %s"
% (pw(a, 20), rw(b, 20), rw(c, 20), rw(d, 24)))
print(" 모수가 많을수록 유연하고 표본이 많이 필요합니다")
print(" 214강의 복잡도 손잡이가 여기서는 공분산의 자유도입니다")
print(" 길쭉한 덩어리에서 세 가지를 견줍니다")
n3 = 500
z3 = rng.integers(0, 2, n3)
S3 = np.stack([np.array([[3.0, 0.0], [0.0, 0.1]]),
np.array([[3.0, 0.0], [0.0, 0.1]])])
mu3 = np.array([[0.0, 0.0], [0.0, 1.2]])
X3 = np.zeros((n3, 2))
for j in [0, 1]:
m = z3 == j
L = np.linalg.cholesky(S3[j])
X3[m] = mu3[j] + rng.normal(0, 1, (int(m.sum()), 2)) @ L.T
print(" 가로로 길쭉한 띠 둘을 위아래로 놓았습니다")
print(" %s %s %s %s"
% (pw("공분산 형태", 20), rw("순도", 16), rw("평균 로그우도", 20),
rw("모수 개수", 16)))
for nm, cv, npar in [("구 모양", "spherical", 2 * (2 + 1) + 1),
("대각", "diag", 2 * (2 + 2) + 1),
("완전", "full", 2 * (2 + 3) + 1)]:
best = None
for _ in range(10):
p_, m_, s_, r_, h_, c_ = em_fit(X3, 2, rng, 200, 1e-6, cv)
if best is None or h_[-1] > best[4][-1]:
best = (p_, m_, s_, r_, h_)
lab = np.argmax(best[3], axis=1)
print(" %s %16.6f %20.6f %16d"
% (pw(nm, 20), purity(lab, z3, 2), best[4][-1], npar))
kl3 = kmeans(X3, 2, rng)
print(" %s %16.6f %20s %16d"
% (pw("k 평균", 20), purity(kl3, z3, 2), rw("해당 없음", 20), 4))
print(" 구 모양 가정은 길쭉한 띠를 못 나눕니다. k 평균과 같은 이유입니다")
print(" 대각과 완전은 축 방향을 다르게 잡을 수 있어 나눕니다")
print(" 221강 문제 4 의 길쭉한 띠 문제가 공분산으로 풀립니다")
print(" 기울어진 덩어리에서는 대각도 모자란지 봅니다")
n4 = 500
z4 = rng.integers(0, 2, n4)
A = np.array([[1.0, 0.9], [0.9, 1.0]])
S4 = np.stack([A * 1.0, A * 1.0])
mu4 = np.array([[0.0, 0.0], [1.2, -1.2]])
X4 = np.zeros((n4, 2))
for j in [0, 1]:
m = z4 == j
L = np.linalg.cholesky(S4[j])
X4[m] = mu4[j] + rng.normal(0, 1, (int(m.sum()), 2)) @ L.T
print(" 45 도로 기울어진 덩어리 둘입니다")
print(" %s %s %s"
% (pw("공분산 형태", 20), rw("순도", 16), rw("평균 로그우도", 20)))
for nm, cv in [("구 모양", "spherical"), ("대각", "diag"), ("완전", "full")]:
best = None
for _ in range(10):
p_, m_, s_, r_, h_, c_ = em_fit(X4, 2, rng, 200, 1e-6, cv)
if best is None or h_[-1] > best[4][-1]:
best = (p_, m_, s_, r_, h_)
lab = np.argmax(best[3], axis=1)
print(" %s %16.6f %20.6f"
% (pw(nm, 20), purity(lab, z4, 2), best[4][-1]))
print(" 기울어진 방향은 완전 공분산이라야 잡습니다")
print(" 대각은 축에 나란한 타원만 그리므로 기울기를 못 씁니다")
print(" 88강의 주성분이 하는 축 회전을 공분산이 대신합니다")
# --- 문제 4: 무엇이 잘못될 수 있는가 ------------------------------------
print(" 이 방법이 무너지는 경우를 봅니다")
print(" %s %s %s"
% (pw("무엇", 22), rw("무엇이 일어나나", 24), rw("어떻게 막나", 24)))
for a, b, c in [("특이해", "한 점에 분산 0", "공분산에 작은 값 더함"),
("국소 최대", "시작점에 딸림", "여러 번 돌림"),
("갈래 수", "우도로는 못 정함", "정보기준이나 교차검증"),
("라벨 바꿔치기", "번호가 뒤바뀜", "번호는 뜻이 없음"),
("모양이 정규가 아님", "억지로 맞춤", "덩어리를 더 씀")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 24), rw(c, 24)))
print(" 특이해를 일부러 만들어 봅니다")
print(" 한 덩어리의 중심을 점 하나에 두고 분산을 아주 작게 시작합니다")
print(" %s %s %s %s"
% (pw("더하는 값", 14), rw("가장 작은 분산", 20), rw("평균 로그우도", 20),
rw("그 덩어리가 맡은 유효 개수", 30)))
for reg in [1e-2, 1e-4, 1e-6, 1e-10]:
mus = np.stack([X1[0], X1.mean(axis=0)])
Ss = np.stack([1e-3 * np.eye(2), np.cov(X1.T)])
pis = np.array([0.5, 0.5])
for _ in range(80):
LG = np.stack([log_norm(X1, mus[j], Ss[j]) + np.log(pis[j])
for j in range(2)], axis=1)
Rq = np.exp(LG - logsumexp(LG)[:, None])
Nk = Rq.sum(axis=0) + 1e-12
pis = Nk / n1
mus = (Rq.T @ X1) / Nk[:, None]
for j in range(2):
Z = X1 - mus[j]
Ss[j] = (Rq[:, j][:, None] * Z).T @ Z / Nk[j] + reg * np.eye(2)
LG = np.stack([log_norm(X1, mus[j], Ss[j]) + np.log(pis[j])
for j in range(2)], axis=1)
ll = float(logsumexp(LG).mean())
ev = min(float(np.linalg.eigvalsh(Ss[j]).min()) for j in range(2))
print(" %s %20.6e %20.6f %30.6f"
% (pw("%.0e" % reg, 14), ev, ll, float(Rq[:, 0].sum())))
print(" 더하는 값이 1e-2 면 분산 바닥이 높아 그 덩어리가 빠져나옵니다")
print(" 유효 개수 392.9 를 맡고 로그우도도 -3.116650 으로 정상 자리입니다")
print(" 1e-4 이하면 세 점 남짓만 맡은 채 분산 0.00024 에 갇힙니다")
print(" 전체 로그우도가 -3.388533 으로 오히려 낮습니다. 국소 최대에 갇힌 것입니다")
print(" 막는 값을 아예 안 두면 분산이 0 으로 가고 그 점의 밀도가 무한이 됩니다")
print(" 211강의 벌점과 같은 장치이고 여기서는 안 갇히게 하는 구실도 합니다")
print(" 갈래 수를 정보기준으로 골라 봅니다")
print(" 참 갈래가 둘인 자료입니다")
print(" %s %s %s %s %s"
% (pw("k", 8), rw("평균 로그우도", 20), rw("모수 개수", 14),
rw("AIC", 16), rw("BIC", 16)))
for k in [1, 2, 3, 4, 6]:
best = None
for _ in range(12):
p_, m_, s_, r_, h_, c_ = em_fit(X1, k, rng, 200, 1e-4)
if best is None or h_[-1] > best[4][-1]:
best = (p_, m_, s_, r_, h_)
npar = k * (2 + 3) + (k - 1)
ll = best[4][-1] * n1
print(" %s %20.6f %14d %16.6f %16.6f"
% (pw(str(k), 8), best[4][-1], npar,
-2 * ll + 2 * npar, -2 * ll + npar * np.log(n1)))
print(" 로그우도는 k 를 키우면 계속 오릅니다. 221강과 같습니다")
print(" AIC 와 BIC 는 모수 개수에 벌을 주므로 어느 자리에서 돌아섭니다")
print(" BIC 가 벌을 더 세게 주므로 더 작은 k 를 고릅니다")
print(" 덩어리가 정규가 아니면 어떻게 되는지 봅니다")
th = rng.uniform(0, 2 * np.pi, 400)
rr = 3.0 + rng.normal(0, 0.2, 400)
X5 = np.stack([rr * np.cos(th), rr * np.sin(th)], axis=1)
print(" 고리 하나짜리 자료입니다. 정규분포가 아닙니다")
print(" %s %s %s"
% (pw("덩어리 수", 12), rw("평균 로그우도", 20), rw("BIC", 18)))
for k in [1, 2, 4, 8]:
best = None
for _ in range(12):
p_, m_, s_, r_, h_, c_ = em_fit(X5, k, rng, 200, 1e-4)
if best is None or h_[-1] > best[4][-1]:
best = (p_, m_, s_, r_, h_)
npar = k * (2 + 3) + (k - 1)
print(" %s %20.6f %18.6f"
% (pw(str(k), 12), best[4][-1],
-2 * best[4][-1] * 400 + npar * np.log(400)))
print(" 고리를 정규분포 여럿으로 덮습니다. 덩어리 수가 모양을 대신합니다")
print(" 그래서 여기서 나온 덩어리는 참 군집이 아니라 밀도 근사 조각입니다")
print(" 군집으로 쓸 것인지 밀도로 쓸 것인지를 먼저 정해야 합니다")
# --- 문제 5: 실무에서 쓰기 ---------------------------------------------
print(" 혼합모형을 무엇에 쓰는지 정리합니다")
print(" %s %s %s"
% (pw("쓰임", 22), rw("무엇을 쓰나", 24), rw("어디서 다시 보나", 24)))
for a, b, c in [("군집", "가장 큰 소속 확률", "이 강의"),
("밀도 추정", "혼합 밀도 자체", "225강 이상탐지"),
("빠진 값 채우기", "조건부 기댓값", "156강"),
("자료 만들기", "뽑아서 새 점", "S10 생성모형"),
("반지도 학습", "라벨 있는 것과 없는 것", "이 문제")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 24), rw(c, 24)))
print(" 밀도 추정이 이상점 찾기에 쓰이는 것을 봅니다")
p6, m6, s6, r6, h6, c6 = em_fit(X1, 2, rng, 200, 1e-4)
LG6 = np.stack([log_norm(X1, m6[j], s6[j]) + np.log(p6[j])
for j in range(2)], axis=1)
dens = logsumexp(LG6)
out_pts = np.array([[8.0, 8.0], [-5.0, 4.0], [1.5, 1.0]])
LGo = np.stack([log_norm(out_pts, m6[j], s6[j]) + np.log(p6[j])
for j in range(2)], axis=1)
do = logsumexp(LGo)
print(" %s %s %s"
% (pw("어떤 점", 24), rw("로그밀도", 20), rw("학습 자료의 몇 퍼센트 아래", 30)))
for nm, v in [("학습 자료 5 퍼센트 자리", float(np.quantile(dens, 0.05))),
("가운데쯤 점", float(do[2])),
("멀리 떨어진 점", float(do[0])),
("반대쪽 멀리", float(do[1]))]:
pc = float(np.mean(dens < v))
print(" %s %20.6f %30.6f" % (pw(nm, 24), v, pc))
print(" 멀리 떨어진 점의 로그밀도가 아주 낮습니다")
print(" 학습 자료의 밀도 분포에서 몇 퍼센트 자리인지로 이상 여부를 정합니다")
print(" 225강에서 이 방법을 제대로 다룹니다")
print(" 라벨이 조금 있을 때 함께 쓰는 법을 봅니다")
n7 = 600
z7 = rng.integers(0, 2, n7)
mu7 = np.array([[0.0, 0.0], [2.2, 1.6]])
X7 = mu7[z7] + rng.normal(0, 1.0, (n7, 2))
X7t = mu7[rng.integers(0, 2, 2000)] + rng.normal(0, 1.0, (2000, 2))
z7t = np.argmin(((X7t[:, None, :] - mu7[None, :, :]) ** 2).sum(axis=2), axis=1)
def gauss_clf(Xa, ya, Xb):
ms, ss, ps = [], [], []
for j in [0, 1]:
Z = Xa[ya == j]
ms.append(Z.mean(axis=0))
ss.append(np.cov(Z.T) + 1e-4 * np.eye(2))
ps.append(len(Z) / len(ya))
L = np.stack([log_norm(Xb, ms[j], ss[j]) + np.log(ps[j])
for j in [0, 1]], axis=1)
return np.argmax(L, axis=1)
print(" %s %s %s"
% (pw("라벨이 몇 개 있나", 20), rw("라벨만 쓸 때", 20),
rw("라벨 없는 것도 쓸 때", 24)))
for nl in [6, 20, 100]:
idx = np.concatenate([np.where(z7 == 0)[0][:nl // 2],
np.where(z7 == 1)[0][:nl // 2]])
a1 = float(np.mean(gauss_clf(X7[idx], z7[idx], X7t) == z7t))
p8, m8, s8, r8, h8, c8 = em_fit(X7, 2, rng, 200, 1e-4,
"full", X7[idx][[0, nl // 2]])
L8 = np.stack([log_norm(X7t, m8[j], s8[j]) + np.log(p8[j])
for j in [0, 1]], axis=1)
pr = np.argmax(L8, axis=1)
a2 = max(float(np.mean(pr == z7t)), float(np.mean(pr != z7t)))
print(" %s %20.6f %24.6f" % (pw(str(nl), 20), a1, a2))
print(" 라벨이 6 개뿐이면 라벨만으로는 공분산을 못 추정합니다")
print(" 라벨 없는 자료로 모양을 잡고 라벨로 이름만 붙이면 훨씬 낫습니다")
print(" 216강의 생성모형이 표본이 적을 때 강하다고 한 것과 같은 이유입니다")
print(" 마지막으로 세 군집 방법을 한자리에 놓습니다")
print(" %s %s %s %s"
% (pw("무엇", 16), rw("k 평균", 18), rw("밀도 기반", 18),
rw("혼합모형", 20)))
for a, b, c, d in [("배정", "굳음", "굳음", "확률"),
("모양", "공", "아무 모양", "타원"),
("개수", "정함", "안 정함", "정보기준"),
("잡음", "다 넣음", "따로 뺌", "낮은 밀도"),
("밀도를 주나", "아니오", "아니오", "예")]:
print(" %s %s %s %s"
% (pw(a, 16), rw(b, 18), rw(c, 18), rw(d, 20)))
print(" 마지막 줄이 혼합모형만의 것입니다. 새 점의 밀도를 잴 수 있습니다")
print(" 223강은 밀도를 모형으로 적었습니다. 224강은 축을 갈아탑니다")
# 221강은 모양을 가정했고 222강은 안 가정했습니다
# 이번에는 모양을 확률분포로 적습니다
# 무엇 k 평균 혼합모형
# 덩어리가 무엇인가 중심 하나 정규분포 하나
# 배정 가장 가까운 하나 확률로 나눠 가짐
# 모양 언제나 공 공분산이 정함
# 크기 차이 못 다룸 섞임 비율로 다룸
# 무엇을 최대화 제곱합 최소 우도 최대
# 자료가 정규분포 여럿을 섞어 뽑았다고 봅니다
# 먼저 어느 덩어리인지 뽑고 그 다음 그 분포에서 점을 뽑습니다
# 149강의 최대우도를 그대로 쓰는데 덩어리 표시가 안 보입니다
# 안 보이는 표시가 있으면 왜 어려운지 봅니다
# 무엇 표시를 알면 표시를 모르면
# 우도 곱이 갈라짐 합이 로그 안에
# 최대우도 닫힌 해 닫힌 해가 없음
# 풀이 그냥 평균과 공분산 번갈아 풀기
# 무엇이 문제 없음 로그 안의 합
# 표시를 알면 갈래별로 나눠 평균과 공분산을 그냥 구하면 됩니다
# 모르면 로그 안에 합이 들어가 미분해도 안 풀립니다
# 표시를 알 때와 모를 때의 추정을 견줍니다
# 무엇 첫 평균 둘째 평균 참값과의 거리
# 표시를 알 때 0.012667 3.025345 0.186789
# 표시를 모를 때 -0.008524 2.985016 0.198413
# 참값 0.000000 3.000000 0.000000
# 표시를 몰라도 거의 같은 자리를 찾습니다
# 덩어리가 잘 갈리면 안 보이는 표시를 거의 복원할 수 있습니다
# 156강의 결측자료 문제와 같은 구조입니다
# 번갈아 푸는 절차를 세웁니다
# 단계 무엇을 고정하고 무엇을 구하나
# E 단계 모수를 고정 각 점의 소속 확률
# M 단계 소속 확률을 고정 가중 평균과 가중 공분산
# 반복 우도가 안 오를 때까지 반드시 오름
# 221강의 배정과 갱신이 여기서는 확률과 가중으로 바뀝니다
# 배정이 0 아니면 1 이 아니라 0 과 1 사이 값입니다
# 우도가 정말 매번 오르는지 봅니다
# 반복 평균 로그우도 앞 반복 대비 소속 확률의 최대값 평균
# 1 -4.355372 0.000000 0.680591
# 2 -3.353551 1.001821 0.686919
# 3 -3.304156 0.049395 0.740618
# 5 -3.230432 0.029636 0.841910
# 10 -3.167370 0.012517 0.937145
# 31 -3.116413 0.000000 0.976345
# 로그우도가 매번 오르고 어느 자리에서 멈춥니다
# 132강의 젠센 부등식으로 오른다는 것을 증명합니다. 심화 1 에서 봅니다
# k 평균처럼 국소 최대에 갇힐 수 있습니다
# 소속 확률이 무엇을 뜻하는지 봅니다
# 경계에서 먼 점과 가까운 점의 소속 확률을 봅니다
# 어떤 점 첫 덩어리 확률 둘째 덩어리 확률 가장 큰 값
# 가장 애매한 점 0.493988 0.506012 0.506012
# 중간쯤 점 0.999708 0.000292 0.999708
# 가장 확실한 점 1.000000 0.000000 1.000000
# 전체 평균 0.654113 0.345887 0.976344
# 애매한 점은 0.5 근처이고 확실한 점은 1 에 가깝습니다
# k 평균은 이 값을 0 아니면 1 로 강제합니다
# 그래서 k 평균을 굳은 배정 혼합모형이라 부르기도 합니다
# k 평균이 혼합모형의 특수한 경우인지 확인합니다
# 공분산을 같은 구 모양으로 묶고 분산을 0 으로 보내 봅니다
# 분산 고정값 소속 확률의 최대값 평균 k 평균과 같은 배정 비율 순도
# 1.00 0.964052 0.996667 0.945000
# 0.30 0.990105 1.000000 0.945000
# 0.10 0.996328 0.998333 0.946667
# 0.02 0.998983 1.000000 0.945000
# 분산을 줄이면 소속 확률의 최대값이 0.964052 에서 0.998983 으로 오릅니다
# 0 으로 보내면 0 아니면 1 이 됩니다
# 배정도 k 평균과 거의 같아집니다. 0.30 과 0.02 에서는 완전히 같습니다
# k 평균은 혼합모형에서 공분산을 묶고 굳힌 것입니다
# 공분산을 어떻게 두느냐로 모형의 크기가 정해집니다
# 어떻게 두나 모수 개수 어떤 모양 차원 10 갈래 3 이면
# 구 모양 공유 1 같은 크기 공 1
# 구 모양 따로 k 크기 다른 공 3
# 대각 따로 k 곱하기 d 축에 나란한 타원 30
# 완전 따로 k 곱하기 d(d+1)/2 아무 타원 165
# 모수가 많을수록 유연하고 표본이 많이 필요합니다
# 214강의 복잡도 손잡이가 여기서는 공분산의 자유도입니다
# 길쭉한 덩어리에서 세 가지를 견줍니다
# 가로로 길쭉한 띠 둘을 위아래로 놓았습니다
# 공분산 형태 순도 평균 로그우도 모수 개수
# 구 모양 0.516000 -3.210053 7
# 대각 0.974000 -2.902283 9
# 완전 0.974000 -2.901441 11
# k 평균 0.516000 해당 없음 4
# 구 모양 가정은 길쭉한 띠를 못 나눕니다. k 평균과 같은 이유입니다
# 대각과 완전은 축 방향을 다르게 잡을 수 있어 나눕니다
# 221강 문제 4 의 길쭉한 띠 문제가 공분산으로 풀립니다
# 기울어진 덩어리에서는 대각도 모자란지 봅니다
# 45 도로 기울어진 덩어리 둘입니다
# 공분산 형태 순도 평균 로그우도
# 구 모양 0.548000 -3.028916
# 대각 0.504000 -3.027482
# 완전 1.000000 -2.587183
# 기울어진 방향은 완전 공분산이라야 잡습니다
# 대각은 축에 나란한 타원만 그리므로 기울기를 못 씁니다
# 88강의 주성분이 하는 축 회전을 공분산이 대신합니다
# 이 방법이 무너지는 경우를 봅니다
# 무엇 무엇이 일어나나 어떻게 막나
# 특이해 한 점에 분산 0 공분산에 작은 값 더함
# 국소 최대 시작점에 딸림 여러 번 돌림
# 갈래 수 우도로는 못 정함 정보기준이나 교차검증
# 라벨 바꿔치기 번호가 뒤바뀜 번호는 뜻이 없음
# 모양이 정규가 아님 억지로 맞춤 덩어리를 더 씀
# 특이해를 일부러 만들어 봅니다
# 한 덩어리의 중심을 점 하나에 두고 분산을 아주 작게 시작합니다
# 더하는 값 가장 작은 분산 평균 로그우도 그 덩어리가 맡은 유효 개수
# 1e-02 3.037308e-01 -3.116650 392.936744
# 1e-04 3.380781e-04 -3.388533 2.738312
# 1e-06 2.376726e-04 -3.388402 2.746681
# 1e-10 2.366520e-04 -3.388402 2.746681
# 더하는 값이 1e-2 면 분산 바닥이 높아 그 덩어리가 빠져나옵니다
# 유효 개수 392.9 를 맡고 로그우도도 -3.116650 으로 정상 자리입니다
# 1e-4 이하면 세 점 남짓만 맡은 채 분산 0.00024 에 갇힙니다
# 전체 로그우도가 -3.388533 으로 오히려 낮습니다. 국소 최대에 갇힌 것입니다
# 막는 값을 아예 안 두면 분산이 0 으로 가고 그 점의 밀도가 무한이 됩니다
# 211강의 벌점과 같은 장치이고 여기서는 안 갇히게 하는 구실도 합니다
# 갈래 수를 정보기준으로 골라 봅니다
# 참 갈래가 둘인 자료입니다
# k 평균 로그우도 모수 개수 AIC BIC
# 1 -3.396148 5 4085.377169 4107.361817
# 2 -3.116413 11 3761.695559 3810.061786
# 3 -3.108903 17 3764.683498 3839.431302
# 4 -3.102288 23 3768.745439 3869.874822
# 6 -3.095997 35 3785.196126 3939.088664
# 로그우도는 k 를 키우면 계속 오릅니다. 221강과 같습니다
# AIC 와 BIC 는 모수 개수에 벌을 주므로 어느 자리에서 돌아섭니다
# BIC 가 벌을 더 세게 주므로 더 작은 k 를 고릅니다
# 덩어리가 정규가 아니면 어떻게 되는지 봅니다
# 고리 하나짜리 자료입니다. 정규분포가 아닙니다
# 덩어리 수 평균 로그우도 BIC
# 1 -4.341889 3503.468683
# 2 -4.095024 3341.925270
# 4 -3.233581 2724.668148
# 8 -2.782338 2507.469419
# 고리를 정규분포 여럿으로 덮습니다. 덩어리 수가 모양을 대신합니다
# 그래서 여기서 나온 덩어리는 참 군집이 아니라 밀도 근사 조각입니다
# 군집으로 쓸 것인지 밀도로 쓸 것인지를 먼저 정해야 합니다
# 혼합모형을 무엇에 쓰는지 정리합니다
# 쓰임 무엇을 쓰나 어디서 다시 보나
# 군집 가장 큰 소속 확률 이 강의
# 밀도 추정 혼합 밀도 자체 225강 이상탐지
# 빠진 값 채우기 조건부 기댓값 156강
# 자료 만들기 뽑아서 새 점 S10 생성모형
# 반지도 학습 라벨 있는 것과 없는 것 이 문제
# 밀도 추정이 이상점 찾기에 쓰이는 것을 봅니다
# 어떤 점 로그밀도 학습 자료의 몇 퍼센트 아래
# 학습 자료 5 퍼센트 자리 -5.091277 0.050000
# 가운데쯤 점 -3.038086 0.488333
# 멀리 떨어진 점 -39.102802 0.000000
# 반대쪽 멀리 -51.948897 0.000000
# 멀리 떨어진 점의 로그밀도가 아주 낮습니다
# 학습 자료의 밀도 분포에서 몇 퍼센트 자리인지로 이상 여부를 정합니다
# 225강에서 이 방법을 제대로 다룹니다
# 라벨이 조금 있을 때 함께 쓰는 법을 봅니다
# 라벨이 몇 개 있나 라벨만 쓸 때 라벨 없는 것도 쓸 때
# 6 0.742500 0.960000
# 20 0.948500 0.960000
# 100 0.994000 0.960000
# 라벨이 6 개뿐이면 라벨만으로는 공분산을 못 추정합니다
# 라벨 없는 자료로 모양을 잡고 라벨로 이름만 붙이면 훨씬 낫습니다
# 216강의 생성모형이 표본이 적을 때 강하다고 한 것과 같은 이유입니다
# 마지막으로 세 군집 방법을 한자리에 놓습니다
# 무엇 k 평균 밀도 기반 혼합모형
# 배정 굳음 굳음 확률
# 모양 공 아무 모양 타원
# 개수 정함 안 정함 정보기준
# 잡음 다 넣음 따로 뺌 낮은 밀도
# 밀도를 주나 아니오 아니오 예
# 마지막 줄이 혼합모형만의 것입니다. 새 점의 밀도를 잴 수 있습니다
# 223강은 밀도를 모형으로 적었습니다. 224강은 축을 갈아탑니다