DS School 5주차: 입문반 마지막- 자체점수화&캐글의 이해
데이터분석을 위해 DS School에서 파이썬을 배운지 한달, 마지막 5회차 수업에 가는 느낌은 조금 달랐다.
어떻게 보면 5회뿐인 수업의 마지막이지만, 그래도 3월 한 달 동안 이 수업의 예습-수업-복습 단계를 철저히 밟으며 일주일 중에 가장 많은 시간을 투자했기 때문에 짧은 시간 내에 얻은 것이 굉장히 많다고 느꼈다. 그랬기에 마지막 수업인 5회차 수업은 나에게 소중할 수 밖에 없었다.
마지막 수업은
1. 이전 Bike Sharing Demand에 대한 복습 겸 점수 끌어올리는 방법에 대해
2. 데이터 시각화에 대해 (따로 다음글에서 다룰 예정)
배우는 것이 메인이었고, 이후 어떤 방식으로 공부를 해 나갈지에 대해서도 강사님을 통해 알 수 있었다.
먼저 Bike Sharing Demand 사례를 통해 이전에 이어서 좀 더 효과적인 데이터 분석을 할 수 있는 팁들에 대해 얘기해보려 한다. Bike Sharing Demand 사례는 이미 이전 글들에 관련 데이터를 첨부하였으니 데이터는 이전 글들에서 받아서 함께 해보면 좋을 것 같다.
Column이 Feature의 의미로 데이터 분석을 할 때, 디씨젼 트리를 실행 시킬 때 중요하다는 것은 이미 수차례 강조한 바 있다. 그렇다면 좋은 Column과 안 좋은 Column을 구분하는 방법은 단순히 나의 주관을 믿는 것과, 시행착오법으로 모든 Column들의 조합을 시도해보는 방법 뿐인 걸까? 조금 더 효율적이고 빠른 방법은 없을까에 대한 고민은 아마 디씨젼트리를 돌려보며 여러 번 시도한 사람들이라면 누구든 했을 것이다.
이 때 사용해 볼 수 있는 방법으로 지니 불순도(Gini Impurity)가 있다.
이 공식을 쓰면 굉장히 쉬운 방식으로 좋은 Column과 안좋은 Column을 구별할 수 있다. 장점은? 심플하다는 것. 설명의 편의성을 위해 Bike Sharing Demand 대신 처음 다뤘던 TItanic 사례를 이용해서 설명하겠다.
지니불순도를 구하는 공식은 1-(Psurvived)^2-(Pperish)^2 [^2는 제곱이라는 표시이다]
으로 나타낼 수 있다.
따라서 만약 survived가 100이고 perish가 0이라면 1-(100/100)^2-(0/100)^2=0 이 나오겠고,
survived가 50, perish가 50이면 1-(50/100)^2-(50/100)^2=0.5 가 나올 것이다.
생존과 사망이라는 직관적인 사례로 바로 알 수 있듯이 공식에 대입해 본 결과값이 0에 가까울수록 좋은 Column DATA라고 볼 수 있는것이다. 이를 어떻게 적용하냐하면, Train Data를 다 불러온다음에 Column들을 다 쪼개서 0에 가깝게 Gini Impurity 값이 나온 애들이 좋은 Column이라 판단하고 분석을 진행하면 된다. 언제까지 이 과정을 밟냐고 묻는 다면 Max Depth로 설정해 둔 값까지가 그 답이 되겠다.
이 과정을 그럼 하나하나 우리가 수행하고 있어야 하나? 그건 전혀 아니다. 이 지니불순도는, 다 쪼개고 또 쪼개서 지니가 0이 될 때까지, 혹은 max depth가 될 때까지 반복하는 이 과정은 바로 Decision Tree의 원리와 직결된다. 우리가 할 것은 "아 이 과정이 지니불순도의 개념을 차용한 것이구나" 라고 이해하고 그저 Decision Tree를 가져와서 Fit하고 Predict해서 돌리면 될 뿐이다.
참고로 디씨젼 트리에서 지니불순도가 적용된 예시를 하나 들어 앞선 짧은 예시보다 좀 더 일반적인 공식활용을 알아보겠다.
#gini=0.473
#samples=891
#value=[549,342]
#class=Perish
1-(549/891)*(549/891)-(342/891)*(342/891)
즉, 이에 따른 결과값은 0.5에 근접한 0.473으로 나오니까 안좋은 컬럼이라고 판단할 수 있다.
이번엔 캐글 Competition시스템에 대해서 더 알아보자.
캐글은 제출(Submit) 맥시멈 카운트가 있다. 하루에 10회. 즉, 하루에 정답을 제출할 수 있는 기회가 10번 주어고 그 이후에는 제출한 결과가 어떻게 나오는지 캐글 상에서는 확인이 불가하다는 말이다. 따라서 캐글 자체를 사용하지 않고 내가 만든 모델이 잘 만든 모델인지를 알아볼 방법이 있다. 매우 유용한 방법이다.
이 때 사용되는 검증 방법이 두 가지로 나뉘는데, Hold-Out Validation과 Cross Validation이다.
Hold-out Validation은 예를 들면 Train Data가 10000개 일때 이를 두조각으로 나눠서
1) 8000개를 fit해서 남은 2000개를 predict해보는 방식과
2) 그 반대로 2000개를 fit해서 8000개를 predict해보는 방식을
비교해서 두 가지가 같게 나오면 모델이 잘 짜여진것으로 판단하는 검증방법니다.
X,y(actual)<->y(predict)
Hold-out Validation의 한계로는 점수가 잘 안 나올 가능성이 있고 Cross-Validation에 비해 비교적 덜 정확하다는 점이다. 두 가지로 나눴을때 fit이 안 맞을 가능성도 있다.
Cross Validation은 앞선 Hold-Out과 마찬가지로 똑같이 10000개가 있을 때 A,B,C,D 4 파트로 나눠서
1)처음엔 A,B,C 를 fit에 D를 predict에
2)두번째로 A,B,D를 fit에 C를 predict에
3)그 다음엔 A,C,D를 fit에 B를 predict에
4) 마지막으로 B,C,D를 fit에, A를 predict에 넣어 비교검증해보는 방식이다.
더 복잡한 프로세스로 구성된 만큼 홀드아웃 벨리데이션에 비해 정확하고 4개를 하면 기본적으로 3개는 fit이 나온다. 그렇다면 Cross Validation의 단점은? 당연 느리다는 점이다.
조각 잘게 나누면 나눌수록 프로세스가 복잡해지고 거쳐야할 단계가 많아지기에 정확하지만 더 느려지는 것은 직관적으로도 알 수 있는 사실. 따라서 속도가 중요하면 조각을 적게, 정확도가 중요하면 조각을 많이 나누어야 한다. (관례상 5~10개로 나눈다.)
결론적으로는 데이터가 적을 때는 Hold-out validation을 사용하고,
데이터가 많은 경우 Cross Validation을 사용하되 그 조각내는 것을 밸런스에 맞게 결정해야 할 것이다.
##참고 코딩
from sklearn.model_selection import cross_val_score
score=cross_val_score(model, X_train, y_train, cv=20, scoring="neg_mean_absolute_error").mean()
print("Score={0:.5f}".format(score))
<20조각 낸다는것. mean으로 평균내기>
<scoring="neg_mean_absolute_error: mean_absolute_error 사용한다는것.>
Q1: 왜 점수를 내면 (-)로 score가 나오나?
>> +냐-냐는 중요하지 않아. 0에 가까울수록 좋은것만 알아두면 돼.
Q2: 왜 실행할때마다 점수가 다르게 나오나?
>> 우리가 쓰는 DecisionTreeRegressor에 랜덤 속성이들어가서 그런것. 딱히 중요하지도 않고 대세에 영향을 주지도 않는다.
하지만 원활한 값으로 시험하기 위해서는 DecisionTree에서 랜덤 값이 안 나오도록 고정하는 것이 중요하기 때문에 random_state=아무 숫자 로 넣는다.
위의 코딩에 대한 설명을 자세히 본 사람이라면 mean_absolute_error에 대한 의문을 가질 수 있다. 도대체 저게 뭔데 저걸 사용한다는 거지? 하고 궁금할 것이다. 캐글을 자체검증하고 점수화시킬 때는 측정 공식이 중요한데, 내가 짠 모델이 얼마나 정확하게 짠 것인지를 파악하는데에 단순히 퍼센트로 몇프로다 라고 하는것은 굉장히 부적절한 것이 사실이다.
Count=100 : actual값, 즉 실제 값을 (a)로 하고,
Model A=120 / Model B=70 : 이 두개를 predict값, 즉 예측값인 (p)라 할 때
실제값과 예측값이 얼마나 차이나는지 측정해볼 수 있는 공식이 세가지가 있다.
1. Mean Absolute Error= 절댓값 [p-a] : 정확할수록 0에 가깝고 정확하지 않을수록 0에서 멀어진다.
2. Mean Squared Error= (p-a)의 제곱 : 이것도 정확할수록 0에 가깝고 정확하지 않을수록 0에서 멀어진다.
3. Root Mean Squared Error=(p-a)의 제곱을 루트 취해주기
그럼 언제 어떤 공식을 쓰는 것이 유의적일까? 실제값과 예측값 사이의 차이가 크면 클수록 더 페널티를 주고싶다! 라고 하면 2번째 mean squared error를 쓰는 것이 좋다. 제곱을 한만큼 그 차이가 다른 두 공식에 비해 더 크게 나타나기 때문이다. 반대로 그렇지 않다라고 하면 1번째 Mean Absolute Error를 사용한다. 즉, 회사가 측정공식을 선정할 때는 어떤 것을 추구하냐에 따라서 Mean Absolute Error와 Mean Squared Error 중에서 알아서 쓴다. 물론 이 두가지 방식을 메인으로 쓰다가 결국에는 tuning이 들어가긴 한다.
참고로 3번째 Root Mean Squared Error는 사실상 2번과 똑같다.
이러한 측정공식은 Kaggle Competition 상에서 Overview 탭에 측정공식을 제시해주는 경우가 일반적인데, 우리가 할 것은 주어진 측정공식을 보고 반대로 어떻게 접근할지를 유추하는 것이다.
Bike Sharind Demand 사례에서도 Overview 탭의 Evaluation을 보면 3번째 공식인 Root Mean Squared Error의 모양이지만 하나의 차이점을 발견할 수 있다. 바로 그 안에 로그가 있는 것인데 이 의미는 로그 함수가 갖는 "1이 넘으면 완만하게 증가한다"는 특성을이해하면 쉽게 알 수 있다.
즉, 앞서 설명한 2번째 측정공식 Mean Squared Error의 방식과 반대로 차이가 클수록 페널티가 덜 들어가게 설정한 것이다. 이 측정공식은 Root Mean Squared Logasm Error라고 부른다.
언제까지나 캐글 시스템 안에서 데이터분석이 이루어질 수는 없는 법.
데이터 공부에 큰 뜻을 지니고 들어온 만큼, 어느 단계 이상이 되면 Real Life Data들을 활용하여 정해진 방식이나 문제 없이 유의미한 결과를 도출해내어야 좋은 데이터분석가의 길로 접어들 수 있을 것이다.
따라서 마지막 시간에 배우기 시작한 자체적인 검증/측정 방식은 상당히 큰 도움이 되었다.
이와 함께 데이터입문반의 꽃이라고도 할 수 있었던 데이터 시각화 또한 배웠는데, 이는 별도로 다음 글에서 다루어보도록 하겠다.