2. 강성희
2017 ~ Current: Co-Founder & CEO @DS School
2013 ~ Current: Mentor @Software Maestro
2015 ~ 2016: Partner @Naver D2 Startup Factory
2010 ~ 2016: CEO @Wow Insights(formerly Walk Inc.)
2007 ~ 2010: Software Engineer @Hanbit Soft & T3 Entertainment
3. 서론
오늘의 내용
• Scikit-Learn이라는 오픈소스 프로젝트에 Contribution을 시도한 이야기
• 결과적으로는 공헌에 실패(=master 브랜치에 머지되지 않음)
• Scikit-Learn을 획기적으로 개선하거나 유저에게 큰 도움을 줄 거라는 기대로 시작하지 않음
• 발표자 개인적인 목표인 ‘라이브러리를 완벽하게 이해하기 위한 과정’의 하나로서 시작
4. 서론
오늘의 내용
• Scikit-Learn이라는 오픈소스 프로젝트에 Contribution을 시도한 이야기
• 결과적으로는 공헌에 실패(=master 브랜치에 머지되지 않음)
• Scikit-Learn을 획기적으로 개선하거나 유저에게 큰 도움을 줄 거라는 기대로 시작하지 않음
• 발표자 개인적인 목표인 ‘라이브러리를 완벽하게 이해하기 위한 과정’의 하나로서 시작
오늘의 발표를
Success Case가 아닌, Fail Case의 하나로 받아들어주셨으면 좋겠습니다.
7. 시작
데이터를 다루기 위한 오픈소스 파이썬 패키지. 이 중 Scikit-Learn이 오늘의 주제
http://scikit-learn.org/
https://github.com/scikit-learn/scikit-learn/
8. Scikit-Learn에 공헌하기 - RMSE(Root Mean Squared Error)
우리가 예측한 결과(predict, 이하 p)가 정답(actual, 이하 a)에 얼마나 근접한지 알기 위해,
우리는 측정 공식을 정의하고 사용한다. RMSE는 그 측정 공식 중 하나.
1. Mean Absolute Error(MAE)
2. Mean Squared Error(MSE)
3. Root Mean Squared Error(RMSE)
참고자료: MAE and RMSE — Which Metric is Better?
https://goo.gl/BhmVJW
9. Scikit-Learn에 공헌하기 - RMSE(Root Mean Squared Error)
우리가 예측한 결과(predict, 이하 p)가 정답(actual, 이하 a)에 얼마나 근접한지 알기 위해,
우리는 측정 공식을 정의하고 사용한다. RMSE는 그 측정 공식 중 하나.
1. Mean Absolute Error(MAE)
2. Mean Squared Error(MSE)
3. Root Mean Squared Error(RMSE)
참고자료: MAE and RMSE — Which Metric is Better?
https://goo.gl/BhmVJW
?
10. Scikit-Learn에 공헌하기 - RMSE(Root Mean Squared Error)
RMSE를 구현한 뒤 Scikit-Learn에 Pull Request를 날렸다.
11. Scikit-Learn에 공헌하기 - RMSE(Root Mean Squared Error)
결과적으로는 공헌이 받아들여지지 않았다. Master 브랜치에 merge되지 않은 채, 지금도 PR이 그대로 남아있다.
https://github.com/scikit-learn/scikit-learn/pull/6457
첫 시작
2016.2.27
Merge 실패
2016.10.15
아무도 반응이 없음 ㅠㅠ
2016.3.04
1차 피드백+개선
2016.2.29
옛다 관심 ㅋ
2016.3.27
뜬금 rebase 요청;;
2016.10.11
총 기간: 2016.2.27 ~ 206.10.15 (약 8개월)
다섯 명의 관계자가 토론. (이 중 3명은 Commiter)
다섯 명이 1,000자가 넘는 토론을 벌임. (강연자 인생 가장 긴 영작 토론)
13. 배경지식을 갖추기
섭씨(Celcious)를 화씨(Farenhight)로 변환하는 간단한 알고리즘을 작성.
단 온도 변환에 대한 아무런 사전 지식 없이, 인공지능 알고리즘이 스스로 변환 공식을 찾도록 유도한다.
섭씨-화씨 변환 공식
섭씨 화씨
20 68
22 71.6
14 57.2
36 96.8
공식을 바탕으로 데이터셋을 구축. (약 100여 개)
인공지능 알고리즘을 학습시키기
예측값(predict)과 실제값(actual) 사이의 갭을 구한 뒤,
이 갭을 기준으로 보간해나간다
Gradient Descent 라는 알고리즘을 활용해
스스로 섭씨-화씨 변환을 하도록 학습한다.
14. 배경지식을 갖추기
섭씨(Celcious)를 화씨(Farenhight)로 변환하는 간단한 알고리즘을 작성.
단 온도 변환에 대한 아무런 사전 지식 없이, 인공지능 알고리즘이 스스로 변환 공식을 찾도록 유도한다.
섭씨-화씨 변환 공식
섭씨 화씨
20 68
22 71.6
14 57.2
36 96.8
공식을 바탕으로 데이터셋을 구축. (약 100여 개)
인공지능 알고리즘을 학습시키기
예측값(predict)과 실제값(actual) 사이의 갭을 구한 뒤,
이 갭을 기준으로 보간해나간다
Gradient Descent 라는 알고리즘을 활용해
스스로 섭씨-화씨 변환을 하도록 학습한다.
15. 배경지식을 갖추기
섭씨(Celcious)를 화씨(Farenhight)로 변환하는 간단한 알고리즘을 작성.
단 온도 변환에 대한 아무런 사전 지식 없이, 인공지능 알고리즘이 스스로 변환 공식을 찾도록 유도한다.
섭씨-화씨 변환 공식
섭씨 화씨
20 68
22 71.6
14 57.2
36 96.8
공식을 바탕으로 데이터셋을 구축. (약 100여 개)
인공지능 알고리즘을 학습시키기
예측값(predict)과 실제값(actual) 사이의 갭을 구한 뒤,
이 갭을 기준으로 보간해나간다
Gradient Descent 라는 알고리즘을 활용해
스스로 섭씨-화씨 변환을 하도록 학습한다.
16. 배경지식을 갖추기
섭씨(Celcious)를 화씨(Farenhight)로 변환하는 간단한 알고리즘을 작성.
단 온도 변환에 대한 아무런 사전 지식 없이, 인공지능 알고리즘이 스스로 변환 공식을 찾도록 유도한다.
섭씨-화씨 변환 공식
섭씨 화씨
20 68
22 71.6
14 57.2
36 96.8
공식을 바탕으로 데이터셋을 구축. (약 100여 개)
인공지능 알고리즘을 학습시키기
예측값(predict)과 실제값(actual) 사이의 갭을 구한 뒤,
이 갭을 기준으로 보간해나간다
Gradient Descent 라는 알고리즘을 활용해
스스로 섭씨-화씨 변환을 하도록 학습한다.
17. 배경지식을 갖추기
섭씨(Celcious)를 화씨(Farenhight)로 변환하는 간단한 알고리즘을 작성.
단 온도 변환에 대한 아무런 사전 지식 없이, 인공지능 알고리즘이 스스로 변환 공식을 찾도록 유도한다.
섭씨-화씨 변환 공식
섭씨 화씨
20 68
22 71.6
14 57.2
36 96.8
공식을 바탕으로 데이터셋을 구축. (약 100여 개)
인공지능 알고리즘을 학습시키기
예측값(predict)과 실제값(actual) 사이의 갭을 구한 뒤,
이 갭을 기준으로 보간해나간다
Gradient Descent 라는 알고리즘을 활용해
스스로 섭씨-화씨 변환을 하도록 학습한다.
18. 배경지식을 갖추기
섭씨(Celcious)를 화씨(Farenhight)로 변환하는 간단한 알고리즘을 작성.
단 온도 변환에 대한 아무런 사전 지식 없이, 인공지능 알고리즘이 스스로 변환 공식을 찾도록 유도한다.
섭씨-화씨 변환 공식
섭씨 화씨
20 68
22 71.6
14 57.2
36 96.8
공식을 바탕으로 데이터셋을 구축. (약 100여 개)
인공지능 알고리즘을 학습시키기
예측값(predict)과 실제값(actual) 사이의 갭을 구한 뒤,
이 갭을 기준으로 보간해나간다
Gradient Descent 라는 알고리즘을 활용해
스스로 섭씨-화씨 변환을 하도록 학습한다.
19. 배경지식을 갖추기
인공지능의 예측 결과가 잘 맞는지 확인하기 위해,
보유한 데이터에서 일정 부분을 떼 예측한 뒤 이를 Scoring Metric(ex: MSE)로 측정한다.
Cross Validation
A B C D E
20 개 20 개 20 개 20 개 20 개
데이터 갯수: 100 개
4. A + B + C + E
5. A + B + C + D
3. A + B + D + E
2. A + C + D + E
1. B + C + D + E A
B
C
D
E
데이터를 5조각 낸 뒤,
조각을 뺀 나머지로 알고리즘을 학습하고, 조각을 예측한다.
이후 그 결과값의 평균을 낸다.
평균(mean)을 구한다
20. MSE와 MAE는 결과값이 음수가 나온다!
기존에 우리가 알고 있던 공식과 다르게, MAE와 MSE는 결과값이 음수로 나온다.
하지만 발표자가 구현한 RMSE는 결과값이 양수로 나오기 때문에, 서로 맞지 않는다.
1. Mean Absolute Error(MAE)
2. Mean Squared Error(MSE)
3. Root Mean Squared Error(RMSE)
= -0.51832
= -0.34168
= +0.11672
21. 실패 사유
발표자는 MAE와 MSE를 양수가 나오도록 수정하려고 했지만,
담당자(GaelVaroquaux)는 RMSE의 결과값이 음수가 나오도록 수정해야 한다고 제안.
E
24. 관련 기록을 찾기
깃헙의 이슈란에는 심지어 2013년 9월에 관련 글이 존재
E
https://github.com/scikit-learn/scikit-learn/issues/2439
25. 관련 기록을 찾기
메일링 리스트에도 관련 토론이 있다. 이것도 2013년 10월
E
https://www.mail-archive.com/scikit-learn-general@lists.sourceforge.net/msg08945.html
26. 관련 기록을 찾기
2015년도, 2016년도에도 이와 관련된 이슈와 PR이 있다.
E
https://github.com/scikit-learn/scikit-learn/pull/6028
https://github.com/scikit-learn/scikit-learn/issues/6129
28. 관련 기록을 찾기
심지어 Spark에도 유사 사례가 존재한다! (이것도 Scikit-Learn 깃헙 이슈에서 발견)
E
29. 관련 기록을 찾기
다 적을 수 없을 정도로 많은 곳에서 이 이슈에 대해서 다루고 있다
E
Stack Overflow
sklearn GridSearchCV with Pipeline
scikit-learn cross validation, negative values with mean squared error
Am I correct to get negative cross_val_score when I am using neg_log_loss in scikit-learn 0.18?
GitHub
MSE is negative when returned by cross_val_score
More intuitive scoring argument for loss and error #5023
Deprecated negative valued scorers
mean_absolute_error gives out negative result
[RFC / SLEP?] Enhance scorer (objective) interface and deprecate the `greater_is_better` attr.
[WIP] Multiple-metric grid search
Fixing MAE and MSE errors. should not be negative when used in cross_val
[MRG + 2] Rename scorers like `mse` to ‘neg_mse'
[Scikit-learn-general] Negative mean_squared_error & other custom metrics using SVR on 0.14.1
ML Evaluator should indicate if metric should be maximized or minimized
31. Hyperparameter
인공지능이 스스로 찾을 수 없는 값을 Hyperparameter 라고 부른다.
지금 우리의 경우, learning_rate를 Hyperparameter라고 볼 수 있다.
E
Hyperparameter(ex: learning_rate)를 수정하면
모델의 결과값이 달라진다.
32. Finding optimal hyperparameters - GridSearchCV
가장 쉬운 방법은, 좋은 Hyperparameter라고 생각할 수 있는 후보들을 전부 다 테스트하는 것이다.
이를 Grid Search라고 하며, Scikit-Learn에는 GridSearchCV라는 클래스가 구현되어 있다.
E
Learning Rate Score(MSE)
0.0001 0.31123
0.0003 0.27836
0.0005 0.30214
0.0007 0.37423
33. Hyperparameter - Bigger is better? Smaller is better?
우리가 사용하는 Scoring Metric에 따라,
가장 작은 값에 해당하는 Hyperparameter를 선택할지, 가장 큰 값에 해당하는 Hyperparameter를 선택할지 달라진다.
E
Learning Rate Score(Accuracy)
0.0001 0.8979
0.0003 0.91231
0.0005 0.96129
0.0007 0.79123
Learning Rate Score(MSE)
0.0001 0.31123
0.0003 0.27836
0.0005 0.30214
0.0007 0.37423
Scoring Metric이 Accuracy(퍼센티지)라면
가장 큰 값(0.96129)에 해당하는 Learning Rate(0.0005)를 반환한다.
Scoring Metric이 MSE라면
가장 작은 값(0.27836)에 해당하는 Learning Rate(0.0003)를 반환한다.
34. Hyperparameter - Bigger is better? Smaller is better?
이를 구현하는 방식은 크게 세 가지로 나뉠 수 있다
E
bigger_is_better가 True면 Score가 가장 큰 Hyperparameter를 반환하고,
bigger_is_better가 False면 Score가 가장 작은 Hyperparameter를 반환한다.
1. Grid Search에 bigger_is_better 옵션을 추가한다.
35. Hyperparameter - Bigger is better? Smaller is better?
이를 구현하는 방식은 크게 세 가지로 나뉠 수 있다
E
1. Grid Search에 bigger_is_better 옵션을 추가한다.
scoring과 bigger_is_better가 다르면 문제가 생긴다. (게다가 Grid Search는 오래 걸린다!)
bigger_is_better가 True면 Score가 가장 큰 Hyperparameter를 반환하고,
bigger_is_better가 False면 Score가 가장 작은 Hyperparameter를 반환한다.
36. Hyperparameter - Bigger is better? Smaller is better?
이를 구현하는 방식은 크게 세 가지로 나뉠 수 있다
E
2. Scoring을 만들 때 bigger_is_better 옵션을 추가한다.
Scoring Metric을 만들 때, 이 값이 크면 좋은지 작으면 좋은지를 명시한다.
cross_validation과 GridSearchCV는 가만히 놔둔다.
37. Hyperparameter - Bigger is better? Smaller is better?
이를 구현하는 방식은 크게 세 가지로 나뉠 수 있다
E
2. Scoring을 만들 때 bigger_is_better 옵션을 추가한다.
Scoring Metric을 만들 때, 이 값이 크면 좋은지 작으면 좋은지를 명시한다.
cross_validation과 GridSearchCV는 가만히 놔둔다.
새로운 Scoring Metric을 만들기 너무 복잡하다.
현재의 코드에서 매우 많은 부분을 수정해야 한다.
38. Hyperparameter - Bigger is better? Smaller is better?
이를 구현하는 방식은 크게 세 가지로 나뉠 수 있다
E
3. 아예 모든 Scoring을 bigger_is_better으로 통일한다.
Smaller is better인 Metric(ex: MSE)을 강제로 bigger_is_better로 변환한다.
그리고 GridSearch를 할 때 무조건 Score가 가장 큰 Hyperparameter를 반환한다!
39. Hyperparameter - Bigger is better? Smaller is better?
이를 구현하는 방식은 크게 세 가지로 나뉠 수 있다
E
3. 아예 모든 Scoring을 bigger_is_better으로 통일한다.
Smaller is better인 Metric(ex: MSE)을 강제로 bigger_is_better로 변환한다.
그리고 GridSearch를 할 때 무조건 Score가 가장 큰 Hyperparameter를 반환한다!
PROFIT…?
43. 추가하자면…
Scikit-Learn 뿐만 아니라 Spark에서도 비슷한 고민의 흔적을 발견
이 흔적을 Scikit-Learn의 맴버가 GitHub Issue의 코멘트로 공유
https://issues.apache.org/jira/browse/SPARK-10097
https://github.com/scikit-learn/scikit-learn/issues/5023
44. 추가하자면…
Scikit-Learn 뿐만 아니라 Spark에서도 비슷한 고민의 흔적을 발견
이 흔적을 Scikit-Learn의 맴버가 GitHub Issue의 코멘트로 공유
https://issues.apache.org/jira/browse/SPARK-10097
https://github.com/scikit-learn/scikit-learn/issues/5023
45. 추가하자면…
Scikit-Learn 뿐만 아니라 Spark에서도 비슷한 고민의 흔적을 발견
이 흔적을 Scikit-Learn의 맴버가 GitHub Issue의 코멘트로 공유
https://issues.apache.org/jira/browse/SPARK-10097
https://github.com/scikit-learn/scikit-learn/issues/5023
46. 요약
• 발표자는 Scikit-Learn을 훌륭히 습득했다는 것을 확인하는 차원에서, RMSE Metric을 구현해서 PR을 날림.
• 하지만 이 RMSE Metric은, 기존의 Scikit-Learn Metric과 다르게 작을수록 좋은(smaller is better) Metric이었음.
• 리뷰어는 RMSE Metric에 마이너스를 붙여서, 클 수록 좋은(bigger is better) Metric으로 바꾸는 것을 권장.
• 이 상황을 납득할 수 없었던 발표자는 2013년 깃헙 이슈 + 메일링 리스트부터 관련 내용을 하나하나 뒤져가며 진상을 파악함.
• 결국 무슨 상황인지 파악 완료. 그러나 이해는 되지만 솔직히 납득은 되지 않았다. (..) 이 PR을 수정해서(=마이너스를 붙여서) 계
속 밀어붙여야 하나 고뇌하기 시작함…
• 마음같아서는 GridSearchCV부터 시작해서 Metric 관련 모듈을 통채로 갈아엎고 싶었으나, PR을 날린지 어언 8개월… 이미
열정이 많이 식어버렸음. (매 번 Any Update?를 적는것도 이젠 지친다!)