머신러닝/머신러닝에 대해

머신러닝을 학습시키기 전, 데이터셋을 전처리하는 과정에 대해 알아보자. - 의미없는 데이터 NaN으로 바꾸기(np.nan) / NaN을 처리하는 2가지 전략 (dropna함수, fillna함수)

Cong_S 2022. 5. 6. 17:07

인공지능을 학습시키기 위해선 우리가 보유 중인 데이터셋을 전처리하는 과정이 필요하다.

사람이 이해하기 쉬운 데이터셋을 컴퓨터(인공지능)이

이해하기쉬운 데이터로 처리해주는 과정이 필요하다는 뜻이다.

 

필요에 따라 달라질 수는 있겠지만

보통 다음과 같은 단계의 과정을 거쳐 데이터를 처리하게 된다.

 

df = pd.read_csv('50_Startups.csv')
df

 

# 1. 판다스 데이터셋(데이터프레임)을 가져온다.

이때, 데이터를 describe( ) 함수로 각 컬럼들의 최소, 최댓값의 범위가 얼마나 다른지,

NaN은 아니지만 의미없는 데이터는 없는지 혹은,  나와야할 컬럼이 안나오지는 않는지 파악해야한다.

 

# 2. 데이터셋을 보고 어떤 인공지능을 만들지 계획한다.

이 때, 원하는 인공지능을 만들기 위해 어떠한 컬럼의 값이 필요한지

어떤 컬럼이 레이블 데이터가 되어야할지 파악해야한다.

위의 경우는 Profit을 제외한 모든 컬럼이 예측하는데에 도움이 된다고 판단하여 모두 포함하였다.

 

# NaN 처리
df.isna().sum()

 

# 3. NaN 데이터 처리 (주의할 점, NaN이 들어가도 될 의미없는 데이터인데 자리를 차지하는 데이터가 있는지 확인할 것)

인공지능이 학습하는 데에 있어 NaN이 하나라도 존재할 경우 에러가 나기 때문에 빼먹어선 안될 과정이다.

의미없는 데이터임에도 불구하고 NaN으로 두지 않은 데이터의 예

간혹 NaN이 없다하더라도 데이터를 수집할 때 값이 없는 경우임에도 NaN으로 처리하지 않고

0이나 '없음' 등으로 처리해 NaN임에도 불구하고 감지되지 않는 경우가 존재한다.

 

위 데이터셋에서 의미없이 0으로 채워진 행이 이렇게나 많다.

위 이미지와 같은 경우 0을 NaN으로 다시 처리해주고 다시 NaN을 삭제하거나

인공지능 학습에 방해되지않는 다른 값으로 채워주는 과정이 필요하다.

# 0인 부분을 NaN으로 바꿔주는 작업
df.loc[:,'Plas':'mass'] = df.loc[:,'Plas':'mass'].replace(0, np.nan)

위와 같이 replace( ) 함수를 사용해 0을 np.nan 으로 값을 변경해줄수 있다.

df = df.dropna()

#또는

df = df.fillna(df.mean())

그 다음 dropna( ) 함수나 fillna( )함수로

NaN이 존재하는 행을 삭제하거나 , NaN을 학습에 방해되지 않는 값(ex.컬럼의 평균값) 으로 채워주면 된다.

중요한 부분이니 꼭 짚고 넘어가도록 하자.

 

X = df.loc[:, :'age']

y = df['class']

 

# 4. 데이터셋을 가지고 X, y 로 분리한다. 즉, 예측에 사용할 변수와 레이블링 변수로 바꾼다.

 


# 5. 위의 데이터셋에는 없지만, 카테고리컬 데이터 그 중에서 문자열 데이터일 때 꼭 거쳐야하는 과정이다.

문자열 데이터는 인공지능이 학습할 수 없기 때문에 별도의 넘버링 과정을 거쳐주어야 한다.

 

from sklearn.preprocessing import LabelEncoder,OneHotEncoder 
from sklearn.compose import ColumnTransformer

# 1. 레이블 인코딩 하는 방법
encoder = LabelEncoder()
X = encoder.fit_transform(X['Country'])

##############################################

# 2. 원 핫 인코딩 하는 방법
ct = ColumnTransformer( [ ('encoder',OneHotEncoder(), [0] ) ] , remainder='passthrough' )
X = ct.fit_transform(X)  

# [0] 이라고 쓴 이유는 X에서 원핫인코딩할 컬럼이 컴퓨터가 매기는 인덱스가 0 이기 때문에
# 즉, 원핫인코딩할 컬럼의 인덱스를 써주게되면 변환시켜준다.
# 만약 원핫 인코딩할 컬럼이 2개면, 해당 컬럼의 인덱스를 리스트안에 적어주면된다.
# remainder = 'passthrough' 는 내가 지정한 컬럼 외에는 건들지 말라는 뜻이다.

 

작업할 때는 카테고리컬 데이터인지 확인하고

카테고리컬 데이터가 3개 이상이면 원 핫 인코딩. 2개 이하면 레이블 인코딩으로 한다. 

 


# 6. 데이터의 범위를 일정하게 맞춰주는 피쳐 스케일링 과정을 가진다. 

피쳐 스케일링이 필요한 이유는 인공지능은 유클리디언 디스턴스로 오차를 줄여 나가는데, 

하나의 변수는 오차가 크고, 하나의 변수는 오차가 작으면, 나중에 오차를 수정할때 편중되게 된다. 
따라서 값의 레인지를 맞춰줘야 정확하게 트레이닝 되는 것이다.

 

  • 표준화(Standardisation) : 평균을 기준으로 얼마나 떨어져 있느냐? 같은 기준으로 만드는 방법, 음수도 존재, 데이터의 최대최소값 모를때 사용.
  • 정규화(Normalisation) : 0 ~ 1 사이로 맞추는 것. 데이터의 위치 비교가 가능, 데이터의 최대최소값 알떄 사용
from sklearn.preprocessing import StandardScaler, MinMaxScaler

먼저 라이브러리를 불러온다. 

s_scaler = StandardScaler()        # 각 컬럼의 평균과 표준편차 스케일링
s_scaler.fit_transform(X)

먼저 표준화의 방법이다. 특징은 0을 기준으로 얼마나 가깝고 먼지에 따라 수를 표현하게 된다.

m_scaler = MinMaxScaler()         # 각 컬럼의 최솟값과 최댓값 사이의 값을 0~ 1 로 표현
X = m_scaler.fit_transform(X)

다음은 정규화 방법이다. 특징은 각 컬럼의 최솟값과 최댓값을 0고 1로 표현하고 그 안에서 수를 표현한다.

 

두 가지 방법을 용도에 맞게 사용하면 된다.

 

 

# 7. 데이터 셋의 X와 y를 학습에 사용할 데이터와 테스트에 사용할 데이터로 나눠준다. 

학습용 X 와 y 를 나누고 테스트용 X와 y 를 나눠준다. 총 4가지 데이터로 나누면 된다.

 

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split( X, y , test_size = 0.2 , random_state = 3 )    

# random_state / 랜덤 라이브러리의 씨드값과 같은 기능

 

## 위 과정을 끝냈다면,

이제는 처리된 데이터들을 가지고 용도에 맞는 라이브러리를 찾아 인공지능에게 학습을 시킬 수 있다.