강과 강은 변수가 많을 때 어떻게 벌점을 걸고 를 고를지를 봤습니다. 그런데 근본 질문이 남습니다.
"자료가 부족해진다"는 대답으로는 부족합니다. 얼마나 부족해지는지, 왜 부족해지는지를 알아야 무엇을 해야 할지 정할 수 있습니다.
그런데 이 강의의 절반은 반대 이야기입니다. 실제 자료에서는 변수가 수천 개여도 잘 되는 경우가 많고, 그 이유도 수치로 확인합니다.
문제. 고차원 공간의 부피를 봅니다.
() 정육면체에 든 공의 비율을 재세요.
() 공 안에서 부피가 어디에 있는지 보세요.
() 실제로 점을 뽑아 거리를 재세요.
생각의 실마리. 차원이 하나 늘 때마다 곱해지는 것이 생깁니다. 비율이 보다 작으면 곱할수록 으로 가고, 그 속도가 지수입니다.
풀이. () 한 변이 인 정육면체에 꼭 맞는 공(반지름 )을 넣고 비율을 잽니다.
| 차원 | 공의 부피 | 정육면체 부피 | 비율의 상용로그 |
|---|---|---|---|
차원 에서는 비율이 의 마이너스 제곱 근처입니다. 공이 사실상 아무것도 안 차지합니다.
그러면 부피는 어디로 갔습니까. 모서리입니다. 차원 정육면체의 모서리는 개이고, 차원이 오를수록 부피가 전부 그쪽으로 갑니다.
() 공 안에서도 부피가 어디에 있는지 봅니다. 반지름 안쪽의 비율은 입니다.
| 차원 | 반지름 안쪽의 비율 | 바깥 퍼센트 껍질의 비율 |
|---|---|---|
반지름을 퍼센트만 줄여도 차원 에서는 부피가 거의 다 사라집니다. 부피가 껍질에 몰린다는 것은 뽑은 점들이 다 바깥에 있다는 뜻입니다.
() 실제로 표준정규에서 점을 뽑아 원점까지의 거리를 잽니다.
| 차원 | 평균 거리 | 표준편차 | 표준편차 나누기 평균 |
|---|---|---|---|
평균 거리는 에 비례해 자랍니다. 이고 잰 값이 입니다.
표준편차는 차원과 거의 무관하게 근처로 일정합니다. 그래서 상대적 흩어짐이 에서 로 줄어듭니다.
모든 점이 원점에서 거의 같은 거리에 있습니다. 두께가 일정한 껍질에 전부 얹혀 있는 셈입니다.
이 문제에서 배우는 것. 고차원에서 공간은 텅 비고 점들은 껍질에 몰립니다. 부피 비율이 제곱으로 줄기 때문이고, 이것은 자료의 성질이 아니라 공간 자체의 성질입니다.
확인 1-1. 고차원 정육면체에서 부피가 어디에 몰리는지 쓰세요.
답. 모서리에 몰립니다.
확인 1-2. 검산에서 차원 일 때 공의 부피 비율의 상용로그를 쓰세요.
답. 입니다.
확인 1-3. 검산에서 차원 일 때 평균 거리와 표준편차를 쓰세요.
답. 과 입니다.
문제. 거리 기반 방법이 왜 무너지는지 봅니다.
() 가장 가까운 점과 가장 먼 점의 비를 재세요.
() 이웃 방법이 실제로 얼마나 나빠지는지 재세요.
() 같은 밀도를 지키려면 표본이 몇 개 필요한지 세세요.
생각의 실마리. 문제 에서 모든 점이 같은 껍질에 있다고 했습니다. 어떤 기준점에서 봐도 마찬가지라면, 가장 가까운 점과 가장 먼 점의 차이가 없어집니다.
풀이. () 점 개를 뽑고 기준점 하나에서의 거리를 잽니다.
| 차원 | 가장 가까운 거리 | 가장 먼 거리 | 먼 것 나누기 가까운 것 |
|---|---|---|---|
차원 에서는 가장 먼 점이 가장 가까운 점보다 배 멉니다. 차원 에서는 배입니다.
"가장 가까운 이웃"이라는 말이 뜻을 잃습니다. 개 중 등과 등의 차이가 퍼센트뿐이면, 그 등을 고르는 것이 정보가 아니라 잡음입니다.
() 이웃 방법이 실제로 얼마나 나빠지는지 잽니다. 참 함수는 앞의 두 변수만 쓰고 나머지는 잡음입니다.
| 변수 수 | 가장 가까운 이웃 오차 | 참 변수만 썼을 때 | 몇 배 나쁜가 |
|---|---|---|---|
참 정보는 하나도 안 늘었는데 오차가 배가 됐습니다. 잡음 변수 개가 거리를 끌고 다니므로 이웃이 엉뚱한 점을 가리킵니다.
강의 변수 선택이 여기서 성능 문제가 됩니다. 쓸모없는 변수를 지우는 것이 취향이 아니라 필수입니다.
() 같은 밀도를 지키려면 표본이 몇 개 필요한지 셉니다. 한 변을 칸으로 쪼개면 칸 수가 입니다.
| 차원 | 칸 수 | 칸마다 개면 필요한 표본 |
|---|---|---|
차원 이면 표본이 억 개 필요합니다. 변수 열 개는 실무에서 적은 편인데도 그렇습니다.
이것이 차원의 저주라는 이름이 붙은 이유입니다. 필요한 표본이 차원에 대해 지수로 늘어납니다.
이 문제에서 배우는 것. 거리에 기대는 방법은 고차원에서 원리적으로 무너집니다. 알고리즘을 개선해서 될 일이 아니고, 거리를 재는 축을 줄이거나 다른 구조를 가정해야 합니다.
확인 2-1. 고차원에서 "가장 가까운 이웃"이 왜 뜻을 잃는지 쓰세요.
답. 가장 가까운 점과 가장 먼 점의 거리가 거의 같아지기 때문입니다.
확인 2-2. 검산에서 차원 과 일 때 먼 것 나누기 가까운 것을 쓰세요.
답. 과 입니다.
확인 2-3. 검산에서 변수 개일 때 이웃 오차가 몇 배 나쁜지 쓰세요.
답. 배입니다.
문제. 집중 현상을 정리합니다.
() 네 가지 형태를 정리하세요.
() 무작위 두 벡터의 각도를 재세요.
() 구면 위 좌표가 얼마나 몰리는지 재세요.
생각의 실마리. 지금까지 본 것은 모두 **"흩어져 있을 것 같은데 실제로는 한곳에 몰려 있다"**는 이야기입니다. 이 현상에 이름이 있습니다.
풀이. () 네 가지 형태를 정리합니다.
| 무엇 | 무엇이 일어나나 | 어디서 봤나 |
|---|---|---|
| 부피의 집중 | 껍질로 몰림 | 문제 |
| 거리의 집중 | 다 비슷해짐 | 문제 |
| 각도의 집중 | 거의 직교함 | 곧 봅니다 |
| 함수값의 집중 | 평균 근처로 몰림 | 곧 봅니다 |
넷을 묶어 측도의 집중이라 합니다. 고차원에서는 매끄러운 함수의 값이 거의 상수가 됩니다.
() 무작위 두 벡터의 각도를 잽니다.
| 차원 | 평균 코사인 | 코사인의 표준편차 | 도에서 도 사이 비율 |
|---|---|---|---|
코사인의 표준편차가 로 줄어듭니다. 이고 잰 값이 입니다.
차원 에서는 쌍이 전부 도에서 도 사이입니다. 아무렇게나 뽑은 두 벡터가 거의 언제나 직교에 가깝습니다.
이것이 무작위 벡터가 서로 간섭하지 않는 이유입니다. 고차원에는 거의 직교인 방향이 아주 많이 들어갑니다. 문제 의 무작위 사영이 통하는 근거가 여기입니다.
() 구면 위 좌표가 얼마나 몰리는지 잽니다.
| 차원 | 첫 좌표의 표준편차 | 나누기 루트 | 둘의 비 |
|---|---|---|---|
단위 구면 위에서 좌표 하나는 폭 안에 갇힙니다. 구면의 반지름은 인데 좌표는 근처에서만 논다는 뜻입니다.
차원이 크면 구면의 거의 전부가 적도 근처에 있습니다. 어느 축을 적도로 잡아도 그렇습니다.
리프시츠 함수는 다 이렇게 집중합니다. 좌표 함수는 리프시츠 상수 인 함수이고, 일반적으로 리프시츠 상수 인 함수는 평균에서 이상 벗어날 확률이 이하입니다. 이것이 집중 부등식의 내용입니다.
이 문제에서 배우는 것. 고차원의 이상함은 흩어진 사례들이 아니라 하나의 현상입니다. 매끄러운 함수가 거의 상수가 되고, 그래서 차이를 보고 판단하는 방법이 다 어려워집니다.
확인 3-1. 측도의 집중을 한 문장으로 쓰세요.
답. 고차원에서 매끄러운 함수의 값이 거의 상수가 되는 현상입니다.
확인 3-2. 검산에서 차원 일 때 코사인의 표준편차를 쓰세요.
답. 입니다.
확인 3-3. 검산에서 차원 일 때 구면 첫 좌표의 표준편차와 를 쓰세요.
답. 과 입니다.
문제. 왜 실제로는 잘 되는지 봅니다.
() 겉보기 차원과 내재 차원을 구분하세요.
() 내재 차원을 실제로 재세요.
() 내재 차원이 낮으면 이웃 방법이 되살아나는지 보세요.
생각의 실마리. 문제 부터 까지는 점이 공간 전체에 고르게 퍼져 있다고 가정했습니다. 실제 자료는 그렇지 않습니다. 사진의 화소는 만 개인데 가능한 화소 조합 대부분은 사진이 아닙니다.
풀이. () 구분합니다.
| 무엇 | 겉보기 차원 | 실제로 몇 차원인가 |
|---|---|---|
| 한 직선 위의 점 | ||
| 한 평면 위의 점 | ||
| 굽은 곡면 위의 점 | 곡면의 매개변수 수 | |
| 성긴 벡터 | 이 아닌 개수 |
겉보기 차원이 아니라 내재 차원이 어려움을 정합니다.
() 내재 차원을 실제로 잽니다. 차원 공간에 네 가지 자료를 놓습니다.
| 자료 | 겉보기 차원 | 특이값 퍼센트 | 상관 차원 |
|---|---|---|---|
| 직선 위 | |||
| 평면 위 | |||
| 굽은 띠 위 | |||
| 진짜 차원 |
굽은 띠의 매개변수는 각도와 높이 둘이므로 참 내재 차원이 입니다. 그런데 특이값은 으로 셉니다. 굽은 것을 곧게 펴서 볼 수 없기 때문입니다.
상관 차원은 평면을 로, 굽은 띠를 으로 냅니다. 거리 분포의 기울기로 재므로 굽어도 잡습니다.
다만 진짜 차원을 로 크게 모자라게 셉니다. 상관 차원도 높은 차원에서는 점이 지수로 모자랍니다. 차원을 재는 것 자체가 차원의 저주에 걸립니다.
강의 주성분이 직선 구조에만 맞는 도구인 이유가 셋째 줄입니다.
() 내재 차원이 낮으면 이웃 방법이 되살아나는지 봅니다.
| 자료 | 의 분산 | 가장 가까운 이웃 오차 | 분산 대비 비율 |
|---|---|---|---|
| 차원인데 내재 차원 | |||
| 진짜 차원 |
의 분산이 다르므로 마지막 열로 견줍니다. 비율이 이면 의 평균을 내놓는 것과 다를 바 없다는 뜻입니다.
내재 차원이 이면 차원이어도 비율이 입니다. 진짜 차원에서는 로 평균보다도 나쁩니다.
저주는 겉보기 차원이 아니라 내재 차원에 걸립니다.
이 문제에서 배우는 것. 변수가 많다는 사실만으로 겁먹을 필요가 없습니다. 물어야 할 것은 **"자료가 그 공간을 실제로 채우고 있는가"**입니다. 대부분의 실제 자료는 채우지 않고, 그래서 고차원 방법이 작동합니다.
확인 4-1. 겉보기 차원과 내재 차원 중 무엇이 어려움을 정하는지 쓰세요.
답. 내재 차원이 정합니다.
확인 4-2. 검산에서 굽은 띠의 특이값 퍼센트와 상관 차원을 쓰세요.
답. 과 입니다.
확인 4-3. 검산에서 두 자료의 분산 대비 비율을 쓰세요.
답. 과 입니다.
문제. 대응 수단을 정리합니다.
() 수단을 정리하세요.
() 무작위 사영이 거리를 얼마나 지키는지 재세요.
() 흔한 오해를 바로잡으세요.
생각의 실마리. 문제 에서 내재 차원이 낮으면 괜찮다고 했습니다. 그러면 내재 차원을 찾아내거나, 낮은 것처럼 쓰는 방법이 대응 수단입니다.
풀이. () 정리합니다.
| 수단 | 무엇을 하나 | 어디서 배웠나 |
|---|---|---|
| 변수 선택 | 쓸 것만 남김 | 강 라소 |
| 차원 축소 | 축을 갈아탐 | 강 주성분 |
| 무작위 사영 | 차원만 줄임 | 이 강의 문제 |
| 구조 가정 | 매끄럽다고 가정 | 강 이후 |
| 거리 대신 다른 것 | 각도나 성긴 겹침 | 문제 |
다섯 가지가 모두 실제 차원을 낮추거나 낮은 것처럼 쓰는 방법입니다.
() 무작위 사영을 재 봅니다. 차원 점 개를 무작위 행렬로 낮은 차원에 던집니다.
| 사영 차원 | 거리비의 평균 | 가장 큰 어긋남 | 이론 문턱 |
|---|---|---|---|
필요한 차원이 원래 차원과 무관합니다. 이든 만이든 상관없이 점의 개수의 로그로만 자랍니다.
평균은 어느 줄에서나 에 가깝습니다. 사영이 거리를 평균적으로는 잘 지킵니다.
그런데 가장 나쁜 쌍은 차원에서 퍼센트나 어긋납니다. 보조정리가 약속하는 것은 평균이 아니라 최악이고, 그 상한이 마지막 열의 입니다. 실제 어긋남이 문턱보다 작으므로 약속은 지켜졌습니다.
이 표를 읽을 때 평균 열만 보고 안심하면 안 됩니다. 이웃 탐색처럼 최악의 쌍이 답을 정하는 문제에서는 문턱 쪽을 봐야 합니다.
() 흔한 오해를 바로잡습니다.
| 흔한 오해 | 실제로는 |
|---|---|
| 변수가 많으면 무조건 나쁘다 | 내재 차원이 낮으면 괜찮다 |
| 차원 축소는 언제나 이득이다 | 쓸 축을 지울 수 있다 |
| 거리가 크면 다른 것이다 | 높은 차원에서는 다 크다 |
| 표본을 늘리면 해결된다 | 필요한 수가 지수로 는다 |
둘째 줄을 조심해야 합니다. 주성분은 분산이 큰 축을 남기는데, 를 설명하는 축이 분산이 작을 수 있습니다. 강 문제 에서 본 대로 정보가 있는 방향과 분산이 큰 방향은 다릅니다.
이 문제에서 배우는 것. 대응 수단은 모두 차원을 실제로 낮추는 것입니다. 그런데 무엇을 지울지는 자료가 아니라 문제가 정합니다. 분산만 보고 지우면 쓸 축을 지울 수 있습니다.
확인 5-1. 무작위 사영에 필요한 차원이 무엇으로 정해지는지 쓰세요.
답. 점의 개수의 로그로 정해지고 원래 차원과 무관합니다.
확인 5-2. 검산에서 사영 차원 일 때 가장 큰 어긋남과 이론 문턱을 쓰세요.
답. 과 입니다.
확인 5-3. 차원 축소가 손해가 될 수 있는 경우를 쓰세요.
답. 분산이 작지만 를 설명하는 축을 지울 때입니다.
| 유형 | 무엇을 묻나 | 어디를 보나 |
|---|---|---|
| 부피의 소멸 | 공이 정육면체의 몇 퍼센트인가 | 문제 |
| 껍질 집중 | 점이 어디에 있나 | 문제 |
| 거리의 무의미 | 가까운 것과 먼 것의 비 | 문제 |
| 필요 표본 | 지수로 늘어남 | 문제 |
| 각도의 집중 | 거의 직교 | 문제 |
| 집중 부등식 | 리프시츠 함수가 거의 상수 | 문제 |
| 내재 차원 | 겉보기와 다름 | 문제 |
| 상관 차원 | 거리 분포의 기울기 | 문제 |
| 무작위 사영 | 로그로만 자람 | 문제 |
| 축소의 위험 | 쓸 축을 지울 수 있음 | 문제 |
핵심 크기를 한자리에 모읍니다.
| 무엇 | 차원에 따라 | 결과 |
|---|---|---|
| 평균 거리 | 로 자람 | 다 멀어짐 |
| 거리의 표준편차 | 일정 | 다 비슷해짐 |
| 코사인의 표준편차 | 1/\sqrt | 거의 직교 |
| 필요 표본 | c^ | 저주 |
| 사영에 필요한 차원 | \log n/\varepsilon^ | 축복 |
문제 6. 고차원 정육면체에서 부피가 어디에 몰리는지 쓰세요.
답. 모서리에 몰립니다.
문제 7. 검산에서 차원 일 때 공의 부피 비율의 상용로그를 쓰세요.
답. 입니다.
문제 8. 검산에서 차원 일 때 평균 거리와 표준편차를 쓰세요.
답. 과 입니다.
문제 9. 검산에서 차원 과 일 때 먼 것 나누기 가까운 것을 쓰세요.
답. 과 입니다.
문제 10. 검산에서 변수 개일 때 이웃 오차가 몇 배 나쁜지 쓰세요.
답. 배입니다.
문제 11. 검산에서 차원 일 때 칸마다 개면 필요한 표본을 쓰세요.
답. 억 개입니다.
문제 12. 검산에서 차원 일 때 코사인의 표준편차를 쓰세요.
답. 입니다.
문제 13. 검산에서 차원 일 때 구면 첫 좌표의 표준편차를 쓰세요.
답. 입니다.
문제 14. 검산에서 굽은 띠의 특이값 퍼센트와 상관 차원을 쓰세요.
답. 과 입니다.
문제 15. 검산에서 진짜 차원의 상관 차원을 쓰고 무엇을 뜻하는지 쓰세요.
답. 이고 상관 차원도 높은 차원에서는 크게 모자라게 센다는 뜻입니다.
문제 16. 검산에서 두 자료의 분산 대비 이웃 오차 비율을 쓰세요.
답. 과 입니다.
문제 17. 검산에서 사영 차원 일 때 가장 큰 어긋남과 이론 문턱을 쓰세요.
답. 과 입니다.
문제 18. 차원 축소가 손해가 될 수 있는 경우를 쓰세요.
답. 분산이 작지만 를 설명하는 축을 지울 때입니다.
심화 1. 공의 부피가 왜 최대가 되는 차원이 있는지 설명하세요.
반지름 인 공의 부피는 에서 최대이고 그 뒤로 줄어 으로 갑니다.
| 무엇 | 언제 |
|---|---|
| 비가 보다 큼 | |
| 비가 보다 작음 | |
| 최대 | 근처 |
감마 함수가 지수보다 빨리 자라기 때문입니다. 는 지수로 자라지만 은 계승처럼 자라므로, 어느 지점부터 분모가 이깁니다. 반지름을 로 두면 가 더 붙어 처음부터 줄어듭니다.
심화 2. 거리의 표준편차가 왜 차원과 무관한지 유도하세요.
는 자유도 인 카이제곱이므로 평균 , 분산 입니다. 제곱근을 델타법으로 근사합니다.
| 무엇 | 값 |
|---|---|
| 표준편차의 근사 | |
| 검산의 차원 | |
| 상대적 흩어짐 | 1/\sqrt |
가 약분되어 사라집니다. 강의 델타법이 여기서 쓰였고, 상대적 흩어짐이 이므로 차원 에서 이며 검산의 와 맞습니다.
심화 3. 성긴 구조에서는 왜 저주가 약해지는지 설명하세요.
개 중 개만 이 아니면, 가능한 위치가 개이고 그 로그가 정도입니다.
| 무엇 | 필요한 표본 |
|---|---|
| 조밀한 차원 | c^ |
| 개만 성김 | |
| , |
지수가 로그로 바뀝니다. 강의 라소가 변수 개에 표본 개로 통했던 것이 이 계산의 결과입니다. 자료가 정보를 담는 방식이 성기면 저주가 걸리지 않습니다.
심화 4. 매끄러움 가정이 무엇을 사는지 설명하세요.
참 함수가 번 미분 가능하면 비모수 회귀의 최적 수렴 속도가 이렇습니다.
| 속도 | ||
|---|---|---|
| n^ | ||
| n^ | ||
| n^ | ||
| 아무거나 | 에 가까움 |
가 지수 자리에 있으므로 매끄러움을 더 가정할수록 그 영향이 희석됩니다. 매끄러움은 공짜가 아닙니다. 참 함수가 실제로 그만큼 매끄럽지 않으면 편향이 남습니다.
심화 5. 무작위 사영이 왜 통하는지 문제 과 이어 설명하세요.
문제 에서 고차원의 무작위 벡터가 거의 직교한다고 했습니다. 사영 행렬 의 행 개가 거의 직교인 방향이므로, 사영은 거의 정규직교 기저로의 정사영처럼 행동합니다.
| 무엇 | 어디서 |
|---|---|
| 평균이 보존됨 | 의 분산을 로 잡았음 |
| 분산이 | 자유도 인 카이제곱 |
| 쌍이 개 | 합집합 상계에 이 들어옴 |
셋째 줄이 의 출처입니다. 한 쌍이 어긋날 확률이 이고 쌍이 개이므로, 전부 성립하려면 이면 됩니다.
심화 6. 고차원의 축복이라 부르는 것을 정리하세요.
집중은 나쁘기만 한 것이 아닙니다.
| 무엇 | 왜 축복인가 |
|---|---|
| 무작위 사영 | 차원과 무관하게 줄임 |
| 거의 직교인 방향이 많음 | 신호를 겹치지 않게 담음 |
| 함수값이 집중 | 표본 하나로도 평균을 잼 |
| 최적화가 쉬워짐 | 안장점이 국소 최소보다 훨씬 많음 |
넷째 줄이 S의 주제로 이어집니다. 강에서 본 볼록성이 없어도 고차원 신경망이 학습되는 이유 중 하나가 고차원에서는 모든 방향이 위로 굽은 점이 드물다는 것입니다. 무작위 대칭 행렬의 고유값이 전부 양수일 확률이 차원에 대해 지수로 줄어들기 때문입니다.
정답.
| 기호 | 읽는 법 | 뜻 |
|---|---|---|
| 차원의 저주 | curse of dimensionality | 필요한 표본이 지수로 늘어납니다 |
| 측도의 집중 | concentration of measure | 매끄러운 함수가 거의 상수가 됩니다 |
| 겉보기 차원 | ambient dimension | 자료가 놓인 공간의 차원입니다 |
| 내재 차원 | intrinsic dimension | 자료가 실제로 퍼진 차원입니다 |
| 상관 차원 | correlation dimension | 거리 분포의 기울기로 잰 차원입니다 |
| 다양체 가정 | manifold hypothesis | 자료가 낮은 차원 곡면 위에 있다는 가정입니다 |
| 무작위 사영 | random projection | 무작위 행렬로 차원을 줄입니다 |
| 존슨 린덴스트라우스 | Johnson-Lindenstrauss | 거리를 지키는 데 필요한 차원의 상계입니다 |
| 리프시츠 함수 | Lipschitz function | 기울기가 위로 막힌 함수입니다 |
| 고차원의 축복 | blessing of dimensionality | 집중이 도움이 되는 경우입니다 |
다음은 214강 모델 복잡도와 과적합입니다. 이 강의가 왜 어려워지는지를 봤습니다. 다음 강의는 어려움을 재는 눈금을 만듭니다.
import numpy as np
rng = np.random.default_rng(20261101)
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 lgam(x):
# 램천 근사로 로그 감마를 직접 구합니다 (numpy 만 씁니다)
g = 7.0
c = np.array([0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6,
1.5056327351493116e-7])
x = float(x) - 1.0
a = c[0]
t = x + g + 0.5
for i in range(1, 9):
a += c[i] / (x + i)
return 0.5 * np.log(2 * np.pi) + (x + 0.5) * np.log(t) - t + np.log(a)
def log_vol_ball(d, r=1.0):
return (d / 2.0) * np.log(np.pi) - lgam(d / 2.0 + 1.0) + d * np.log(r)
# --- 문제 1: 부피가 어디로 가는가 ---------------------------------------
print(" 변수를 하나 늘리는 것이 왜 자료를 갑자기 부족하게 만드는지 봅니다")
print(" 먼저 정육면체 안에 든 공의 부피 비율을 봅니다")
print(" %s %s %s %s"
% (pw("차원", 10), rw("공의 부피", 18), rw("정육면체 부피", 16),
rw("비율의 상용로그", 20)))
for d in [1, 2, 3, 5, 10, 20, 50, 100]:
lv = log_vol_ball(d, 0.5)
print(" %s %18.10f %16.6f %20.6f"
% (pw(str(d), 10), float(np.exp(lv)), 1.0,
float(lv / np.log(10.0))))
print(" 한 변이 1 인 정육면체에 꼭 맞는 공을 넣습니다")
print(" 차원 100 에서는 비율이 10 의 마이너스 70 제곱 근처입니다")
print(" 차원이 오르면 공이 사실상 아무것도 안 차지합니다")
print(" 부피가 모서리 쪽으로 갑니다. 모서리는 2 의 d 제곱 개입니다")
print(" 공 안에서도 부피가 껍질로 몰립니다")
print(" %s %s %s"
% (pw("차원", 10), rw("반지름 0.9 안쪽의 비율", 26),
rw("바깥 10 퍼센트 껍질의 비율", 30)))
for d in [1, 2, 5, 10, 50, 200]:
inner = 0.9 ** d
print(" %s %26.10f %30.10f"
% (pw(str(d), 10), inner, 1.0 - inner))
print(" 반지름을 10 퍼센트만 줄여도 차원 200 에서는 거의 다 사라집니다")
print(" 부피가 껍질에 몰린다는 것은 점들이 다 바깥에 있다는 뜻입니다")
print(" 실제로 점을 뽑아 원점까지의 거리를 봅니다")
print(" %s %s %s %s"
% (pw("차원", 10), rw("평균 거리", 16), rw("표준편차", 16),
rw("표준편차 나누기 평균", 24)))
for d in [1, 2, 10, 100, 1000]:
P = rng.normal(0, 1, (4000, d))
r = np.sqrt((P ** 2).sum(axis=1))
print(" %s %16.6f %16.6f %24.6f"
% (pw(str(d), 10), float(r.mean()), float(r.std()),
float(r.std() / r.mean())))
print(" 평균 거리는 차원의 제곱근에 비례해 자랍니다")
print(" 표준편차는 차원과 거의 무관하게 일정합니다")
print(" 그래서 상대적 흩어짐이 0 으로 갑니다. 모든 점이 같은 껍질에 있습니다")
# --- 문제 2: 거리가 뜻을 잃습니다 ---------------------------------------
print(" 거리로 이웃을 찾는 방법이 왜 무너지는지 봅니다")
print(" %s %s %s %s"
% (pw("차원", 10), rw("가장 가까운 거리", 20), rw("가장 먼 거리", 18),
rw("먼 것 나누기 가까운 것", 26)))
for d in [1, 2, 5, 20, 100, 1000]:
P = rng.normal(0, 1, (500, d))
q = rng.normal(0, 1, d)
dist = np.sqrt(((P - q) ** 2).sum(axis=1))
print(" %s %20.6f %18.6f %26.6f"
% (pw(str(d), 10), float(dist.min()), float(dist.max()),
float(dist.max() / dist.min())))
print(" 차원 1 에서는 가장 먼 점이 가장 가까운 점보다 수백 배 멉니다")
print(" 차원 1000 에서는 1.2 배도 안 됩니다. 다 비슷하게 멉니다")
print(" 가장 가까운 이웃이라는 말이 뜻을 잃습니다")
print(" 이웃 기반 방법이 실제로 얼마나 나빠지는지 잽니다")
print(" 참 함수는 앞의 두 변수만 씁니다. 나머지는 잡음입니다")
print(" %s %s %s %s"
% (pw("변수 수", 12), rw("가장 가까운 이웃 오차", 24),
rw("참 변수만 썼을 때", 22), rw("몇 배 나쁜가", 16)))
n2 = 500
def knn_err(d, k=1):
Xa = rng.uniform(-1, 1, (n2, d))
ya = np.sin(3 * Xa[:, 0]) + Xa[:, 1] ** 2
Xb = rng.uniform(-1, 1, (500, d))
yb = np.sin(3 * Xb[:, 0]) + Xb[:, 1] ** 2
dd = ((Xb[:, None, :] - Xa[None, :, :]) ** 2).sum(axis=2)
idx = np.argsort(dd, axis=1)[:, :k]
pr = ya[idx].mean(axis=1)
return float(np.mean((yb - pr) ** 2))
e_two = knn_err(2)
for d in [2, 5, 10, 30, 100]:
e_all = knn_err(d)
print(" %s %24.6f %22.6f %16.6f"
% (pw(str(d), 12), e_all, e_two, e_all / e_two))
print(" 참 변수만 썼을 때는 어느 줄이나 같은 값입니다. 기준선이기 때문입니다")
print(" 첫 줄이 정확히 1 이 아닌 것은 자료를 따로 뽑았기 때문입니다")
print(" 쓸모없는 변수를 더할수록 이웃이 엉뚱한 점을 가리킵니다")
print(" 거리가 잡음 변수 98 개에 끌려다니기 때문입니다")
print(" 211강의 변수 선택이 여기서 성능 문제가 됩니다")
print(" 같은 밀도를 지키려면 표본이 몇 개 필요한지 셉니다")
print(" 한 변을 10 칸으로 쪼갠다고 하면 칸 수가 10 의 d 제곱입니다")
print(" %s %s %s"
% (pw("차원", 10), rw("칸 수", 24), rw("칸마다 10 개면 필요한 표본", 30)))
for d in [1, 2, 3, 5, 10]:
print(" %s %24.0f %30.0f"
% (pw(str(d), 10), 10.0 ** d, 10.0 ** (d + 1)))
print(" 차원 10 이면 표본이 100 억 개 필요합니다")
print(" 이것이 차원의 저주라는 이름이 붙은 이유입니다")
# --- 문제 3: 측도의 집중 ------------------------------------------------
print(" 거리가 다 비슷해지는 현상을 정리해 부릅니다")
print(" %s %s %s"
% (pw("무엇", 22), rw("무엇이 일어나나", 24), rw("어디서 봤나", 20)))
for a, b, c in [("부피의 집중", "껍질로 몰림", "문제 1"),
("거리의 집중", "다 비슷해짐", "문제 2"),
("각도의 집중", "거의 직교함", "곧 봅니다"),
("함수값의 집중", "평균 근처로 몰림", "곧 봅니다")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 24), rw(c, 20)))
print(" 넷을 묶어 측도의 집중이라 합니다")
print(" 무작위 두 벡터의 각도를 봅니다")
print(" %s %s %s %s"
% (pw("차원", 10), rw("평균 코사인", 16), rw("코사인의 표준편차", 22),
rw("80 도에서 100 도 사이 비율", 30)))
for d in [2, 5, 20, 100, 1000]:
A = rng.normal(0, 1, (3000, d))
B = rng.normal(0, 1, (3000, d))
cs = ((A * B).sum(axis=1)
/ (np.sqrt((A ** 2).sum(axis=1)) * np.sqrt((B ** 2).sum(axis=1))))
near = float(np.mean(np.abs(cs) < np.cos(np.deg2rad(80))))
print(" %s %16.6f %22.6f %30.6f"
% (pw(str(d), 10), float(cs.mean()), float(cs.std()), near))
print(" 코사인의 표준편차가 차원의 제곱근에 반비례해 줄어듭니다")
print(" 차원 1000 에서는 거의 모든 쌍이 직교에 가깝습니다")
print(" 이것이 무작위 벡터가 서로 간섭하지 않는 이유입니다")
print(" 구면 위 함수값이 얼마나 몰리는지 봅니다")
print(" 좌표 하나를 봅니다. 구면 위에서 뽑아 반지름 1 로 맞춥니다")
print(" %s %s %s %s"
% (pw("차원", 10), rw("첫 좌표의 표준편차", 22), rw("1 나누기 루트 d", 20),
rw("둘의 비", 14)))
for d in [2, 10, 100, 1000]:
S = rng.normal(0, 1, (5000, d))
S = S / np.sqrt((S ** 2).sum(axis=1))[:, None]
sd = float(S[:, 0].std())
ref = 1.0 / np.sqrt(d)
print(" %s %22.6f %20.6f %14.6f"
% (pw(str(d), 10), sd, ref, sd / ref))
print(" 구면 위에서 좌표 하나는 폭 1 나누기 루트 d 안에 갇힙니다")
print(" 차원이 크면 구면의 거의 전부가 적도 근처에 있습니다")
print(" 리프시츠 함수는 다 이렇게 집중합니다. 이것이 집중 부등식의 내용입니다")
# --- 문제 4: 저주가 안 통하는 경우 --------------------------------------
print(" 그런데 실제 자료에서는 차원이 커도 잘 되는 경우가 많습니다")
print(" 까닭은 자료가 낮은 차원 구조 위에 있기 때문입니다")
print(" %s %s %s"
% (pw("무엇", 22), rw("겉보기 차원", 16), rw("실제로 몇 차원인가", 24)))
for a, b, c in [("한 직선 위의 점", "60", "1"),
("한 평면 위의 점", "60", "2"),
("굽은 곡면 위의 점", "60", "곡면의 매개변수 수"),
("성긴 벡터", "60", "0 이 아닌 개수")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 16), rw(c, 24)))
print(" 겉보기 차원이 아니라 내재 차원이 어려움을 정합니다")
print(" 내재 차원을 실제로 재 봅니다")
print(" %s %s %s %s"
% (pw("자료", 24), rw("겉보기 차원", 14), rw("특이값 95 퍼센트", 20),
rw("상관 차원", 14)))
def corr_dim(P):
m = min(len(P), 600)
Q = P[:m]
dd = np.sqrt(((Q[:, None, :] - Q[None, :, :]) ** 2).sum(axis=2))
iu = np.triu_indices(m, 1)
v = np.sort(dd[iu])
r1, r2 = v[int(0.05 * len(v))], v[int(0.30 * len(v))]
c1, c2 = 0.05, 0.30
return float(np.log(c2 / c1) / np.log(r2 / r1))
def sv95(P):
s = np.linalg.svd(P - P.mean(axis=0), compute_uv=False)
e = np.cumsum(s ** 2) / (s ** 2).sum()
return int(np.searchsorted(e, 0.95) + 1)
D0 = 60
t = rng.uniform(0, 1, (1200, 1))
lin = t @ rng.normal(0, 1, (1, D0)) + rng.normal(0, 0.01, (1200, D0))
pl = rng.uniform(0, 1, (1200, 2)) @ rng.normal(0, 1, (2, D0)) \
+ rng.normal(0, 0.01, (1200, D0))
th = rng.uniform(0, 4 * np.pi, (1200, 1))
cur = np.hstack([th * np.cos(th), th * np.sin(th),
rng.uniform(0, 6, (1200, 1))])
cur = cur @ rng.normal(0, 1, (3, D0)) + rng.normal(0, 0.01, (1200, D0))
ful = rng.normal(0, 1, (1200, D0))
for nm, P in [("직선 위", lin), ("평면 위", pl), ("굽은 띠 위", cur),
("진짜 60 차원", ful)]:
print(" %s %14d %20d %14.6f"
% (pw(nm, 24), D0, sv95(P), corr_dim(P)))
print(" 굽은 띠의 매개변수는 각도와 높이 둘입니다. 참 내재 차원이 2 입니다")
print(" 특이값은 그것을 3 으로 셉니다. 굽은 것을 곧게 펴서 못 보기 때문입니다")
print(" 상관 차원은 평면을 1.79 로 굽은 띠를 1.86 으로 냅니다. 굽어도 잡습니다")
print(" 다만 진짜 60 차원을 15.74 로 크게 모자라게 셉니다")
print(" 상관 차원도 높은 차원에서는 점이 지수로 모자랍니다")
print(" 88강의 주성분이 직선 구조에만 맞는 도구인 이유입니다")
print(" 내재 차원이 낮으면 이웃 방법이 되살아나는지 봅니다")
print(" %s %s %s %s"
% (pw("자료", 26), rw("y 의 분산", 14), rw("가장 가까운 이웃 오차", 24),
rw("분산 대비 비율", 18)))
base2 = e_two
def knn_on(P, y, k=1):
m = len(P) // 2
Xa, ya = P[:m], y[:m]
Xb, yb = P[m:], y[m:]
dd = ((Xb[:, None, :] - Xa[None, :, :]) ** 2).sum(axis=2)
idx = np.argsort(dd, axis=1)[:, :k]
return float(np.mean((yb - ya[idx].mean(axis=1)) ** 2))
y_lin = np.sin(6 * t[:, 0])
y_ful = np.sin(6 * (ful[:, 0] - ful[:, 0].min())
/ (ful[:, 0].max() - ful[:, 0].min()))
for nm, P, yy in [("60 차원인데 내재 1 차원", lin, y_lin),
("진짜 60 차원", ful, y_ful)]:
ev = knn_on(P, yy)
print(" %s %14.6f %24.6f %18.6f"
% (pw(nm, 26), float(yy.var()), ev, ev / float(yy.var())))
print(" y 의 분산이 다르므로 마지막 열의 분산 대비 비율로 견줍니다")
print(" 비율이 1 이면 y 의 평균을 내놓는 것과 다를 바 없다는 뜻입니다")
print(" 내재 차원이 1 이면 60 차원이어도 이웃이 잘 듭니다")
print(" 저주는 겉보기 차원이 아니라 내재 차원에 걸립니다")
# --- 문제 5: 그래서 무엇을 하는가 ---------------------------------------
print(" 차원이 높을 때 쓸 수 있는 수단을 정리합니다")
print(" %s %s %s"
% (pw("수단", 22), rw("무엇을 하나", 24), rw("어디서 배웠나", 20)))
for a, b, c in [("변수 선택", "쓸 것만 남김", "211강 라소"),
("차원 축소", "축을 갈아탐", "88강 주성분"),
("무작위 사영", "차원만 줄임", "이 강의 문제 5"),
("구조 가정", "매끄럽다고 가정", "213강 이후"),
("거리 대신 다른 것", "각도나 성긴 겹침", "문제 3")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 24), rw(c, 20)))
print(" 다섯 가지가 모두 실제 차원을 낮추거나 낮은 것처럼 쓰는 방법입니다")
print(" 무작위 사영이 거리를 얼마나 지키는지 잽니다")
print(" 1000 차원 점 300 개를 무작위 행렬로 낮은 차원에 던집니다")
n5, d5 = 300, 1000
P5 = rng.normal(0, 1, (n5, d5))
iu5 = np.triu_indices(n5, 1)
d_ori = np.sqrt(((P5[:, None, :] - P5[None, :, :]) ** 2).sum(axis=2))[iu5]
print(" %s %s %s %s"
% (pw("사영 차원", 12), rw("거리비의 평균", 18), rw("가장 큰 어긋남", 20),
rw("이론 문턱", 14)))
for m in [10, 50, 200, 800]:
R = rng.normal(0, 1.0 / np.sqrt(m), (d5, m))
Q = P5 @ R
d_new = np.sqrt(((Q[:, None, :] - Q[None, :, :]) ** 2).sum(axis=2))[iu5]
rat = d_new / d_ori
eps = np.sqrt(8.0 * np.log(n5) / m)
print(" %s %18.6f %20.6f %14.6f"
% (pw(str(m), 12), float(rat.mean()),
float(np.abs(rat - 1.0).max()), float(eps)))
print(" 존슨 린덴스트라우스 보조정리가 말하는 문턱이 마지막 열입니다")
print(" 필요한 차원이 원래 차원과 무관하고 점의 개수의 로그로만 자랍니다")
print(" 평균은 어느 줄에서나 1 에 가깝습니다. 사영이 거리를 평균적으로는 지킵니다")
print(" 그런데 가장 나쁜 쌍은 50 차원에서 43.5 퍼센트나 어긋납니다")
print(" 보조정리가 약속하는 것은 평균이 아니라 최악이고 그 상한이 마지막 열입니다")
print(" 실제 어긋남이 문턱보다 작으므로 약속은 지켜졌습니다")
print(" 마지막으로 무엇을 조심해야 하는지 정리합니다")
print(" %s %s"
% (pw("흔한 오해", 30), rw("실제로는", 34)))
for a, b in [("변수가 많으면 무조건 나쁘다", "내재 차원이 낮으면 괜찮다"),
("차원 축소는 언제나 이득이다", "쓸 축을 지울 수 있다"),
("거리가 크면 다른 것이다", "높은 차원에서는 다 크다"),
("표본을 늘리면 해결된다", "필요한 수가 지수로 는다")]:
print(" %s %s" % (pw(a, 30), rw(b, 34)))
print(" 213강은 왜 어려워지는지 봤습니다. 214강은 복잡도를 재는 법을 봅니다")
# 변수를 하나 늘리는 것이 왜 자료를 갑자기 부족하게 만드는지 봅니다
# 먼저 정육면체 안에 든 공의 부피 비율을 봅니다
# 차원 공의 부피 정육면체 부피 비율의 상용로그
# 1 1.0000000000 1.000000 -0.000000
# 2 0.7853981634 1.000000 -0.104910
# 3 0.5235987756 1.000000 -0.281001
# 5 0.1644934067 1.000000 -0.783852
# 10 0.0024903946 1.000000 -2.603732
# 20 0.0000000246 1.000000 -7.608864
# 50 0.0000000000 1.000000 -27.813399
# 100 0.0000000000 1.000000 -69.728581
# 한 변이 1 인 정육면체에 꼭 맞는 공을 넣습니다
# 차원 100 에서는 비율이 10 의 마이너스 70 제곱 근처입니다
# 차원이 오르면 공이 사실상 아무것도 안 차지합니다
# 부피가 모서리 쪽으로 갑니다. 모서리는 2 의 d 제곱 개입니다
# 공 안에서도 부피가 껍질로 몰립니다
# 차원 반지름 0.9 안쪽의 비율 바깥 10 퍼센트 껍질의 비율
# 1 0.9000000000 0.1000000000
# 2 0.8100000000 0.1900000000
# 5 0.5904900000 0.4095100000
# 10 0.3486784401 0.6513215599
# 50 0.0051537752 0.9948462248
# 200 0.0000000007 0.9999999993
# 반지름을 10 퍼센트만 줄여도 차원 200 에서는 거의 다 사라집니다
# 부피가 껍질에 몰린다는 것은 점들이 다 바깥에 있다는 뜻입니다
# 실제로 점을 뽑아 원점까지의 거리를 봅니다
# 차원 평균 거리 표준편차 표준편차 나누기 평균
# 1 0.796693 0.594126 0.745739
# 2 1.253960 0.659354 0.525818
# 10 3.080227 0.690079 0.224035
# 100 9.960115 0.709489 0.071233
# 1000 31.621327 0.711229 0.022492
# 평균 거리는 차원의 제곱근에 비례해 자랍니다
# 표준편차는 차원과 거의 무관하게 일정합니다
# 그래서 상대적 흩어짐이 0 으로 갑니다. 모든 점이 같은 껍질에 있습니다
# 거리로 이웃을 찾는 방법이 왜 무너지는지 봅니다
# 차원 가장 가까운 거리 가장 먼 거리 먼 것 나누기 가까운 것
# 1 0.004263 3.076791 721.660626
# 2 0.083027 3.454153 41.602556
# 5 1.017863 6.266771 6.156795
# 20 3.713009 8.666377 2.334058
# 100 11.079527 16.395186 1.479773
# 1000 41.976079 47.142161 1.123072
# 차원 1 에서는 가장 먼 점이 가장 가까운 점보다 수백 배 멉니다
# 차원 1000 에서는 1.2 배도 안 됩니다. 다 비슷하게 멉니다
# 가장 가까운 이웃이라는 말이 뜻을 잃습니다
# 이웃 기반 방법이 실제로 얼마나 나빠지는지 잽니다
# 참 함수는 앞의 두 변수만 씁니다. 나머지는 잡음입니다
# 변수 수 가장 가까운 이웃 오차 참 변수만 썼을 때 몇 배 나쁜가
# 2 0.008621 0.006959 1.238835
# 5 0.168801 0.006959 24.256446
# 10 0.411501 0.006959 59.132088
# 30 0.755771 0.006959 108.603186
# 100 0.940499 0.006959 135.148413
# 참 변수만 썼을 때는 어느 줄이나 같은 값입니다. 기준선이기 때문입니다
# 첫 줄이 정확히 1 이 아닌 것은 자료를 따로 뽑았기 때문입니다
# 쓸모없는 변수를 더할수록 이웃이 엉뚱한 점을 가리킵니다
# 거리가 잡음 변수 98 개에 끌려다니기 때문입니다
# 211강의 변수 선택이 여기서 성능 문제가 됩니다
# 같은 밀도를 지키려면 표본이 몇 개 필요한지 셉니다
# 한 변을 10 칸으로 쪼갠다고 하면 칸 수가 10 의 d 제곱입니다
# 차원 칸 수 칸마다 10 개면 필요한 표본
# 1 10 100
# 2 100 1000
# 3 1000 10000
# 5 100000 1000000
# 10 10000000000 100000000000
# 차원 10 이면 표본이 100 억 개 필요합니다
# 이것이 차원의 저주라는 이름이 붙은 이유입니다
# 거리가 다 비슷해지는 현상을 정리해 부릅니다
# 무엇 무엇이 일어나나 어디서 봤나
# 부피의 집중 껍질로 몰림 문제 1
# 거리의 집중 다 비슷해짐 문제 2
# 각도의 집중 거의 직교함 곧 봅니다
# 함수값의 집중 평균 근처로 몰림 곧 봅니다
# 넷을 묶어 측도의 집중이라 합니다
# 무작위 두 벡터의 각도를 봅니다
# 차원 평균 코사인 코사인의 표준편차 80 도에서 100 도 사이 비율
# 2 -0.023536 0.705682 0.105333
# 5 -0.001025 0.449790 0.257333
# 20 -0.005710 0.228047 0.538667
# 100 -0.001642 0.100096 0.915000
# 1000 -0.000452 0.031324 1.000000
# 코사인의 표준편차가 차원의 제곱근에 반비례해 줄어듭니다
# 차원 1000 에서는 거의 모든 쌍이 직교에 가깝습니다
# 이것이 무작위 벡터가 서로 간섭하지 않는 이유입니다
# 구면 위 함수값이 얼마나 몰리는지 봅니다
# 좌표 하나를 봅니다. 구면 위에서 뽑아 반지름 1 로 맞춥니다
# 차원 첫 좌표의 표준편차 1 나누기 루트 d 둘의 비
# 2 0.705895 0.707107 0.998287
# 10 0.315093 0.316228 0.996411
# 100 0.100781 0.100000 1.007813
# 1000 0.031255 0.031623 0.988358
# 구면 위에서 좌표 하나는 폭 1 나누기 루트 d 안에 갇힙니다
# 차원이 크면 구면의 거의 전부가 적도 근처에 있습니다
# 리프시츠 함수는 다 이렇게 집중합니다. 이것이 집중 부등식의 내용입니다
# 그런데 실제 자료에서는 차원이 커도 잘 되는 경우가 많습니다
# 까닭은 자료가 낮은 차원 구조 위에 있기 때문입니다
# 무엇 겉보기 차원 실제로 몇 차원인가
# 한 직선 위의 점 60 1
# 한 평면 위의 점 60 2
# 굽은 곡면 위의 점 60 곡면의 매개변수 수
# 성긴 벡터 60 0 이 아닌 개수
# 겉보기 차원이 아니라 내재 차원이 어려움을 정합니다
# 내재 차원을 실제로 재 봅니다
# 자료 겉보기 차원 특이값 95 퍼센트 상관 차원
# 직선 위 60 1 1.013144
# 평면 위 60 2 1.790030
# 굽은 띠 위 60 3 1.864462
# 진짜 60 차원 60 56 15.754661
# 굽은 띠의 매개변수는 각도와 높이 둘입니다. 참 내재 차원이 2 입니다
# 특이값은 그것을 3 으로 셉니다. 굽은 것을 곧게 펴서 못 보기 때문입니다
# 상관 차원은 평면을 1.79 로 굽은 띠를 1.86 으로 냅니다. 굽어도 잡습니다
# 다만 진짜 60 차원을 15.74 로 크게 모자라게 셉니다
# 상관 차원도 높은 차원에서는 점이 지수로 모자랍니다
# 88강의 주성분이 직선 구조에만 맞는 도구인 이유입니다
# 내재 차원이 낮으면 이웃 방법이 되살아나는지 봅니다
# 자료 y 의 분산 가장 가까운 이웃 오차 분산 대비 비율
# 60 차원인데 내재 1 차원 0.529966 0.000143 0.000270
# 진짜 60 차원 0.373528 0.461821 1.236375
# y 의 분산이 다르므로 마지막 열의 분산 대비 비율로 견줍니다
# 비율이 1 이면 y 의 평균을 내놓는 것과 다를 바 없다는 뜻입니다
# 내재 차원이 1 이면 60 차원이어도 이웃이 잘 듭니다
# 저주는 겉보기 차원이 아니라 내재 차원에 걸립니다
# 차원이 높을 때 쓸 수 있는 수단을 정리합니다
# 수단 무엇을 하나 어디서 배웠나
# 변수 선택 쓸 것만 남김 211강 라소
# 차원 축소 축을 갈아탐 88강 주성분
# 무작위 사영 차원만 줄임 이 강의 문제 5
# 구조 가정 매끄럽다고 가정 213강 이후
# 거리 대신 다른 것 각도나 성긴 겹침 문제 3
# 다섯 가지가 모두 실제 차원을 낮추거나 낮은 것처럼 쓰는 방법입니다
# 무작위 사영이 거리를 얼마나 지키는지 잽니다
# 1000 차원 점 300 개를 무작위 행렬로 낮은 차원에 던집니다
# 사영 차원 거리비의 평균 가장 큰 어긋남 이론 문턱
# 10 0.965245 0.896040 2.136124
# 50 0.994196 0.435031 0.955304
# 200 1.002415 0.254183 0.477652
# 800 0.999278 0.095781 0.238826
# 존슨 린덴스트라우스 보조정리가 말하는 문턱이 마지막 열입니다
# 필요한 차원이 원래 차원과 무관하고 점의 개수의 로그로만 자랍니다
# 평균은 어느 줄에서나 1 에 가깝습니다. 사영이 거리를 평균적으로는 지킵니다
# 그런데 가장 나쁜 쌍은 50 차원에서 43.5 퍼센트나 어긋납니다
# 보조정리가 약속하는 것은 평균이 아니라 최악이고 그 상한이 마지막 열입니다
# 실제 어긋남이 문턱보다 작으므로 약속은 지켜졌습니다
# 마지막으로 무엇을 조심해야 하는지 정리합니다
# 흔한 오해 실제로는
# 변수가 많으면 무조건 나쁘다 내재 차원이 낮으면 괜찮다
# 차원 축소는 언제나 이득이다 쓸 축을 지울 수 있다
# 거리가 크면 다른 것이다 높은 차원에서는 다 크다
# 표본을 늘리면 해결된다 필요한 수가 지수로 는다
# 213강은 왜 어려워지는지 봤습니다. 214강은 복잡도를 재는 법을 봅니다