데이터 품질과 데이터에 담긴 유용한 정보의 양은 머신 러닝 알고리즘을 얼마나 잘 학습할 수 있는지 결정하는 중요한 요소이다.
-> 학습 알고리즘에 데이터를 주입하기 전에 조사하고 전처리하는 것이 매우 중요하다.
실제로 데이터 엔지니어들이 시간을 가장 오래 쏟는 부분이 '데이터 전처리'라고 합니다.
//
누락된 데이터 다루기
일반적으로 누락된 값은 데이터 테이블에 숫자가 아니라는 의미의 NaN이나 NULL과 같은 값을 사용합니다.
이러한 누락된 값을 무시해버린다면 예상치 못한 결과가 나오기도 합니다.
이런 누락된 데이터를 처리하기 가장 편한 방법은 누락된 데이터를 제거하는 것이다.
df.dropna(axis=0) -> 행 제거
df.dropna(axis=1) -> 열 제거
df.dropna(thresh=4) -> NaN이 아닌 값이 네 개보다 작은 행을 삭제한다. 예를들어 2번행에 값이 5 6 NaN 8 이라면 NaN이 아닌 값이 3개여서 해당 행이 제거된다.
df.dropna(subset=['C']) -> 'C'열에 NaN이 있는 행들을 삭제한다.
이러한 방법은 예상가듯이 안정된 분석이 불가능할 수 있고, 분류기가 클래스를 구분하는 데 필요한 중요한 정보를 잃을 위험이 있다.
내가 가장 많이 사용하는 방법은 누락된 값을 대체하는 것이다. 보통 평균값이나 중위값으로 대체하는 것 같다.
교재에서는 평균으로 대체하는 방법을 제시했다.
SimpleImputer , IterativeImputer , KNNImputer 클래스가 적혀있긴 한데, 만약 직접 코드에 적용시키려면 구글링이 필요할 것 같다.
(IterativeImputer 클래스는 아직 실험적이라고 함.)
-> 결국 나는 사용안할 것 같다.
나는 fillna 함수를 적용시키는 걸 선호한다.
//
머신러닝을 하며 꼭 사용하는 메서드는 fit과 predict 인 것 같다.
fit 메서드를 사용해서 모델의 파라미터를 학습한다. -> predict 메서드를 사용하여 레이블이 없는 새로운 데이터 샘플에 대한 예측을 만든다. -> 이후에 제시된 지표( 예를들어 accuracy )를 통해, 예측값과 실제타겟값을 비교해본다.
이 부분이 데이터분석을 할 때 마지막 즈음 단계다. 나보다 더 뛰어난 엔지니어들은 이걸 토대로, 어플리케이션을 만들거나 현업에 적용시킬 것이고, 내가 현업에 들어가면 하게 될 일이 될거다.
//
데이터 분석할 때 다루기 쉬운 데이터는 수치형 데이터다. 그 이유는 내가 모델을 사용할 때, 수치형 데이터로만 사용해봐서 범주형 데이터들을 모두 수치형 데이터로 바꾸는 과정이 필요하기 때문이다. 이 글을 쓰면서 생각해보니, 범주형 데이터를 그대로 머신러닝에 쓸 수 있었나? 라는 궁금증이 생겼다. -> 우선 사이킷런은 문자열 값을 입력 값으로 처리하지 않기 때문에 변환해야한다. 우선 무조건 범주형은 수치형으로 ! 라고 알고 있어야겠다.
//
그렇다면 어떻게 범주형의 문자열 값을 수치형으로 ? -> mapping 함수를 직접 만들자 !
데이터분석을 시작하면 꼭 한번씩 해보는 타이타닉에서도 이 방법을 사용했던 기억이 새록새록 난다.
size_mapping = { 'XL' : 3, 'L' : 2, 'M' : 1}
df['size'] = df['size'].map(size_mapping)
이런식으로 XL,L,M 의 문자열 데이터들을 각각 3,2,1에 해당하는 수치형 데이터로 변환해주었다.
클래스 레이블 인코딩 ( enumerate 함수를 이용 ) 하는 코드도 적어봤다.
import numpy as np
class_mapping = { label:idx for idx,label in enumerate(np.unique(df['classlabel']))}
class_mapping >>> {'class1' : 0 , 'class2' : 1}
df['classlabel'] = df['classlabel'].map(class_mapping)
더 있어보이려면 사이키럿에 구현되있는 LabelEncoder 클래스를 사용하면 된다.
from sklearn.preprocessing import LabelEncoder
class_le = LabelEncoder()
y = class_le.fit_transform(df['classlabel'].values)
y >>> array([1,0,1])
여기서 fit_transform 메서드는 fit 메서드와 transform 메서드를 합쳐 놓은 단축 메서드이다. -> 라이브러리 너무 좋아 ~!
//
범주형 데이터를 다룰 때 발생할 수 있는 문제
위에서 범주형 데이터들을 숫자 0,1,2,,, 이렇게 변환시켰다. 그런데 0이랑 1중에 뭐가 더 좋아보일까? 라고 생각해보면 숫자가 큰 1이 더 좋아보인다. 컴퓨터도 동일한 알고리즘으로 생각할 수 있고, 실제로 결과가 이상하게 나오는 경우도 발생한다.
해결책
원-핫 인코딩 기법을 사용한다. -> 더미 특성을 만든다. -> 예를 들어 blue 샘플은 blue=1 , green=0, red=0
from sklearn.preprocessing import OneHotEncoder
X = df[['color','size','price']].values
color_ohe = OneHotEncoder()
color_ohe.fit_transform(X[:,0].reshape(-1,1)).toarray()
이렇게하면 size나 price는 그대로 두고, color만 더미데이터가 생성된다.
당연히 ! 똑똑이분들이 메서드를 만들어놨따.
pd.get_dummies(df[['price','color','size']]) -> 문자열 열만 반환하고 나머지 열은 그대로 둔다.
원-핫 인코딩 기법을 사용해도 문제점은 발생한다. -> 다중 공선성(multicollinearity)
: 특성 간의 상관관계가 높으면 역행렬을 계산하기 어려워 수치적으로 불안정하다
-> 쉽게 설명하면, color_green / color_red / color_blue 벌써 color에 대해 3개의 column이 생겨났다.
이 중 color_blue 열 자체를 없애버리면 변수 간의 상관관계를 감소시킬 수 있다. 왜 ?
-> 만약에 color_green = 0 / color_red =0 인 행이 있다면 그 행의 color_blue 값은 무엇일까 ? 당연히 1일 것이다.
-> color_blue 열을 없애더라도 잃는 정보는 없다
-> color_blue 열을 없앰으로써 원-핫 인코딩을 사용함으로써 발생할 수 있는 다중 공선성의 위험을 제거한다.
-> pd.get_dummies(df[['price','color','size']], drop_first=True)
'Category > 빅데이터&파이썬' 카테고리의 다른 글
데이콘 - 뉴스 토픽 분류 AI 경진대회 (7) | 2022.03.21 |
---|---|
데이터셋 나누기 / 특성 스케일 조정 / 그리드서치 / SVM (47) | 2022.03.06 |
3장 사이킷런 첫걸음 : 퍼셉트론 훈련, 로지스틱 회귀, 결정 트리 (24) | 2022.03.04 |
MLOps란 ? (0) | 2022.02.27 |
인공지능학회 CUAI 합격 ( + 타이타닉코드 ) (1) | 2022.02.24 |