지도학습 모델의 독립변수 중요도를 확인하기 위해 사용하는 Drop Column Importance에 대해 알아본다.
예제 파일: car_bmw3.csv
개요
지도학습 모델을 평가할 때 종속변수를 기반으로 해당 모델의 전반적인 성능을 비교하는 것이 일반적이다. 그리고 더 나아가서 입력된 독립변수의 중요도가 어떠한지 확인하는 작업을 하기도 한다.
※ 모델평가(분류모델) 게시물 확인하기
※ 모델평가(회귀모델) 게시물 확인하기
모델을 만든다고 해서 최종적으로 모든 독립변수를 사용하는 것은 아니다. 어떤 독립변수는 해석하기가 난해할 수 있고, 어떤 독립변수는 (가공 또는 확보)비용이 많이 들 수 있고, 어떤 독립변수는 영향력이나 중요도가 상대적으로 낮아 굳이 필요가 없을 수도 있기에 여러 판단기준에 따라 불필요 하다고 판단되는 독립변수를 모델에서 제외하기도 한다.
이는 모델의 경량화나 정비를 위해 실시하는 특성 공학(Feature Engineering)과 매우 관련이 깊으며 보다 나은 모델을 확보하기 위해 독립변수의 중요도를 아는 것은 중요하다. 그 중요도를 파악하기 위한 방법 중 지도학습 모델에 공통적으로 사용할 수 있는 방법은 대표적으로 두 가지가 있으며 이는 다음과 같다.
- Permutation Importance
- Drop Column Importance
이 게시글에서는 Drop Column Importance에 대해 다룬다.
다음은 독립변수 모두를 사용한 FM(Full Model)과 각 독립변수를 하나씩 제외한 축소모델(RM, Reduced Model)로 그 성능을 평가한 RMSE(Root Mean Squared Error)를 비교하는 그림이다.
일반적으로 특정 독립변수를 하나 제외하고 모델을 평가하면 모델의 성능이 떨어지는데 그 성능이 얼마나 떨어지는지를 확인하는 것이다. 그리고 이를 통해 각 독립변수의 중요도를 파악할 수 있다. 위 그림에서는 FM의 경우 RMSE가 13.232로 나왔다. 그리고 변수 A를 제외하고 평가한 모델 RM1의 RMSE는 21.342가 나와 FM 대비 8.11만큼 감소한 것을 알 수 있다. 이 방식으로 다른 변수들을 하나씩 제외하고 모델을 평가해본다. 최종적으로 가장 RMSE의 증가량이 높은 A변수가 상대적으로 가장 중요한 변수라고 할 수 있고 B 변수가 상대적으로 가장 덜 중요한 변수라고 할 수 있다.
장점
- 모델에 종속되지 않음
- 쉬운 결과 해석
모델에 종속되지 않는 것은 모델의 독립변수별 중요도 평가 방법을 지도학습의 어떠한 모델에도 사용할 수 있다는 것이다. 예를 들어 랜덤포레스트(random forest)의 경우 MDI(Mean Decrease in Impurity)가 있긴 하지만 이는 랜덤포레스트(또는 트리모델)한정으로 사용하는 기법이다. 그래서 이런 자체적인 독립변수 중요도 평가 방법이 존재하지 않는 모델의 경우 Drop Column Importance를 사용하는 것이 좋은 선택이 될 수 있다. 그리고 변수 중요도를 파악하는 과정에서 각 독립변수를 하나씩 제거한 다음에 그 결과를 확인하기 때문에 상대적으로 Permutation Importance보다 그 원리 이해와 해석이 상대적으로 쉽다고 할 수 있다.
단점
기준 평가지표 확인을 위해 모든 독립변수를 사용해서 완전 모형(full model)을 학습하게 된다. 그리고 비교를 위해 각 독립변수가 하나씩 제거된 축소 모형(reduced model)도 독립변수 개수만큼 학습해야 하는데 여기서 연산 비용이 크게 들어간다. 물론 각 모델 학습이 수 분 이내로 끝나면 크게 신경쓰는 내용이 아니겠으나, 모델 학습에 시간단위로 시간소요가 일어난다면 차라리 Permutation Importance를 고려하는 것이 나을 수 있다.
실습
먼저 데이터와 모델을 준비하자. 데이터 “car_bmw3.csv”는 본 게시물 상단 링크를 통해 다운로드 하도록 하자.
1 | import pandas as pd |
year | price | transmission | mileage | fuelType | tax | mpg | engineSize | |
---|---|---|---|---|---|---|---|---|
0 | 2017 | 16500 | Manual | 16570 | Diesel | 125 | 58.9 | 2.0 |
1 | 2017 | 14250 | Automatic | 55594 | Other | 135 | 148.7 | 2.0 |
명목형 변수를 가변수(dummy variable)로 바꾸고 종속변수로 사용할 “price” 변수를 첫 번째로 옮겨보자.
1 | df_dum = pd.get_dummies(df, columns = ["transmission", "fuelType"], dtype = "int") |
price | year | mileage | tax | mpg | engineSize | transmission_Automatic | transmission_Manual | |
---|---|---|---|---|---|---|---|---|
0 | 16500 | 2017 | 16570 | 125 | 58.9 | 2.0 | 0 | 1 |
1 | 14250 | 2017 | 55594 | 135 | 148.7 | 2.0 | 1 | 0 |
2 | 16000 | 2017 | 45456 | 30 | 64.2 | 2.0 | 1 | 0 |
데이터세트를 분리하고 모델을 생성하고 RMSE를 계산한 결과 RMSE가 3577.4인 것을 확인할 수 있다.
1 | df_train, df_test = train_test_split(df_dum, train_size = 0.7, random_state = 123) |
모델과 데이터가 준비되었으니 이제 각 독립변수별 중요도를 계산해보자.
첫 번째 종속변수를 제외하고 독립변수를 하나씩 제외한 데이터를 기반으로 RMSE 계산 결과를 “ls_rmse_sub” 객체에 저장한다.
1 | ls_rmse_sub = [] |
이제 각 중요도를 보기 좋게 정리하면 다음과 같다.
1 | df_perf = pd.DataFrame(dict(col_name = df_train.columns[1:], |
col_name | rmse | diff | diff_nor | |
---|---|---|---|---|
0 | year | 4420.064357 | 842.691447 | 1.000000 |
1 | mileage | 3855.385305 | 278.012396 | 0.331563 |
2 | tax | 3575.288862 | -2.084047 | 0.000000 |
3 | mpg | 4035.507897 | 458.134988 | 0.544783 |
4 | engineSize | 3650.847741 | 73.474831 | 0.089443 |
5 | transmission_Automatic | 3577.372910 | -0.000000 | 0.002467 |
6 | transmission_Manual | 3577.372910 | -0.000000 | 0.002467 |
7 | transmission_Semi-Auto | 3577.372910 | -0.000000 | 0.002467 |
8 | fuelType_Diesel | 3577.372910 | 0.000000 | 0.002467 |
9 | fuelType_Hybrid | 3577.372910 | 0.000000 | 0.002467 |
10 | fuelType_Other | 3577.372910 | -0.000000 | 0.002467 |
11 | fuelType_Petrol | 3577.372910 | 0.000000 | 0.002467 |
여기서 “year” 변수의 영향도가 가장 큰 것을 알 수 있다.