티스토리 뷰
결정 트리
알코올 농도, 당도, pH지수에 따라 레드 와인과 화이트 와인을 분류해보자. 양성 클래스(1)는 화이트 와인으로 간주한다.
pandas 라이브러리의 info() 메소드로 각 열이 가지는 정보에 대해 먼저 살펴보자.
- Non-Null Count: 전체 데이터 중 각 열에 대해서 Null 값이 아닌 데이터의 개수
- Dtype: 각 열에 저장된 값들의 타입
- memory usage: 사용 중인 메모리 크기
describe()를 사용하면 각 열의 평균값, 표준편차, 최대값 등을 살펴볼 수 있다.
사이킷런의 LogisticRegression 클래스로 로지스틱 회귀를 사용할 수 있다.
결정 트리는 하나의 기준(당도가 2보다 작은가요?)에 따라 데이터셋을 두개로 분류(예: 레드 와인, 아니오: 화이트 와인)하는 트리를 말한다. 사이킷런의 tree 모듈에서 DecisionTreeClassfier 클래스를 사용하면 된다. plot_tree 함수에 만든 트리를 넣어주면 실제로 만든 트리를 볼 수 있다.
plot_tree 함수의 파라미터들을 살펴보자.
- max_depth: 트리의 깊이를 제한할 수 있다.
- filled: True로 설정 시, 양성/음성 클래스 여부에 따라 노드에 색이 칠해진다. 양성에 가까울 수록 농도가 진하다.
- feature_names: 특성의 이름들을 배열로 전달하도록 한다.
트리에서 노드가 갖고 있는 특성들은 다음과 같다.
- samples: 현재의 노드에 몇개의 클래스가 있는지 카운트한다.
- value: 현재 노드에 대해 음성 클래스와 양성 클래스의 개수를 카운트한다. (자식 노드의 samples 값과 동일)
노드의 특성 중에서 gini는 지니 불순도를 뜻한다. 지니 불순도는 1 - (음성 클래스 비율^2 + 양성 클래스 비율^2)를 의미한다.
예를 들어 해당 노드에서 음성과 양성 클래스가 정확하게 반으로 나뉘면 지니 불순도는 0.5가 된다. 만약 모든 데이터가 양성 클래스에 몰리면 지니 불순도는 0이 되고, 이 경우를 순수노드라고 부른다. 결정 트리는 leaf 노드가 순수노드가 될 때까지 노드를 분류한다.
결정트리의 leaf node가 순수해질 때까지 depth를 늘리면 과대적합이 반드시 발생하게 된다. 가지치기(pruning) 기법으로 트리의 깊이를 제한해 과대적합을 막을 수 있다. 대표적인 방법으로 결정트리 클래스의 max_depth 매개변수로 트리의 최대 깊이를 설정하면 정확도는 84%로 낮아지지만 boolean dataset의 양은 줄어든다.
-> 트리에는 규제도, 가중치도 적용할 수도 없기 때문에 과대적합을 막을 수 있는 방법은 가지치기가 유일하다.
결정 트리는 스케일을 조정하지 않고도 특성을 사용할 수 있다는 장점이 있다. 즉 전처리 단계가 필요 없다. 또한 feature_importances 함수로 각 특성의 중요도를 알아낼 수 있다. (위의 코드를 보면 sugar 특성의 중요도가 가장 높다.)
교차 검증과 그리드 서치
이제까지는 훈련 세트, 테스트 세트로만 데이터셋을 나눴지만 이제는 검증에 사용될 데이터까지 총 3개의 데이터셋으로 나눠 훈련에 사용해보고자 한다. (이게 정석.) 검증 데이터셋은 최종 모델을 서비스에 투입했을 때 나타나는 성능을 예측하기 위해서 사용된다. 보통 검증 세트를 통해 모델의 매개변수(하이퍼 파라미터)를 튜닝한다.
검증 세트로 모델의 매개변수를 튜닝하는 과정을 교차 검증이라고 한다.
검증 데이터셋을 보다 효과적으로 사용하기 위해 N개의 폴드(위의 예시에서는 N=3)로 나눠 N-1개의 폴드는 훈련 데이터셋으로, 1개의 폴드는 검증 데이터셋으로 이용하도록 한다. 이 때 첫 번째 모델 훈련 과정에서는 1, 2번째 폴드의 데이터셋을 훈련 셋으로, 3번째 폴드 데이터셋을 검증 셋으로 사용한다. 두번째 모델 훈련은 1, 3번째 폴드로 훈련을, 마지막 모델 훈련은 2, 3번째 폴드로 번갈아가며 훈련을 진행한다. 이 때의 검증 결과는 세 개의 모델 정확도를 평균 내서 도출하도록 한다.
교차 검증을 하기 위해 데이터셋을 직접 분리하지 않아도 된다. cross_validate 함수에 데이터셋을 넣어주기만 하면 알아서 데이터셋에서 검증셋을 분리하고 교차 검증을 진행한다. (이 때 폴드의 개수는 기본적으로 5개이다.)
만약 5개가 아닌 임의의 개수만큼 폴드를 생성해 교차 검증을 진행하고 싶다면 분할기(spliter)를 사용하도록 한다. StratifiedKFold라는 spliter 객체를 사용하면 보다 직접 폴드의 개수를 설정할 수 있다. 객체만 전달해주면 자동으로 적절한 값을 찾아내 K개의 폴드로 나누는데, 이 때 매개변수를 설정하면 직접 K 값을 세팅할 수도 있다.
- n_splits: 나눌 폴드의 개수
- shuffle: 랜덤 여부
교차 검증을 할 때 적절한 매개변수 값을 찾고 싶다면 그리드 서치를 사용한다. model_selection 모듈의 GridSearchCV 클래스를 사용하기 이전에 먼저 매개변수 딕셔너리(params)를 생성해야 한다. 위의 코드에서 예시로 주고 있는 딕셔너리 내부의 min_impurity_decrease는 정보이득의 최소값을 의미한다. 예를 들어 min_impurity_decrease 값이 0.1인 경우에는 부모노드와 자식노드의 불순도 차이가 0.1도 되지 않으면 분류를 멈추도록 한다. 어떤 값이 최적의 min_impurity_decrease 값인지 모르기 때문에 0.0001 ~ 0.0005 까지의 값을 매개변수 딕셔너리에 저장하도록 한다.
GridSearchCV의 두번째 매개변수에 우리가 만든 딕셔너리를 넣어주면 되는데, 이 때 n_jobs 파라미터로 여러 개의 훈련을 동시에 진행할 수 있다. (보통 2, 3 등 코어 개수만큼 지정한다.) 그리드서치로 얻은 모델에서 best_params_를 통해 최적의 파라미터 값을, cv_results로 각 파라미터 값에 대한 정확도를 출력할 수 있다.
params = {'min_impurity_decrease': np.arange(0.0001, 0.001, 0.0001),
'max_depth': range(5, 20, 1),
'min_samples_split': range(2, 100, 10)
}
값을 하나하나 넣어줄 필요없이 메소드로 배열을 생성해 사용할 수도 있다. arange(), range() 메소드 둘다 앞의 두 파라미터 값 범위 안에서 세 번째 파라미터 값의 단위로 배열을 생성한다.
scipy stats 모듈의 uniform과 randint 클래스를 사용하면 더 편하게 균등분포 샘플링을 할 수 있다.
raindint 는 정수 값 샘플링을 도와준다. 0 ~ 10 범위를 설정하고 rvs 메소드로 데이터를 샘플링 하면 0부터 9까지 10개의 값이 랜덤으로 나타난다.
rgen = randint(0, 10)
rgent.rvs(10)
array([9, 2, 1, 8, 6, 4, 5, 6, 2, 6])
unique 메소드를 적용하면 샘플링 데이터에서 중복된 값을 제거해 출력한다.
return_counts=True 설정 시, 각 데이터 값이 몇 번 나타나는지 카운트를 세서 함께 출력한다.
ex) 아래 코드에서 1000개의 데이터 중 0이 95번, 1이 90번 샘플링됨.
np.unique(rgen.rvs(1000), return_counts=True)
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), array([95, 90, 90, 115, 97, 96, 100, 101, 113, 95])
uniform은 0~1까지의 실수 값 샘플링을 도와준다.
ugen = uniform(0, 1)
ugen.rvs(10)
array([0.67694587, 0.77912183, 0.73608526, 0.64430581, 0.8250335, 0.45253031, 0.47240473, 0.81925782, 0.95971199, 0.75004125])
앞에서 배운 것들을 이용해 min_impurity_decrease, max_depth, min_samples_split, min_samples_leaf의 값을 세팅하자.
랜덤 서치는 RandomizedSearchCV 클래스를 사용한다. RandomizedSearchCV에 들어가는 파라미터들은 다음과 같다.
- 결정 트리(DecisionTreeClassifier)
- params
- n_iter: params에서의 샘플링 횟수
이 때 최적의 정확도는 86%이다.
트리와 앙상블
- 정형 데이터: 행과 열로 나눠 데이터베이스나 엑셀 파일(csv 파일)로 저장할 수 있는 데이터 (머신러닝 용)
- 특성공학을 적용하는 전처리 단계가 필요하다.
- 비정형 데이터: 그렇지 않은 데이터 - 텍스트, 오디오, 이미지, 영상 등 (딥러닝 용)
- 보통 특성공학 대신에 표현학습 알고리즘을 적용한다.
랜덤 포레스트는 정형 데이터를 다루는 대표적인 머신러닝 알고리즘으로, 결정 트리를 무작위로 만들어 숲을 만드는 알고리즘을 뜻한다. RandomForestClassifier, RandomForestRegressor 클래스로 사용할 수 있다.
랜덤 포레스트 알고리즘은 부트스트랩 샘플로 훈련을 진행한다. 부트스트랩 샘플이란 훈련 세트에서 중복을 허용해 무작위로 샘플링한 데이터 샘플을 말한다. 각각의 부트스트랩 샘플들로 훈련한 모델들의 예측 정확도를 모두 더해 트리의 개수로 나누면 평균 정확도를 구할 수 있다.
이 때 특성 개수의 루트만큼 특성을 무작위로 골라 최선의 특성 분할 방법을 찾는다. 모든 노드를 만들 때마다 이 과정을 반복해 최선의 특성 분할을 적용하도록 한다.
앙상블 모델 중 한 종류이기 때문에 랜덤 포레스트 클래스는 ensemble 모듈 아래에 존재한다.
랜덤 포레스트 훈련에서 트리를 만들 때 샘플링되지 않은 데이터들이 존재하는데, 이 데이터들을 OOB라고 부른다. 이 사용되지 않은 데이터셋을 검증 데이터셋 용도로 사용할 수 있다. oob_score=True 설정 시, oob_score_ 속성으로 검증 결과를 살펴볼수 있다.
랜덤 포레스트와 비슷한 모델로 엑스트라 트리가 있다. 거의 모든 과정이 비슷하지만 과대적합을 억제하는 방식에 차이가 있다. 부트스트랩 샘플 대신에 전체 샘플을 사용하며, 부모와 자식의 불순도 차이를 계산하는 대신 여러 특성을 기준으로 랜덤하게 트리를 분할하고, 이 중 최적의 불순도를 가지는 트리를 찾아내는 방법을 사용한다. (그래서 속도가 빠름.) ExtraTreesClassifier 클래스로 사용할 수 있다.
그레이디언트 부스팅 알고리즘은 손실 함수와 평균 제곱 오차를 사용한다. 이전 트리의 손실 값들이 낮아지는 방향으로 회귀 결정 트리를 계속 추가하는 알고리즘이다. GradientBoostingClassifier/Regressor 클래스로 사용할 수 있으며 max_depth 또는 learning_rate 파라미터를 추가해 과대적합을 억제할 수 있다.
싸이킷런에서 제공하는 또다른 그레이디언트 부스팅 알고리즘으로 히스토그램 기반 그레이디언트 부스팅이 있다. 훈련 데이터를 256개의 구간으로 나눠 학습시키는 알고리즘으로 사용하기 위해서 experimental 모듈의 enable_hist_gradient_boosting 을 임포트해야한다.
치환 중요도란 행(샘플), 열(특성)이 주어졌을 때, 하나의 열(특성)을 골라 값을 무작위로 섞고 성능을 다시 평가해 각 특성의 중요도를 따지는 것을 말한다. permutation_importance 메소드를 임포트해 사용할 수 있다. n_repeats 파라미터로 섞는 횟수를 설정할 수 있다. (기본값은 5.) 중요도가 높을 수록 해당 특성이 중요함을 의미한다.
히스토그램 그레디언트 부스팅 전용 라이브러리로 따로 LightGBM(Most), XGBoost이 존재한다.
'ML' 카테고리의 다른 글
혼자 공부하는 머신러닝 + 딥러닝 6장 K-평균 리뷰 (0) | 2022.06.10 |
---|---|
혼자 공부하는 머신러닝 + 딥러닝 6장 군집 알고리즘 리뷰 (0) | 2022.06.10 |
혼자 공부하는 머신러닝+딥러닝 4장 리뷰 (0) | 2022.04.27 |
혼자 공부하는 머신러닝+딥러닝 3장 리뷰 (0) | 2022.04.27 |
혼자 공부하는 머신러닝 + 딥러닝 1장 리뷰 (0) | 2022.04.06 |
- Total
- Today
- Yesterday
- atq
- E_FAIL
- awk프로그램
- linux파일
- GithubAPI
- linuxtouch
- whatis
- 버추억박스에러
- cat
- 쇼미더코드
- 사용자ID
- cron시스템
- 리눅스cron
- 리눅스
- linuxgedit
- 코테
- baekjoon
- 백준
- api문서
- Baekjoon27211
- virtualbox
- GitHubAPIforJava
- SELECT #SELECTFROM #WHERE #ORDERBY #GROUPBY #HAVING #EXISTS #NOTEXISTS #UNION #MINUS #INTERSECTION #SQL #SQLPLUS
- linuxawk
- Baekjoon27219
- OnActivityForResult
- 버추억박스오류
- 백준27211
- Linux
- 백준27219
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |