안녕하세요
오늘은 scikit-learn(사이킷런) 패키지 중 OneHotEncoder 함수에 대해 정리해 보았습니다.
preprocessing 모듈은 데이터 전처리를 할 때 사용하기 편한 함수를 제공하고 있습니다. 스케일링, 센터링, 정규화, 이진화, 등을 포함합니다. 향후 하나씩 다루도록 하겠습니다.
컴퓨터를 전공하셨다면 인코딩이랑 언어에 익숙하실 텐데요 사람이 인지할 수 있는 문자를 컴퓨터가 이해하는 0 or 1로 구성된 코드로 바꾸는 것을 얘기합니다. 비슷하게 머신러닝 알고리즘을 적용할 때 문자열 데이터를 숫자형으로 바꿔주기 위한 방법 중 하나입니다. 분석할 데이터에서 문자열 데이터가 카테고리를 나타내거나(ex. 성별(남자/여자), 음식 분류(한식/중식/일식/양식)) 텍스트를 나타냅니다. (ex. 댓글, 기사 제목, 자막, 등)
오늘은 카테고리형 문자열을 어떻게 숫자형으로 바꾸는지에 대한 방법을 다룹니다. 레이블 인코딩(Label encoding)과 원 핫 인코딩(One Hot encoding)이 있는데요 차이점은 레이블은 0부터 숫자를 하나씩 붙입니다. 한식 중식 일식 양식의 카테고리가 있다면 순서대로 0, 1, 2, 3을 매치시켜 사용합니다. 하지만 이렇게 해서 사용하게 되면 데이터 분석 시 숫자가 커짐에 따른 경향을 찾아내서 예측에 영향을 줄수도 있습니다. 실제로는 아무 연관이 없는데도 말이죠. 따라서 해당 방법보다는 One Hot encoding을 사용하는데요 이것은 새로운 독립 변수를 만들어 버립니다. 예를 들면 한식 독립 변수를 만들어서 해당하는 것은 1 그 외는 0이 되고 중식, 일식, 양식 각 독립 변수를 만들어서 0또는 1로 표시를 하는 방법입니다. 그래서 하나만 핫하게 표현했다? 그래서 One Hot인지... (아재 같았네요..)
그럼 사이킷런 preprocessing 모듈에서 OneHotEncoder를 어떻게 사용하는지 실습해 보겠습니다.
우선 예시 train 데이터를 하나 만들어 보겠습니다. 이전 train_test_split 공부 때 사용한 실습 데이터에 소속팀이라는 카테고리를 추가해 보겠습니다.
이름 | 야근 시간 (낮음:0~1: 높음) |
업무 스트레스 지수(낮음:0~1: 높음) | 급여 만족도 (불만:0~1:만족) |
소속팀 | 퇴사 여부 (0:No, 1:Yes) |
김대리 | 0.5 | 0.3 | 0. | 인사팀 | 0 |
최과장 | 0.4 | 0.1 | 0.6 | 개발팀 | 0 |
김사원 | 0 | 0.9 | 0 | 총무팀 | 1 |
이차장 | 0.7 | 0.5 | 0.2 | 개발팀 | 0 |
유대리 | 0.3 | 0.2 | 0.5 | 총무팀 | 0 |
박과장 | 0.2 | 0.4 | 0.1 | 인사팀 | 1 |
sample.csv 파일로 만들고 pd.read_csv 하겠습니다.
import pandas as pd
df = pd.read_csv('sample.csv')
df
소속팀 열의 값을 List로 만들어 보겠습니다.
team_list = list(df['소속팀'].values)
OneHotEncoder의 입력은 array를 나타내는 정수 또는 문자열이어야 합니다.
(The input to this transformer should be an array-like of integers or strings, denoting the values taken on by categorical (discrete) features.) 무슨 말인지 잘 모르겠지만 무튼 배열 입력을 주도록 했습니다.
import numpy as np
team_list_arr = np.array(team_list)
그러고 나서 team_list_arr 를 입력으로 주면 에러가 납니다. 찾아보니 입력 값으로 2차원 데이터를 줘야합니다.
team_list_arr = team_list_arr.reshape(-1,1)
reshape 함수를 이용해서 2차원 데이터로 변경했습니다.
이제 OneHotEncoder를 써보겠습니다.
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
enc.fit(team_list_arr)
labels = enc.transform(team_list_arr)
print(labels.toarray())
각 열이 어떤 것을 의미하는지 보기위해 이름 앞에 team을 붙여보았습니다.
new_colume = list(enc.get_feature_names(['team'])
team_list_arr가 어떻게 바뀌었는지 비교 가능하실 겁니다. 기존 df에 변경된 것을 추가해 보았습니다.
df[new_colume] = labels.toarray()
이제 소속팀 열은 지워도 되니 drop 함수를 쓰겠습니다. inplace = True를 하면 return 값은 없지만 원본 df에서 완전 삭제됩니다. False 이면 drop 한 결과를 return 해주고 원본 df는 변화가 없습니다.
df.drop(columns = ['소속팀'], inplace = True)
지금까지 OneHotEncoder를 활용해서 카테고리 변수를 0또는 1로 바꾸는 것을 살펴보았습니다.
하지만!! 더 편리하게 사용하는 방법이 있는데요 pandas에서 제공하는 get_dummies라는 함수입니다.
처음부터 sample.csv 를 읽어와서 df를 가져오겠습니다.
import pandas as pd
df = pd.read_csv('sample.csv')
이름 열이 카테고리로 인식 될 수 있어서 별도로 저장하고 drop 하고 get_dummies를 사용해 보겠습니다. 한방에 끝납니다.
name_data = df['이름'].values
df.drop(columns = ['이름'], inplace = True)
df = pd.get_dummies(df)
마지막으로 다시 이름 열을 추가하겠습니다. 첫 열에 추가하기 위해 insert 함수를 사용했어요
df.insert(0, '이름', name_data)
OneHotEncoder를 배웠는데 결국엔 get_dummies 함수를 쓰게 되는 결론이 되어 좀 허무하기도 하지만.. 그래도 둘 다 쓸 수 있으면 상황에 맞게 더 편한 것을 선택할 수 있지 않을까요?...
무튼 오늘은 여기까지 하겠습니다.
'Work & Study' 카테고리의 다른 글
[데이터 분석 스터디] 데이터 전처리 (pandas.DataFrame) _null 값 (0) | 2023.04.11 |
---|---|
[영어 공부] 2일차 - what is your hobby? (0) | 2023.03.26 |
[영어 공부] 1일차 - What is your favorite food? (0) | 2023.03.20 |
[데이터 분석 스터디] sklearn.model_selection.train_test_split (0) | 2023.03.07 |