본문 바로가기

Computer Engineering/Machine Learning

[Kaggle] Employee Access Challenge

학교 머신러닝 수업때문에 kaggle competition(http://kaggle.com)을 하는데, 

생각보다 재밌어서 수업 끝나고도 틈틈히 할것같다.

우선 다 끝난 competition들로 공부좀 하고, active competition을 해보면 재밌을듯하다


모델은 Logistic regression을 사용하였고, feature선택은 greedy selection을 사용하였다.

(내 아이디어는 아니고, 포럼에서 메인으로 언급되는 아이디어)

logistical regression에 대한 설명은 많은것 같아서 따로 안하고, 실제로 어떻게 사용했는지만 써놔야겠다.

python의 scikit-learn (sklearn)을 사용하여, 코딩하였다.


지금은 이미 종료된 competition인 employee access challenge를 대상으로 연습해보았다.

이 대회가 데이터 분석은 전혀 필요없고 (하고 싶어도 할 수가 없다.)

오로지 머신러닝 테크닉만 이용해도 좋은 성적을 낼 수 있는 대회인것 같다.


이 competition은, employee들의 Manager ID와 Role에 관련된 여러가지 값들이 주어지고, 

그 employee가 특정 resource에 접근을 요청했을때, 접근을 허용할지 안할지를 판단하는 내용이다.


> 특이사항


이 challenge에서 data의 특이사항은 다음과 같다.


  

  1. action의 값은 0(not approved)와 1(approved)이긴 하지만, 실제 제출할때는 꼭 0과 1이어하는것은 아니다.

  2. 각 column은 어느 '정도'를 나타내는 특성들이 아니다. 단지, 다른 row들과 구분만 가능한 값이다.

 


1. action의 값은 0(not approved)와 1(approved)이긴 하지만, 실제 제출할때는 꼭 0과 1이어하는것은 아니다.


이 말이 무슨 뜻이냐면, 이 competition에서는 AUC로 rank를 매긴다.

근데, 여기서의 AUC는 accuracy가 아니다.

실제 데이터에서 action 1이 94%정도를 차지하고 있기때문에, 

단순한 정확도를 사용하게되면, 전부 1만 써 넣어도 정확도가 94%가 되어버린다.

그래서 이 competition에서는 ROC AUC(Area under curve)를 사용한다.

사실, ROC AUC에 대해서 정확히 공부하지는 않아서, 완벽한 의미는 모르지만.

대충 이야기해보자면, 

True Positive Rate와 False Positive Rate를 이용하여, 그래프를 그리고, 그 그래프의 넓이가 점수가 된다.

그리고, ROC AUC를 측정할 때는 '순서'가 중요하다. 확률이 높은것부터, 높은 값을 주면 된다.

그래서, 제출할때 꼭 0 ~ 1 사이의 값을 넣지 않아도 상관 없다. 

그저 확실히 1이라고 생각되는것부터 높은값을 준 후, 제출하면 된다.

(단순히, 확률을 넣어서 제출하는게 편하다)


2. 각 column은 어느 '정도'를 나타내는 특성들이 아니다. 단지, 다른 row들과 구분만 가능한 값이다.


data를 받아서 보면 알겠지만, 모든 값들이 숫자로 주어져있다.

그리고, 그 숫자가 높은 등급을 의미하는것도 아니다.

예를 들어, ROLE_TITLE의 값들이 원래 의미하는 것들은, CEO, Engineer, Marketer 등을 의미하겠지만, 

이 대회에서는 데이터 값이 1,2,3 과 같이 숫자가 적혀있다. (CEO가 1인지 2인지 3인지 알수없다.)

그래서, Logistical regression에서는 각 컬럼을 곧바로 feature로 사용할 수가 없다. 

왜냐하면......

LR은 각 feature가 연속성이 있는 값이라고 생각하고 만들어져 있는 모델이기 때문이다.

(여기서의 연속성은, continuous, discrete와 같은 것이 아니고, 숫자 높낮이의 의미가 있냐 없냐 이다.)



> Feature Selection


feature의 선택은 다음과 같다.


 

  1. 중복되는 column을 제거한다.

  2. column을 grouping하여, 확장한다.

  3. 각 column을 one hot encoding하여 binary로 변환한다.

  4. greedy로 feature를 선택한다.



1. 중복되는 column을 제거한다.


우선, 값이 중복되는 컬럼을 제거한다.

반드시 제거해야 하는것은 아니지만, 괜히 분석시간만 늘어나기 때문에..

그래서, TITLE과 겹치는 ROLE_CODE를 제거하였다.


2. column을 grouping하여, 확장한다.


grouping을 한다는게, 무슨 말이냐면

기존의 컬럼을 0,1,2,3,4,5,... 라고 한다면, 그냥 기존의 컬럼만 사용하면, 너무 독립적이게 된다.

예를 들어, 정답함수가 '0번 컬럼이 10이고, 1번 컬럼이 5일때, 정답은 1이다.' 라면,

0번이 ~~이고, 1번이 ~~일때, 라는 'and' 연산을 캐치할 수가 없다.

이런 연산을 캐치하기 위해서는, and연산을 한 컬럼을 아예 새로 만들어줘야 한다.

그래서, 기존의 0,1,2,3,... 의 컬럼과 더불어, (0과 1), (0과 2), (0과 3), ..., (1과 2), (1과 3), ...., (0과 1과 2), ..., (0과 1과 2와 3), ...

이런 컬럼들을 추가로 만들어주고, 그 컬럼의 값은 각 컬럼들에 있는 값들의 해시값으로 하면 된다.

그래서 grouping을 하면 할수록, 저런 and연산이 들어간 함수들을 더 잘 캐치할 수 있고, 정확도가 올라간다.

(물론, 속도는 점점 느려진다)


3. 각 column을 one hot encoding하여 binary로 변환한다.


아까 이야기한 특이사항 2번을 해결하기 위해서 각 피쳐들을 binary 포맷으로 바꿔야 한다. 

(이걸 forum에서는 One Hot Encoding 이라고 부르던데, 공식 명칭인지는 잘 모르겠다.)

예를 들어,


 

Column1 

 1

1234

 2

2345

 3

3456


이것이 기존의 컬럼이라면,



 

 1234

2345 

3456 

 1

 1

0

0

 2

 0

1

0

 3

 0

0

1


이렇게 변환하고, Column1대신 1234, 2345, 3456을 feature로 준다.

이렇게 변환함으로써, Logistic regression의 feature로 사용 가능하다.



4. greedy로 feature를 선택한다.


grouping으로 확장된 컬럼들을, 하나씩 넣어보면서 가장 높은 AUC가 나오는 컬럼을 선택해서, list에 포함한다.

포함 하고 나면, 다시 처음으로 돌아가서 모아둔 list에 또 컬럼들을 하나씩 더 추가해보면서, 가장 높은 AUC를 찾는다.

이 과정을 반복하여, 최종 feature들의 set를 뽑아낸다.



이렇게 하면 최종적으로 logistic regression만을 사용해서, 0.89 이상이 나온다.

포럼을 살펴보면 알겠지만, 여기까지는 거의 기본적인 점수이고, 여기서 조금조금씩 끌어 올려야 한다.

logistic regression 만으로 0.91까지 올린 사람들도 있는듯 하다.

그 외에 boosting (여러 모델들을 합쳐서)을 하여, 점수를 올릴수도 있으며, 1위도 이 방법을 사용하였다.


아래의 링크를 따라가면 샘플코드가 있다.


참고: http://kaggle.com/c/amazon-employee-access-challenge/forums/t/5258/how-i-modified-miroslaw-s-code