강부터 강까지 다섯 방법이 모두 공간을 어떻게 나눌지를 다뤘습니다. 이웃으로, 분포로, 상자로, 상자의 평균으로, 상자의 합으로 나눴습니다.
그런데 그냥 긋는 것이 아닙니다. 강 문제 에서 완전히 갈리는 자료면 로지스틱 계수가 발산한다고 했습니다. 경계를 그을 자리가 무한히 많기 때문입니다.
그리고 그 자리를 정하는 데 몇 개의 점만 씁니다. 여기에 커널을 끼우면 변수를 만들지 않고 무한 차원에서 경계를 긋게 됩니다.
문제. 여백 최대 경계를 세웁니다.
() 로지스틱 회귀와 무엇이 다른지 정리하세요.
() 완전히 갈리는 자료에서 견주세요.
() 서포트 벡터만 남기고 다시 풀어 보세요.
생각의 실마리. 완전히 갈리는 자료에서 경계를 그을 자리는 무한히 많습니다. 어느 것을 고를지 정하는 규칙이 필요하고, "가장 여유 있는 것"이 자연스러운 규칙입니다.
풀이. () 정리합니다.
| 무엇 | 로지스틱 회귀 | 여백 최대 경계 |
|---|---|---|
| 무엇을 최소화 | 로그손실 | 노름 더하기 힌지 |
| 모든 점이 기여하나 | 예 | 아니오 |
| 완전히 갈리면 | 계수가 발산 | 여백이 유일하게 정해짐 |
| 확률을 내나 | 예 | 아니오 |
| 커널을 끼울 수 있나 | 어려움 | 쉬움 |
() 완전히 갈리는 자료에서 견줍니다. 표본 개입니다.
| 걸음 수 | 로지스틱 계수 크기 | 힌지 계수 크기 | 힌지 여백 |
|---|---|---|---|
로지스틱 계수는 에서 까지 계속 커집니다. 완전히 갈리면 계수를 키울수록 로그손실이 계속 줄어들기 때문입니다.
힌지 계수는 근처에서 멈춥니다. 여백이 정해졌기 때문입니다. 여백은 경계에서 가장 가까운 점까지의 거리입니다.
() 여백을 정하는 점이 몇 개인지 셉니다.
| 무엇 | 개수 | 전체 대비 비율 |
|---|---|---|
| 경계 위나 안쪽에 있는 점 | ||
| 여백 바깥에 있는 점 | ||
| 전체 |
경계를 정하는 데 쓰이는 점이 개뿐입니다. 이 점들을 서포트 벡터라 합니다.
서포트 벡터만 남기고 다시 풀어 봅니다.
| 무엇으로 풀었나 | 첫 계수 | 둘째 계수 | 절편 |
|---|---|---|---|
| 전체 개 | |||
| 서포트 벡터 개 | |||
| 두 계수의 비 |
두 경계가 같은 판정을 내리는 비율이 입니다. 개를 지웠는데 판정이 하나도 안 바뀝니다.
나머지 점은 정말 안 쓰였습니다. 강 문제 에서는 경계 근처만 남기면 이웃 방법이 무너졌습니다. 다수결이 아니라 경계를 직접 긋기 때문에 다릅니다. 강 문제 의 근접도처럼 어느 점이 중요한지가 방법마다 다릅니다.
이 문제에서 배우는 것. 여백을 최대로 하는 것은 답이 여럿일 때 하나를 고르는 규칙입니다. 그리고 그 규칙은 소수의 점만 쓴다는 뜻밖의 성질을 딸려 옵니다. 그 희소성이 다음 문제들의 바탕이 됩니다.
확인 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. 서포트 벡터 머신이 표본이 많을 때 무거운 이유를 쓰세요.
답. 커널 행렬이 표본 수의 제곱만큼 커지기 때문입니다.
| 유형 | 무엇을 묻나 | 어디를 보나 |
|---|---|---|
| 여백 최대 | 답이 여럿일 때 고르는 규칙 | 문제 |
| 서포트 벡터 | 소수만 씀 | 문제 |
| 와 | 역수 관계 | 문제 |
| 힌지의 특별함 | 이상점이 아니라 희소성 | 문제 |
| 변수 폭발 | 차수에 지수로 | 문제 |
| 커널 요령 | 내적만 계산 | 문제 |
| 커널 고르기 | 유사도가 곧 가정 | 문제 |
| 감마 | 얼마나 국소적인가 | 문제 |
| 표준화 | 거리를 쓰므로 필수 | 문제 |
| 계산 비용 | 표본 제곱 | 문제 |
핵심 식을 한자리에 모읍니다.
| 커널 | 식 | 손잡이 |
|---|---|---|
| 선형 | 없음 | |
| 다항 | (x^{\top}z+c)^ | 와 |
| 가우스 | ||
| 라플라스 | e^ |
문제 6. 완전히 갈리는 자료에서 로지스틱 계수가 어떻게 되는지 쓰세요.
답. 걸음을 늘릴수록 계속 커집니다.
문제 7. 검산에서 서포트 벡터의 개수와 비율을 쓰세요.
답. 개이고 입니다.
문제 8. 검산에서 서포트 벡터만으로 푼 경계가 전체로 푼 것과 같은 판정을 내리는 비율을 쓰세요.
답. 입니다.
문제 9. 와 강의 의 관계를 쓰세요.
답. 는 의 역수이고 가 벌점 세기입니다.
문제 10. 검산에서 가 과 일 때 서포트 벡터 수를 쓰세요.
답. 개와 개입니다.
문제 11. 검산에서 여백 일 때 힌지와 로지스틱 손실을 쓰세요.
답. 과 입니다.
문제 12. 커널 요령이 무엇을 아껴 주는지 쓰세요.
답. 늘린 변수를 만들지 않고 내적만 계산합니다.
문제 13. 검산에서 변수 개에 차수 이면 항이 몇 개인지 쓰세요.
답. 개입니다.
문제 14. 검산에서 직접 만든 내적과 커널 값의 최대 차이를 쓰세요.
답. 입니다.
문제 15. 커널이 되기 위한 조건을 쓰세요.
답. 대칭이고 그람 행렬이 준양정부호여야 합니다.
문제 16. 검산에서 선형 커널과 가우스 감마 의 정확도를 쓰세요.
답. 과 입니다.
문제 17. 검산에서 감마 일 때 두 점의 커널 값 비를 쓰세요.
답. 입니다.
문제 18. 검산에서 배율 일 때 표준화 전과 후의 정확도를 쓰세요.
답. 과 입니다.
심화 1. 여백이 왜 인지 유도하세요.
경계 에서 점 까지의 거리는 이렇습니다.
| 무엇 | 값 |
|---|---|
| 여백 위의 점 | |
| 그 점까지의 거리 | |
| 두 경계선 사이 | |
| 최대화하려면 | 를 최소화 |
를 최소화하는 것이 여백을 최대화하는 것과 같습니다. 그래서 목적함수의 첫 항이 입니다. 강의 릿지 벌점과 같은 꼴인데 뜻이 다릅니다. 거기서는 축소였고 여기서는 여백입니다.
심화 2. 이중 문제와 KKT 조건을 정리하세요.
| \alpha_ | 그 점의 위치 |
|---|---|
| 여백 바깥 | |
| 과 사이 | 여백 위 |
| 여백 안쪽이나 틀림 |
강의 라그랑주 승수가 여기서 입니다. 이중 문제에는 가 내적으로만 나타나므로 커널을 끼울 수 있습니다. 그리고 인 점이 서포트 벡터가 아닌 점이고, 문제 의 개가 그것입니다.
심화 3. 표현 정리를 정리하세요.
| 무엇 | 뜻 |
|---|---|
| \mathcal | 커널이 만드는 함수 공간 |
| 무한 차원일 수 있음 | 가우스 커널 |
| 해는 언제나 유한 | 표본 수만큼의 계수 |
| 왜 | 나머지 방향은 벌점만 늘림 |
무한 차원에서 최소화하는데 해가 표본 수만큼의 계수로 적힙니다. 손실이 에만 딸리므로, 표본이 안 걸치는 방향은 손실을 안 바꾸고 벌점만 늘리기 때문입니다. 검산의 커널 릿지가 이 정리로 푼 것입니다.
심화 4. 커널을 만드는 규칙을 정리하세요.
| 규칙 | 결과 |
|---|---|
| K_{1}+K_ | 커널 |
| () | 커널 |
| K_{1}K_ | 커널 |
| 커널 | |
| 커널 |
마지막 줄이 가우스 커널을 설명합니다. 이고, 가운데가 선형 커널의 지수이며 양쪽이 넷째 규칙의 입니다. 지수를 급수로 펴면 모든 차수의 다항 커널의 합이므로 무한 차원입니다.
심화 5. 갈래가 셋 이상일 때의 방법을 정리하세요.
| 방법 | 모형 개수 | 무엇이 문제 |
|---|---|---|
| 하나 대 나머지 | 개 | 갈래가 치우침 |
| 하나 대 하나 | 개 | 개수가 많음 |
| 구조적 SVM | 개 | 풀기 어려움 |
강의 소프트맥스는 한 번에 풉니다. SVM은 이진 문제로 태어나서 쪼개야 합니다. 하나 대 하나는 모형이 많지만 각 모형이 작아 실제로는 더 빠른 경우가 많습니다.
심화 6. 언제 SVM을 쓸지 정리하세요.
| 상황 | 쓰나 | 왜 |
|---|---|---|
| 표본이 수천 개 이하 | 예 | 커널이 감당됨 |
| 변수가 표본보다 많음 | 예 | 여백이 잘 정의됨 |
| 표본이 수십만 개 | 아니오 | 제곱 비용 |
| 확률이 필요함 | 아니오 | 따로 보정해야 함 |
| 표 형태 자료 | 절반 | 강이 대개 나음 |
둘째 줄이 SVM의 고전적 강점입니다. 유전자 자료처럼 변수가 수만 개이고 표본이 수백 개인 문제에서, 강의 저주에 덜 걸리고 선형 커널만으로도 잘 됩니다. 여백이 표본 수에만 딸리고 차원에 안 딸리기 때문입니다.
정답.
| 기호 | 읽는 법 | 뜻 |
|---|---|---|
| 서포트 벡터 머신 | support vector machine | 여백을 최대로 하는 경계를 긋습니다 |
| 여백 | margin | 경계에서 가장 가까운 점까지의 거리입니다 |
| 서포트 벡터 | support vector | 경계를 정하는 소수의 점입니다 |
| 힌지 손실 | hinge loss | 여백 을 넘으면 입니다 |
| 커널 | kernel | 늘린 공간에서의 내적입니다 |
| 커널 요령 | kernel trick | 변수를 안 만들고 내적만 셉니다 |
| 그람 행렬 | Gram matrix | 모든 쌍의 커널 값을 모은 행렬입니다 |
| 준양정부호 | positive semidefinite | 고유값이 모두 이상입니다 |
| 표현 정리 | representer theorem | 해가 표본의 커널 합으로 적힙니다 |
| 감마 | gamma | 가우스 커널이 얼마나 국소적인지 정합니다 |
단원이 여기서 끝납니다. 강부터 여섯 방법을 세웠고, 그 여섯이 서로 다른 가정의 목록이라는 것을 봤습니다. 강부터는 라벨이 없습니다. 무엇을 맞힐지 없이 자료 안의 구조만으로 무언가를 찾아냅니다.
import numpy as np
rng = np.random.default_rng(20261220)
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 hinge_fit(X, y, C=1.0, steps=6000, lr=None):
# y 는 마이너스 1 과 플러스 1 입니다. 원 문제를 그대로 내려갑니다
n, d = X.shape
w = np.zeros(d)
b = 0.0
if lr is None:
lr = 1.0 / (1.0 + C * np.linalg.norm(X, 2) ** 2 / n)
for _ in range(steps):
m = y * (X @ w + b)
act = (m < 1).astype(float)
gw = w - C * (X.T @ (act * y)) / n
gb = -C * float((act * y).sum()) / n
w = w - lr * gw
b = b - lr * gb
return w, b
def kern(A, B, kind, p=3, g=1.0, c0=1.0):
if kind == "linear":
return A @ B.T
if kind == "poly":
return (A @ B.T + c0) ** p
D = ((A[:, None, :] - B[None, :, :]) ** 2).sum(axis=2)
return np.exp(-g * D)
def kridge_fit(K, y, lam=1e-3):
# 표현 정리로 원 문제를 닫힌 꼴로 풉니다
n = len(y)
return np.linalg.solve(K + lam * n * np.eye(n), y)
def kridge_pred(a, Ktest):
return Ktest @ a
# --- 문제 1: 여백을 가장 크게 하는 경계 ---------------------------------
print(" 215강부터 219강까지는 공간을 어떻게 나눌지를 다뤘습니다")
print(" 이번에는 경계를 직접 긋되 가장 여유 있는 자리에 긋습니다")
print(" %s %s %s"
% (pw("무엇", 22), rw("로지스틱 회귀", 22), rw("여백 최대 경계", 24)))
for a, b, c in [("무엇을 최소화", "로그손실", "노름 더하기 힌지"),
("모든 점이 기여하나", "예", "아니오"),
("완전히 갈리면", "계수가 발산", "여백이 유일하게 정해짐"),
("확률을 내나", "예", "아니오"),
("커널을 끼울 수 있나", "어려움", "쉬움")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 22), rw(c, 24)))
print(" 208강 문제 4 에서 완전 분리면 로지스틱 계수가 발산한다고 했습니다")
print(" 여백을 최대로 하면 그 자리가 하나로 정해집니다")
print(" 완전히 갈리는 자료에서 두 방법을 견줍니다")
n1 = 200
X1 = rng.uniform(-3, 3, (n1, 2))
sep = X1[:, 0] + X1[:, 1]
keep = np.abs(sep) > 0.8
X1, sep = X1[keep], sep[keep]
y1 = np.where(sep > 0, 1.0, -1.0)
n1 = len(y1)
def logit_fit(X, y01, steps, lr=0.5):
A = np.hstack([X, np.ones((len(X), 1))])
w = np.zeros(A.shape[1])
for _ in range(steps):
p = 1.0 / (1.0 + np.exp(-A @ w))
w -= lr * (A.T @ (p - y01)) / len(y01)
return w
y01 = (y1 > 0).astype(float)
print(" 표본 %d 개이고 완전히 갈립니다" % n1)
print(" %s %s %s %s"
% (pw("걸음 수", 12), rw("로지스틱 계수 크기", 24), rw("힌지 계수 크기", 22),
rw("힌지 여백", 16)))
for st in [200, 2000, 20000, 100000]:
wl = logit_fit(X1, y01, st)
wh, bh = hinge_fit(X1, y1, 100.0, min(st, 40000))
mg = float(np.min(y1 * (X1 @ wh + bh)) / max(np.linalg.norm(wh), 1e-12))
print(" %s %24.6f %22.6f %16.6f"
% (pw(str(st), 12), float(np.linalg.norm(wl[:2])),
float(np.linalg.norm(wh)), mg))
print(" 로지스틱 계수는 걸음을 늘릴수록 계속 커집니다")
print(" 힌지 계수는 어느 값에서 멈춥니다. 여백이 정해졌기 때문입니다")
print(" 여백은 경계에서 가장 가까운 점까지의 거리입니다")
print(" 여백을 정하는 점이 몇 개인지 셉니다")
wh, bh = hinge_fit(X1, y1, 100.0, 40000)
m1 = y1 * (X1 @ wh + bh)
print(" %s %s %s"
% (pw("무엇", 26), rw("개수", 12), rw("전체 대비 비율", 20)))
for nm, cnt in [("경계 위나 안쪽에 있는 점", int((m1 <= 1.0001).sum())),
("여백 바깥에 있는 점", int((m1 > 1.0001).sum())),
("전체", n1)]:
print(" %s %12d %20.6f" % (pw(nm, 26), cnt, cnt / n1))
print(" 경계를 정하는 데 쓰이는 점이 아주 적습니다")
print(" 이 점들을 서포트 벡터라 합니다")
print(" 215강 문제 5 에서 경계 근처만 남기면 이웃 방법이 무너졌습니다")
print(" 서포트 벡터만 남기고 다시 풀어 봅니다")
sv = m1 <= 1.0001
w2, b2 = hinge_fit(X1[sv], y1[sv], 100.0 * n1 / int(sv.sum()), 40000)
print(" %s %s %s %s"
% (pw("무엇으로 풀었나", 24), rw("첫 계수", 14), rw("둘째 계수", 14),
rw("절편", 14)))
print(" %s %14.6f %14.6f %14.6f"
% (pw("전체 %d 개" % n1, 24), wh[0], wh[1], bh))
print(" %s %14.6f %14.6f %14.6f"
% (pw("서포트 벡터 %d 개" % int(sv.sum()), 24), w2[0], w2[1], b2))
agree = float(np.mean(np.sign(X1 @ wh + bh) == np.sign(X1 @ w2 + b2)))
r1 = float(wh[0] / wh[1])
r2 = float(w2[0] / w2[1])
print(" %s %14.6f %14.6f"
% (pw("두 계수의 비", 24), r1, r2))
print(" 두 경계가 같은 판정을 내리는 비율은 %.6f 입니다" % agree)
print(" 140 개를 지웠는데 판정이 하나도 안 바뀝니다")
print(" 나머지 점은 정말 안 쓰였습니다")
print(" 이웃 방법은 다수결이라 먼 점이 필요했고 여기서는 필요 없습니다")
print(" 218강 문제 4 의 근접도처럼 어느 점이 중요한지가 방법마다 다릅니다")
# --- 문제 2: 여유를 허용합니다 ------------------------------------------
print(" 완전히 안 갈리는 자료에서는 여유를 허용해야 합니다")
n2 = 400
X2 = rng.uniform(-3, 3, (n2, 2))
s2 = 1.2 * X2[:, 0] + X2[:, 1]
p2 = 1.0 / (1.0 + np.exp(-1.2 * s2))
y2 = np.where(rng.uniform(0, 1, n2) < p2, 1.0, -1.0)
X2t = rng.uniform(-3, 3, (2500, 2))
s2t = 1.2 * X2t[:, 0] + X2t[:, 1]
p2t = 1.0 / (1.0 + np.exp(-1.2 * s2t))
y2t = np.where(rng.uniform(0, 1, 2500) < p2t, 1.0, -1.0)
bayes2 = float(np.mean(np.where(p2t > 0.5, 1.0, -1.0) == y2t))
print(" 베이즈 최적 정확도는 %.6f 입니다" % bayes2)
print(" %s %s %s %s %s"
% (pw("C", 10), rw("계수 크기", 14), rw("여백 폭", 14),
rw("서포트 벡터 수", 18), rw("검증 정확도", 16)))
for C in [0.1, 1.0, 10.0, 100.0, 1000.0]:
w, b = hinge_fit(X2, y2, C, 12000)
m = y2 * (X2 @ w + b)
nrm = max(np.linalg.norm(w), 1e-12)
print(" %s %14.6f %14.6f %18d %16.6f"
% (pw("%.1f" % C, 10), float(nrm), float(1.0 / nrm),
int((m <= 1.0001).sum()),
float(np.mean(np.sign(X2t @ w + b) == y2t))))
print(" 여백 폭은 1 나누기 계수 크기입니다. 두 경계선 사이의 거리입니다")
print(" C 가 0.1 이면 계수가 거의 0 이라 아무것도 못 배웁니다. 정확도가 0.5072 입니다")
print(" C 를 키우면 여백이 좁아지고 서포트 벡터가 383 개에서 135 개로 줍니다")
print(" 학습 자료를 더 맞추려 들수록 경계를 정하는 점이 적어집니다")
print(" C 는 211강의 lambda 의 역수입니다. 1 나누기 C 가 벌점 세기입니다")
print(" 힌지 손실이 다른 손실과 어떻게 다른지 봅니다")
print(" %s %s %s %s %s"
% (pw("여백 m", 12), rw("힌지", 14), rw("로지스틱", 14),
rw("지수", 14), rw("0 과 1", 12)))
for m in [-2.0, -0.5, 0.5, 1.0, 2.0, 4.0]:
hg = max(0.0, 1.0 - m)
lg = float(np.log(1.0 + np.exp(-m)))
ex = float(np.exp(-m))
zo = 1.0 if m <= 0 else 0.0
print(" %s %14.6f %14.6f %14.6f %12.1f"
% (pw("%.1f" % m, 12), hg, lg, ex, zo))
print(" 힌지는 여백 1 을 넘으면 정확히 0 입니다. 그래서 점이 빠집니다")
print(" 로지스틱은 아무리 잘 맞혀도 0 이 안 됩니다. 모든 점이 조금씩 기여합니다")
print(" 지수는 틀린 점에 폭발적으로 반응합니다. 219강 심화 2 의 그 손실입니다")
print(" 세 손실이 이상점에 얼마나 흔들리는지 잽니다")
print(" 라벨을 뒤집은 점을 늘려 가며 검증 정확도를 봅니다")
print(" %s %s %s %s"
% (pw("뒤집은 점 수", 14), rw("힌지", 18), rw("로지스틱", 18),
rw("차", 14)))
for k in [0, 5, 20, 60]:
yb = y2.copy()
if k > 0:
idx = np.argsort(-np.abs(s2))[:k]
yb[idx] = -yb[idx]
w, b = hinge_fit(X2, yb, 1.0, 8000)
ah = float(np.mean(np.sign(X2t @ w + b) == y2t))
wl = logit_fit(X2, (yb > 0).astype(float), 8000)
al = float(np.mean(np.sign(np.hstack([X2t, np.ones((2500, 1))]) @ wl)
== y2t))
print(" %s %18.6f %18.6f %14.6f"
% (pw(str(k), 14), ah, al, ah - al))
print(" 멀리 있는 점의 라벨을 뒤집었습니다. 가장 나쁜 이상점입니다")
print(" 힌지가 로지스틱보다 조금씩 더 나쁩니다. 통념과 반대입니다")
print(" 힌지가 무시하는 것은 잘 맞힌 점이지 크게 틀린 점이 아닙니다")
print(" 크게 틀린 점에 대해 힌지도 로지스틱도 기울기가 1 로 일정합니다")
print(" 둘 다 선형으로 반응하므로 이상점 내성에서 큰 차이가 없습니다")
print(" 정말 튼튼하게 만들려면 219강의 후버처럼 손실을 잘라야 합니다")
# --- 문제 3: 커널로 차원을 올립니다 -------------------------------------
print(" 직선으로 안 갈리는 자료를 봅니다")
n3 = 300
X3 = rng.uniform(-2.5, 2.5, (n3, 2))
r3 = (X3 ** 2).sum(axis=1)
y3 = np.where(r3 < 3.0, 1.0, -1.0)
X3t = rng.uniform(-2.5, 2.5, (2000, 2))
y3t = np.where((X3t ** 2).sum(axis=1) < 3.0, 1.0, -1.0)
print(" 원 안이면 양성입니다. 직선으로는 못 나눕니다")
print(" %s %s %s"
% (pw("무엇을 썼나", 26), rw("검증 정확도", 18), rw("변수 개수", 16)))
w, b = hinge_fit(X3, y3, 1.0, 8000)
print(" %s %18.6f %16d"
% (pw("원래 변수 둘", 26),
float(np.mean(np.sign(X3t @ w + b) == y3t)), 2))
Z3 = np.hstack([X3, X3 ** 2, (X3[:, [0]] * X3[:, [1]])])
Z3t = np.hstack([X3t, X3t ** 2, (X3t[:, [0]] * X3t[:, [1]])])
w, b = hinge_fit(Z3, y3, 1.0, 8000)
print(" %s %18.6f %16d"
% (pw("제곱과 곱을 더함", 26),
float(np.mean(np.sign(Z3t @ w + b) == y3t)), 5))
print(" 변수를 늘리면 직선으로 갈립니다. 원래 공간에서는 원입니다")
print(" 228강의 특성공학이 하는 일입니다. 그런데 차수를 올리면 변수가 폭발합니다")
print(" 차수를 올릴 때 변수 개수가 얼마나 느는지 셉니다")
print(" %s %s %s %s"
% (pw("원래 변수 수", 14), rw("차수 2", 14), rw("차수 3", 16),
rw("차수 5", 18)))
def ncomb(d, p):
v = 1.0
for i in range(p):
v = v * (d + p - i) / (i + 1)
return v
for d in [2, 10, 100, 1000]:
print(" %s %14.0f %16.0f %18.0f"
% (pw(str(d), 14), ncomb(d, 2), ncomb(d, 3), ncomb(d, 5)))
print(" 변수 1000 개에 차수 5 면 항이 천문학적으로 많습니다")
print(" 그런데 힌지 문제의 해가 점들의 내적으로만 적힙니다")
print(" 그러면 변수를 만들지 않고 내적만 계산하면 됩니다. 이것이 커널 요령입니다")
print(" 커널이 정말 같은 답을 내는지 확인합니다")
print(" 차수 2 다항 커널과 직접 만든 변수를 견줍니다")
Z2 = np.hstack([np.ones((n3, 1)), np.sqrt(2) * X3,
X3 ** 2, np.sqrt(2) * (X3[:, [0]] * X3[:, [1]])])
Kd = Z2 @ Z2.T
Kk = kern(X3, X3, "poly", 2, 1.0, 1.0)
print(" %s %s %s"
% (pw("무엇", 30), rw("값", 20), rw("무엇을 뜻하나", 24)))
print(" %s %20.6f %s"
% (pw("직접 만든 변수의 내적 최대", 30), float(Kd.max()),
rw("6 차원 계산", 24)))
print(" %s %20.6f %s"
% (pw("커널 함수의 값 최대", 30), float(Kk.max()),
rw("2 차원 계산", 24)))
print(" %s %20.6e %s"
% (pw("둘의 최대 차이", 30), float(np.abs(Kd - Kk).max()),
rw("같은 것", 24)))
print(" 변수를 6 개 만들어 내적한 것과 커널 한 번 계산한 것이 같습니다")
print(" 차수가 올라가도 커널 계산 비용은 그대로입니다")
print(" 84강의 내적이 여기서 계산을 통째로 아껴 줍니다")
# --- 문제 4: 커널을 갈아 끼웁니다 ---------------------------------------
print(" 커널마다 어떤 경계를 그리는지 봅니다")
print(" %s %s %s"
% (pw("커널", 20), rw("식", 28), rw("어떤 경계", 24)))
for a, b, c in [("선형", "x 와 z 의 내적", "직선"),
("다항 p 차", "내적 더하기 1 의 p 제곱", "p 차 곡면"),
("가우스", "exp 마이너스 감마 거리 제곱", "아무 모양"),
("시그모이드", "tanh 꼴", "신경망 비슷")]:
print(" %s %s %s" % (pw(a, 20), rw(b, 28), rw(c, 24)))
print(" 가우스 커널은 무한 차원 특성 공간에 대응합니다")
print(" 실제로 갈아 끼워 잽니다")
print(" %s %s %s %s"
% (pw("커널", 20), rw("검증 정확도", 18), rw("계수가 큰 점의 수", 20),
rw("전체 대비", 14)))
for nm, kw in [("선형", ("linear", 0, 0)), ("다항 2 차", ("poly", 2, 0)),
("다항 3 차", ("poly", 3, 0)), ("가우스 감마 0.2", ("rbf", 0, 0.2)),
("가우스 감마 1.0", ("rbf", 0, 1.0)),
("가우스 감마 20.0", ("rbf", 0, 20.0))]:
K = kern(X3, X3, kw[0], kw[1], kw[2])
Kt = kern(X3t, X3, kw[0], kw[1], kw[2])
a = kridge_fit(K, y3, 1e-3)
pr = np.sign(kridge_pred(a, Kt))
big = int((np.abs(a) > 0.1 * np.abs(a).max()).sum())
print(" %s %18.6f %20d %14.6f"
% (pw(nm, 20), float(np.mean(pr == y3t)), big, big / n3))
print(" 선형 커널은 0.519000 으로 원을 못 잡습니다. 동전 던지기와 다를 바 없습니다")
print(" 다항 2 차부터 0.96 을 넘고 가우스 감마 0.2 가 0.970000 으로 가장 좋습니다")
print(" 감마를 20 까지 키워도 0.962500 로 크게 안 떨어집니다")
print(" 여기서는 제곱오차를 써서 계수가 희소하지 않습니다. 대부분이 큽니다")
print(" 문제 1 처럼 소수만 남으려면 힌지 손실이라야 합니다")
print(" 힌지가 여백 밖을 정확히 0 으로 만드는 것이 희소성의 원천입니다")
print(" 감마가 커지면 왜 이웃 방법이 되는지 봅니다")
print(" %s %s %s %s"
% (pw("감마", 12), rw("가장 가까운 점의 커널 값", 28),
rw("두 번째 점의 커널 값", 26), rw("둘의 비", 14)))
q = X3t[:1]
D = np.sqrt(((X3 - q) ** 2).sum(axis=1))
o = np.argsort(D)
for g in [1.0, 10.0, 100.0, 1000.0]:
k1 = float(np.exp(-g * D[o[0]] ** 2))
k2 = float(np.exp(-g * D[o[1]] ** 2))
print(" %s %28.10f %26.10f %14.6f"
% (pw("%.1f" % g, 12), k1, k2, k1 / max(k2, 1e-300)))
print(" 감마가 크면 가장 가까운 점만 무게를 갖습니다")
print(" 215강의 커널 회귀와 같은 식입니다. 폭 h 가 여기서는 1 나누기 루트 감마입니다")
print(" 감마가 작으면 모든 점이 비슷한 무게를 가져 거의 직선이 됩니다")
print(" 커널이 되려면 무엇이 필요한지 확인합니다")
print(" 대칭이고 그람 행렬이 준양정부호여야 합니다")
print(" %s %s %s"
% (pw("함수", 26), rw("가장 작은 고유값", 22), rw("커널인가", 16)))
S = rng.uniform(-2, 2, (60, 2))
for nm, kk in [("선형", kern(S, S, "linear")),
("다항 3 차", kern(S, S, "poly", 3, 1.0, 1.0)),
("가우스", kern(S, S, "rbf", 0, 1.0)),
("거리 그대로", -np.sqrt(((S[:, None, :] - S[None, :, :]) ** 2)
.sum(axis=2)))]:
ev = float(np.linalg.eigvalsh((kk + kk.T) / 2).min())
ok = ev > -1e-8
print(" %s %22.6f %s"
% (pw(nm, 26), ev if abs(ev) > 1e-9 else 0.0,
rw("예" if ok else "아니오", 16)))
print(" 마지막 줄은 고유값이 음수라 커널이 아닙니다")
print(" 아무 유사도 함수나 커널이 되지는 않습니다")
print(" 86강의 준양정부호가 여기서 조건이 됩니다")
# --- 문제 5: 실무에서 쓰기 ---------------------------------------------
print(" 실무에서 무엇을 정해야 하는지 정리합니다")
print(" %s %s %s"
% (pw("무엇", 20), rw("무엇을 바꾸나", 24), rw("어떻게 정하나", 26)))
for a, b, c in [("C", "여백과 오분류의 절충", "212강 교차검증"),
("커널", "경계의 모양", "먼저 선형으로 시작"),
("감마", "얼마나 국소적인가", "C 와 함께 격자로"),
("표준화", "거리의 뜻", "반드시 먼저"),
("갈래 셋 이상", "이진 문제로 쪼갬", "하나 대 나머지")]:
print(" %s %s %s" % (pw(a, 20), rw(b, 24), rw(c, 26)))
print(" 넷째 줄이 중요합니다. 커널이 거리를 쓰므로 215강과 같은 문제가 생깁니다")
print(" 표준화를 안 하면 어떻게 되는지 잽니다")
print(" %s %s %s %s"
% (pw("둘째 변수 배율", 16), rw("표준화 안 함", 20), rw("표준화 함", 18),
rw("차", 14)))
for sc in [1.0, 5.0, 20.0]:
A = X3 * np.array([1.0, sc])
B = X3t * np.array([1.0, sc])
K = kern(A, A, "rbf", 0, 1.0)
Kt = kern(B, A, "rbf", 0, 1.0)
a = kridge_fit(K, y3, 1e-3)
e1 = float(np.mean(np.sign(kridge_pred(a, Kt)) == y3t))
sd = A.std(axis=0)
K2 = kern(A / sd, A / sd, "rbf", 0, 1.0)
Kt2 = kern(B / sd, A / sd, "rbf", 0, 1.0)
a2 = kridge_fit(K2, y3, 1e-3)
e2 = float(np.mean(np.sign(kridge_pred(a2, Kt2)) == y3t))
print(" %s %20.6f %18.6f %14.6f"
% (pw("%.0f" % sc, 16), e1, e2, e2 - e1))
print(" 배율을 키우면 표준화 안 한 쪽이 0.9685 에서 0.9000 으로 떨어집니다")
print(" 215강 문제 2 와 완전히 같은 현상입니다. 커널도 거리를 씁니다")
print(" 표준화한 쪽은 어느 배율에서나 같은 값입니다")
print(" 계산 비용을 셉니다")
print(" %s %s %s"
% (pw("무엇", 24), rw("비용", 22), rw("표본 10000 이면", 22)))
for a, b, c in [("커널 행렬 만들기", "n 제곱", "1 억 개"),
("메모리", "n 제곱 곱하기 8 바이트", "800 메가바이트"),
("이중 문제 풀기", "n 제곱에서 세제곱", "아주 느림"),
("예측 한 건", "서포트 벡터 수", "수천 번 계산")]:
print(" %s %s %s" % (pw(a, 24), rw(b, 22), rw(c, 22)))
print(" 표본이 만 개를 넘으면 커널 방법이 무거워집니다")
print(" 그래서 219강의 부스팅이 실무에서 더 많이 쓰입니다")
print(" 마지막으로 여섯 방법을 한자리에 놓습니다")
print(" %s %s %s %s"
% (pw("방법", 20), rw("무엇을 가정하나", 22), rw("경계 모양", 18),
rw("어느 점이 중요한가", 22)))
for a, b, c, d in [("이웃", "가까우면 비슷함", "아무 모양", "다수결이라 전부"),
("나이브 베이즈", "변수가 독립", "대개 직선", "전부 세기"),
("나무", "축에 나란함", "계단", "나눔 근처"),
("숲", "위와 같음", "부드러운 계단", "전부"),
("부스팅", "위와 같음", "부드러운 계단", "잔차가 큰 점"),
("서포트 벡터", "여백이 클수록 좋음", "커널이 정함",
"경계 근처만")]:
print(" %s %s %s %s"
% (pw(a, 20), rw(b, 22), rw(c, 18), rw(d, 22)))
print(" 여섯이 모두 다른 것을 가정합니다. 어느 것이 맞는지는 자료가 정합니다")
print(" 212강의 교차검증이 그 답을 자료에게 묻는 유일한 방법입니다")
print(" 220강으로 04단원이 끝납니다. 221강부터는 라벨 없이 구조를 찾습니다")
# 215강부터 219강까지는 공간을 어떻게 나눌지를 다뤘습니다
# 이번에는 경계를 직접 긋되 가장 여유 있는 자리에 긋습니다
# 무엇 로지스틱 회귀 여백 최대 경계
# 무엇을 최소화 로그손실 노름 더하기 힌지
# 모든 점이 기여하나 예 아니오
# 완전히 갈리면 계수가 발산 여백이 유일하게 정해짐
# 확률을 내나 예 아니오
# 커널을 끼울 수 있나 어려움 쉬움
# 208강 문제 4 에서 완전 분리면 로지스틱 계수가 발산한다고 했습니다
# 여백을 최대로 하면 그 자리가 하나로 정해집니다
# 완전히 갈리는 자료에서 두 방법을 견줍니다
# 표본 144 개이고 완전히 갈립니다
# 걸음 수 로지스틱 계수 크기 힌지 계수 크기 힌지 여백
# 200 3.903827 1.601297 0.607123
# 2000 6.510109 1.601442 0.595974
# 20000 9.563336 1.601685 0.595999
# 100000 11.861343 1.601521 0.601671
# 로지스틱 계수는 걸음을 늘릴수록 계속 커집니다
# 힌지 계수는 어느 값에서 멈춥니다. 여백이 정해졌기 때문입니다
# 여백은 경계에서 가장 가까운 점까지의 거리입니다
# 여백을 정하는 점이 몇 개인지 셉니다
# 무엇 개수 전체 대비 비율
# 경계 위나 안쪽에 있는 점 4 0.027778
# 여백 바깥에 있는 점 140 0.972222
# 전체 144 1.000000
# 경계를 정하는 데 쓰이는 점이 아주 적습니다
# 이 점들을 서포트 벡터라 합니다
# 215강 문제 5 에서 경계 근처만 남기면 이웃 방법이 무너졌습니다
# 서포트 벡터만 남기고 다시 풀어 봅니다
# 무엇으로 풀었나 첫 계수 둘째 계수 절편
# 전체 144 개 1.122257 1.142544 0.043453
# 서포트 벡터 4 개 1.381657 1.309572 -0.048698
# 두 계수의 비 0.982244 1.055045
# 두 경계가 같은 판정을 내리는 비율은 1.000000 입니다
# 140 개를 지웠는데 판정이 하나도 안 바뀝니다
# 나머지 점은 정말 안 쓰였습니다
# 이웃 방법은 다수결이라 먼 점이 필요했고 여기서는 필요 없습니다
# 218강 문제 4 의 근접도처럼 어느 점이 중요한지가 방법마다 다릅니다
# 완전히 안 갈리는 자료에서는 여유를 허용해야 합니다
# 베이즈 최적 정확도는 0.851200 입니다
# C 계수 크기 여백 폭 서포트 벡터 수 검증 정확도
# 0.1 0.113478 8.812282 383 0.507200
# 1.0 0.507164 1.971749 282 0.836800
# 10.0 0.928611 1.076877 173 0.845600
# 100.0 1.200406 0.833051 141 0.846000
# 1000.0 1.250592 0.799621 135 0.848400
# 여백 폭은 1 나누기 계수 크기입니다. 두 경계선 사이의 거리입니다
# C 가 0.1 이면 계수가 거의 0 이라 아무것도 못 배웁니다. 정확도가 0.5072 입니다
# C 를 키우면 여백이 좁아지고 서포트 벡터가 383 개에서 135 개로 줍니다
# 학습 자료를 더 맞추려 들수록 경계를 정하는 점이 적어집니다
# C 는 211강의 lambda 의 역수입니다. 1 나누기 C 가 벌점 세기입니다
# 힌지 손실이 다른 손실과 어떻게 다른지 봅니다
# 여백 m 힌지 로지스틱 지수 0 과 1
# -2.0 3.000000 2.126928 7.389056 1.0
# -0.5 1.500000 0.974077 1.648721 1.0
# 0.5 0.500000 0.474077 0.606531 0.0
# 1.0 0.000000 0.313262 0.367879 0.0
# 2.0 0.000000 0.126928 0.135335 0.0
# 4.0 0.000000 0.018150 0.018316 0.0
# 힌지는 여백 1 을 넘으면 정확히 0 입니다. 그래서 점이 빠집니다
# 로지스틱은 아무리 잘 맞혀도 0 이 안 됩니다. 모든 점이 조금씩 기여합니다
# 지수는 틀린 점에 폭발적으로 반응합니다. 219강 심화 2 의 그 손실입니다
# 세 손실이 이상점에 얼마나 흔들리는지 잽니다
# 라벨을 뒤집은 점을 늘려 가며 검증 정확도를 봅니다
# 뒤집은 점 수 힌지 로지스틱 차
# 0 0.836800 0.847600 -0.010800
# 5 0.834000 0.845600 -0.011600
# 20 0.827200 0.832000 -0.004800
# 60 0.715600 0.761200 -0.045600
# 멀리 있는 점의 라벨을 뒤집었습니다. 가장 나쁜 이상점입니다
# 힌지가 로지스틱보다 조금씩 더 나쁩니다. 통념과 반대입니다
# 힌지가 무시하는 것은 잘 맞힌 점이지 크게 틀린 점이 아닙니다
# 크게 틀린 점에 대해 힌지도 로지스틱도 기울기가 1 로 일정합니다
# 둘 다 선형으로 반응하므로 이상점 내성에서 큰 차이가 없습니다
# 정말 튼튼하게 만들려면 219강의 후버처럼 손실을 잘라야 합니다
# 직선으로 안 갈리는 자료를 봅니다
# 원 안이면 양성입니다. 직선으로는 못 나눕니다
# 무엇을 썼나 검증 정확도 변수 개수
# 원래 변수 둘 0.627000 2
# 제곱과 곱을 더함 0.980500 5
# 변수를 늘리면 직선으로 갈립니다. 원래 공간에서는 원입니다
# 228강의 특성공학이 하는 일입니다. 그런데 차수를 올리면 변수가 폭발합니다
# 차수를 올릴 때 변수 개수가 얼마나 느는지 셉니다
# 원래 변수 수 차수 2 차수 3 차수 5
# 2 6 10 21
# 10 66 286 3003
# 100 5151 176851 96560646
# 1000 501501 167668501 8459043543951
# 변수 1000 개에 차수 5 면 항이 천문학적으로 많습니다
# 그런데 힌지 문제의 해가 점들의 내적으로만 적힙니다
# 그러면 변수를 만들지 않고 내적만 계산하면 됩니다. 이것이 커널 요령입니다
# 커널이 정말 같은 답을 내는지 확인합니다
# 차수 2 다항 커널과 직접 만든 변수를 견줍니다
# 무엇 값 무엇을 뜻하나
# 직접 만든 변수의 내적 최대 159.528979 6 차원 계산
# 커널 함수의 값 최대 159.528979 2 차원 계산
# 둘의 최대 차이 5.684342e-14 같은 것
# 변수를 6 개 만들어 내적한 것과 커널 한 번 계산한 것이 같습니다
# 차수가 올라가도 커널 계산 비용은 그대로입니다
# 84강의 내적이 여기서 계산을 통째로 아껴 줍니다
# 커널마다 어떤 경계를 그리는지 봅니다
# 커널 식 어떤 경계
# 선형 x 와 z 의 내적 직선
# 다항 p 차 내적 더하기 1 의 p 제곱 p 차 곡면
# 가우스 exp 마이너스 감마 거리 제곱 아무 모양
# 시그모이드 tanh 꼴 신경망 비슷
# 가우스 커널은 무한 차원 특성 공간에 대응합니다
# 실제로 갈아 끼워 잽니다
# 커널 검증 정확도 계수가 큰 점의 수 전체 대비
# 선형 0.519000 300 1.000000
# 다항 2 차 0.961500 261 0.870000
# 다항 3 차 0.949000 263 0.876667
# 가우스 감마 0.2 0.970000 210 0.700000
# 가우스 감마 1.0 0.968500 142 0.473333
# 가우스 감마 20.0 0.962500 223 0.743333
# 선형 커널은 0.519000 으로 원을 못 잡습니다. 동전 던지기와 다를 바 없습니다
# 다항 2 차부터 0.96 을 넘고 가우스 감마 0.2 가 0.970000 으로 가장 좋습니다
# 감마를 20 까지 키워도 0.962500 로 크게 안 떨어집니다
# 여기서는 제곱오차를 써서 계수가 희소하지 않습니다. 대부분이 큽니다
# 문제 1 처럼 소수만 남으려면 힌지 손실이라야 합니다
# 힌지가 여백 밖을 정확히 0 으로 만드는 것이 희소성의 원천입니다
# 감마가 커지면 왜 이웃 방법이 되는지 봅니다
# 감마 가장 가까운 점의 커널 값 두 번째 점의 커널 값 둘의 비
# 1.0 0.9852563972 0.9629991889 1.023112
# 10.0 0.8619709587 0.6858974897 1.256705
# 100.0 0.2264260233 0.0230458183 9.825037
# 1000.0 0.0000003542 0.0000000000 8381891775.056154
# 감마가 크면 가장 가까운 점만 무게를 갖습니다
# 215강의 커널 회귀와 같은 식입니다. 폭 h 가 여기서는 1 나누기 루트 감마입니다
# 감마가 작으면 모든 점이 비슷한 무게를 가져 거의 직선이 됩니다
# 커널이 되려면 무엇이 필요한지 확인합니다
# 대칭이고 그람 행렬이 준양정부호여야 합니다
# 함수 가장 작은 고유값 커널인가
# 선형 0.000000 예
# 다항 3 차 0.000000 예
# 가우스 0.000000 예
# 거리 그대로 -132.177007 아니오
# 마지막 줄은 고유값이 음수라 커널이 아닙니다
# 아무 유사도 함수나 커널이 되지는 않습니다
# 86강의 준양정부호가 여기서 조건이 됩니다
# 실무에서 무엇을 정해야 하는지 정리합니다
# 무엇 무엇을 바꾸나 어떻게 정하나
# C 여백과 오분류의 절충 212강 교차검증
# 커널 경계의 모양 먼저 선형으로 시작
# 감마 얼마나 국소적인가 C 와 함께 격자로
# 표준화 거리의 뜻 반드시 먼저
# 갈래 셋 이상 이진 문제로 쪼갬 하나 대 나머지
# 넷째 줄이 중요합니다. 커널이 거리를 쓰므로 215강과 같은 문제가 생깁니다
# 표준화를 안 하면 어떻게 되는지 잽니다
# 둘째 변수 배율 표준화 안 함 표준화 함 차
# 1 0.968500 0.972500 0.004000
# 5 0.955000 0.972500 0.017500
# 20 0.900000 0.972500 0.072500
# 배율을 키우면 표준화 안 한 쪽이 0.9685 에서 0.9000 으로 떨어집니다
# 215강 문제 2 와 완전히 같은 현상입니다. 커널도 거리를 씁니다
# 표준화한 쪽은 어느 배율에서나 같은 값입니다
# 계산 비용을 셉니다
# 무엇 비용 표본 10000 이면
# 커널 행렬 만들기 n 제곱 1 억 개
# 메모리 n 제곱 곱하기 8 바이트 800 메가바이트
# 이중 문제 풀기 n 제곱에서 세제곱 아주 느림
# 예측 한 건 서포트 벡터 수 수천 번 계산
# 표본이 만 개를 넘으면 커널 방법이 무거워집니다
# 그래서 219강의 부스팅이 실무에서 더 많이 쓰입니다
# 마지막으로 여섯 방법을 한자리에 놓습니다
# 방법 무엇을 가정하나 경계 모양 어느 점이 중요한가
# 이웃 가까우면 비슷함 아무 모양 다수결이라 전부
# 나이브 베이즈 변수가 독립 대개 직선 전부 세기
# 나무 축에 나란함 계단 나눔 근처
# 숲 위와 같음 부드러운 계단 전부
# 부스팅 위와 같음 부드러운 계단 잔차가 큰 점
# 서포트 벡터 여백이 클수록 좋음 커널이 정함 경계 근처만
# 여섯이 모두 다른 것을 가정합니다. 어느 것이 맞는지는 자료가 정합니다
# 212강의 교차검증이 그 답을 자료에게 묻는 유일한 방법입니다
# 220강으로 04단원이 끝납니다. 221강부터는 라벨 없이 구조를 찾습니다