시작에 앞서
해당 내용은 '<파이썬 머신러닝 완벽 가이드> 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.
데이터 전처리(Data Preprocessing)
ML 알고리즘은 데이터에 기반하고 있어 어떤 데이터를 입력으로 가지느냐에 따라 결과도 크게 달라질 수 있기 때문에 데이터 전처리가 매우 중요하다.
[데이터 전처리 기본 사항]
- 결손값(Null, NaN)은 허용되지 않는다. : 결손값은 고정된 다른 값으로 변환되어야 한다.
- 사이킷런의 머신러닝 알고리즘은 문자열 값을 입력값으로 허용하지 않는다.: 모든 문자열은 인코딩돼서 숫자 형으로 변환해야 한다.
데이터 인코딩
- 레이블 인코딩: 카테고리 피처를 코드형 숫자 값으로 변환하는 것
- 원-핫 인코딩: 피처 값의 유형에 따라 새로운 피처를 추가해 고유 값에 해당하는 칼럼에만 1을 표시하고 나머지 칼럼에는 0을 표시하는 방식
◆ 레이블 인코딩(Label encoding): LabelEncoder 클래스로 구현
LabelEndoer를 객체로 생성한 후 fit( )과 tranform( )을 호출해 레이블 인코딩 수행
※ 데이터가 많은 경우에는 문자열 값이 어떤 숫자 값으로 인코딩 됐는지 알기 어렵다. 이 경우 LabelEncoder 객체의 classes_ 속성값으로 확인할 수 있다.
※ inverse_transform을 통해 인코딩된 값을 다시 디코딩할 수 있다.
레이블 인코딩은 간단하게 문자열 값을 숫자형 카테고리 값으로 변환한다. 그러나 레이블 인코딩이 일괄적인 숫자 값으로 변환이 되면서 몇몇 ML 알고리즘에는 이를 적용할 경우 예측 성능이 떨어지는 경우가 발생할 수 있다.
이는 숫자 값의 경우 크고 작음에 대한 특성이 작용하기 때문이다. 이러한 특성 때문에 레이블 인코딩은 선형회귀와 같은 ML 알고리즘에는 작용하지 않아야 한다. (예를들어, 전자레인지가 4, 냉장고가 1일 경우 4가 1보다 더 큰 값이므로 특정 ML 알고리즘에서 가중치가 더 부여되거나 더 중요하게 인식할 가능성이 있다. → 코드 번호는 숫자형이 아닌 범주형 데이터가 되어야 한다.)
트리 계열의 ML 알고리즘은 숫자의 이러한 특성을 반영하지 않으므로 레이블 인코딩도 별 문제가 없다.
◆ 원-핫 인코딩(One-Hot Encoding): OneHotEncoder 클래스로 변환
원-핫 인코딩은 사이킷런에서 OneHotEncoder 클래스로 변환이 가능하다. 단, 주의할 점이 있다.
- 입력값으로 2차원 데이터가 필요하다
- OneHotEncoder 를 이용해 변환한 값이 희소 행렬(Sparse Matrix) 형태이므로 이를 다시 toarray( ) 메서드를 이용해 밀집 행렬(Dense Matrix) 로 변환해야 한다.
▶ 8개의 레코드와 1개의 칼럼을 가진 원본 데이터가 8개의 레코드와 6개의 칼럼을 가진 데이터 변환되었다.
※ 판다스에는 원-핫 인코딩을 더 쉽게 지원하는 get_dummies( ) API가 있다.
피처 스케일링과 정규화
- 피처 스케일링(feature scailing): 서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업. 대표적인 방법에는 표준화(Standardization)과 정규화(Normalization)가 있다.
- 표준화: 데이터의 피처 각각이 평균이 0이고 분산이 1인 가우시안 정규 분포를 가진 값으로 변환하는 것
- 정규화: 서로 다른 피처의 크기를 통일하기 위해 크기를 변환해주는 것
◆ StandardScaler: 표준화를 쉽게 지원하기 위한 클래스
StandardScaler 클래스는 개별 피처를 평균이 0이고, 분산이 1인 값으로 변환해준다.
가우시안 정규 분포를 가질 수 있도록 데이터를 변환하는 것은 몇몇 알고리즘에서 매우 중요하며, 특히 사이킷런에서 구현한 RBF 커널을 이용하는 SVM(서포트 벡터 머신)이나 선형 회귀, 로지스틱 회귀는 데이터가 가우시안 분포를 가지고 있다고 가정하고 구현됐기 때문에 사전에 표준화를 적용하는 것은 예측 성능 향상에 중요한 요소가 될 수 있다.
※ 가우시안 분포: 정규분포의 가장 대표적인 꼴로, 대칭을 이루는 종모양의 분포를 말한다.
▶ 모든 칼럼 값의 평균이 0에 아주 가까운 값으로, 그리고 분산은 1에 아주 가까운 값으로 변환됐음을 알 수 있다.
◆ MinMaxScaler: 데이터값을 0과 1사이의 범위 값으로 변환(음수 값이 있을 경우, -1에서 1값)
데이터의 분포가 가우시안 분포가 아닐 경우 Min, Max Scale을 적용해 볼 수 있다.
학습 데이터와 테스트 데이터의 스케일링 변환 시 유의점
Scaler 객체를 이용해 데이터의 스케일링 변환 시 fit( ), transform( ), fit_transform( ) 메서드를 이용한다.
- fit( ): 데이터 변환을 위한 기준 정보 설정을 적용
- transform( ): 설정된 정보를 이용해 데이터 변환
- fit_transform( ): fit( )과 transform( )을 한 번에 적용하는 기능 수행
▶ Scaler 객체를 이용해 학습 데이터 세트로 fit( )과 transform( )을 적용하면 테스트 데이터 세트로는 다시 fit( )을 수행하지 않고 학습 데이터 세트로 fit( )을 수행한 결과를 이용해 transform( )으로 변환을 적용해야 한다.
그렇지 않고 테스트 데이터로 다시 새로운 스케일링 기준 정보를 만들게 되면 학습 데이터와 테스트 데이터의 스케일링 기준 정보가 서로 달라지기 때문에 올바른 예측 결과를 도출하지 못할 수 있다.
[테스트 데이터에 fit( ) 적용 시 발생하는 문제]
1. np.arange( )를 이용해 학습 데이터는 0~10까지, 테스트 데이터를 0~5까지 값을 가지는 ndarray로 생성
2. 테스트 데이터 세트를 변환하는데, fit( )을 호출해 스케일링 기준 정보를 다시 적용한 뒤 transform( ) 수행
▶ 출력 결과 학습 데이터와 테스트 데이터의 스케일링이 맞지 않음을 알 수 있다.
(테스트 데이터: 최솟값 0, 최댓값 5이므로 1/5로 스케일링 → 1은 0.2로, 5는 1로)
(학습 데이터: 1은 0.1로, 10은 1로)
머신러닝 모델은 학습 데이터를 기반으로 학습되기 때문에 반드시 테스트 데이터는 학습 데이터의 스케일링 기준에 따라야 하며, 테스트 데이터의 1값은 학습 데이터와 동일하게 0.1로 변환돼야 한다.
따라서 테스트 데이터에 다시 fit( )을 적용해서는 안 되며 학습 데이터로 이미 fit( )이 적용된 scaler 객체를 이용해 transform( )으로 변환해야 한다.
[테스트 데이터에 fit( ) 호출하지 않고 학습 데이터로 fit( )을 수행한 transform을 이용해 데이터 변환]
※ fit_transform( )을 적용할 때는 테스트 데이터에서는 절대 사용하면 안 된다.
★ 학습과 테스트 데이터 세트로 분리하기 전에 먼저 전체 데이터 세트에 스케일링을 적용한 뒤 학습과 테스트 데이터 세트로 분리하는 것이 바람직하다.
- 가능하다면 전체 데이터의 스케일링 변환을 적용한 뒤 학습과 테스트 데이터 세트로 분리
- 1이 여의치 않다면 테스트 데이터 변환 시에는 fit( )이나 transform( )을 적용하지 않고 학습 데이터로 이미 fit( ) 된 Scaler 객체를 이용해 transform( )으로 변환
- 이는 사이킷런 기반의 PCA(주성분 분석)와 같은 차원 축소 변환이나 텍스트의 피처 벡터와 변환 작업 시에도 동일하게 적용
전체 코드
'[파이썬 Projects] > <파이썬 머신러닝>' 카테고리의 다른 글
[머신러닝] 성능 평가 지표 - 1 (정확도, 정밀도, 재현율, 오차 행렬) (1) | 2024.06.09 |
---|---|
[머신러닝] 타이타닉 생존자 예측 (1) | 2024.06.09 |
[머신러닝] 사이킷런의 model_selection 모듈 (0) | 2024.06.07 |
[머신러닝] 사이킷런에 내장된 예제 데이터 세트 (0) | 2024.05.30 |
[머신러닝] 사이킷런 주요 모듈 (0) | 2024.05.30 |