#!/usr/bin/env python3
One-Hot-Encoding(가변수)
0.살펴보기
factor범주형 변수를 표현하는데 가장 널리 쓰이는 방법인 One-Hot-Encoding원-핫-인코딩은
dummy variable가변수을 만들어 factor형 변수를 0 또는 1 의 값을 가진 하나 이상의 새로운 특성으로 바꿈
따라서 특성당 0, 1의 값이 들어있기 때문에 binary classifier algorithm이진분류알고리즘 적용가능
pandas의 get_dummies 함수는 숫자 특성은 모두 연속형이라 생각해서 가변수를 만들지 않음 1
대신 어떤 열이 연속형인지 범주형인지를 저장할 수 있는 scikit-learn의 OneHotEncoder를 사용할수 있고
DataFrame에 있는 숫자로 된 열을 문자열로 바꿀 수도 있음
# library import
import pandas as pd
# DataFrame 생성
df = pd.DataFrame({'숫자 특성': [0, 1, 2, 1],
'factor형 특성': ['핸드폰', '밀스', '핸드폰', '상자']})
# DataFrame 출력
print('df \n{}'.format(df))
# one-hot-encoding 적용
df_dummy = pd.get_dummies(df)
print('df_dummy \n{}'.format(df_dummy))
### get_dummies를 사용하면 문자열 특성만 인코딩되며 숫자 특성은 바뀌지 않음
### series를 str형태로 변형후 get_dummies 적용
### get_dummies를 적용할 때 columns를 직접 입력
### 방법 1
df1 = df.copy() # DataFrame 복사
df1['숫자 특성'] = df1['숫자 특성'].astype(str) # 타입변형
df1_dummies = pd.get_dummies(df1)
print('df1_dummies \n{}'.format(df1_dummies))
### 방법 2
df2_dummies = pd.get_dummies(df, columns=['숫자 특성', 'factor형 특성']) # get_dummies 적용시 columns 지정
print('df2_dummies \n{}'.format(df2_dummies))
1. adult data loading
# library import
import pandas as pd
# data load
adult = pd.read_csv('adult.csv', index_col=False)
# 원하는 열만 추출
adult = adult[['age', 'workclass', 'education', 'gender', 'hours-per-week', 'occupation', 'income']]
print('adult.head() \n{}'.format(adult.head()))
adult데이터의 처음 5번째 행
2. 범주형 데이터 문자열 확인
pandas ==> value_counts 메소드로 유일한 값이 각각 몇 번 나타나는지 확인
print('columns names \n{}'.format(adult.columns)) # 열 출력
print('age의 갯수 \n{}'.format(adult.age.value_counts())) # dataframe.열.메소드
print('workclass의 갯수 \n{}'.format(adult.workclass.value_counts())) # ? 값 있음을 확인
print('education의 갯수 \n{}'.format(adult.education.value_counts()))
print('gender의 갯수 \n{}'.format(adult.gender.value_counts()))
print('hours-per-week의 갯수 \n{}'.format(adult['hours-per-week'].value_counts())) # 열이름이 특수문자나 띄어쓰기 있으면 ['열이름']으로 접근
print('occupation의 갯수 \n{}'.format(adult.occupation.value_counts())) # ? 값 있음을 확인
print('income의 갯수 \n{}'.format(adult.income.value_counts()))
value_counts로 확인한 특성의 수
3. pandas의 get_dummies로 데이터 reshaping
adult_dummies = pd.get_dummies(adult)
print('원본 특성:\n', list(adult.columns), '\n')
print('get_dummies 후의 특성 :\n', list(adult_dummies.columns))
원본 특성과 get_dummies후의 특성, 'age', 'hours-per-week'를 제외하고 전부 나뉘어진 것을 볼 수 있음
### 숫자형인 age, hours-per-week는 그대로지만 factor형 특성은 값마다 새로운 특성이 만들어짐
### pandas의 values속성을 이용해 numpy 배열로 바꿀수 있음
### target을 income으로 잡을 것이므로 income을 데이터에서 분리해야함
### numpy에서 np.arange(11)[0:10]은 인덱스가 10인 항목을 포함하지 않음
### 그러나 pandas에서 범위 끝은 그 열을 포함함
features = adult_dummies.loc[:, 'age':'occupation_ Transport-moving']
import numpy as np
x = features.values # feature를 numpy배열로 변환
y = adult_dummies['income_ >50K'].values # 타겟데이터를 numpy 배열로 변환
print('x.shape: {}. y.shape: {}'.format(x.shape, y.shape)) # x.shape: (31143, 44), y.shape:(31143,)
4. one-hot-coding한 데이터를 바탕으로 machine learning
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = \
train_test_split(x, y,
test_size=0.3, random_state=0)
logreg = LogisticRegression().fit(x_train, y_train)
print('테스트 점수 \n{:.3f}'.format(logreg.score(x_test, y_test))) # 0.813
### adult 데이터셋에서는 factor형 변수가 문자열로 인코딩 되어있음
### 철자 오류가 날 수 있지만 다른 한 편으로는 변수가 factor형이란 것을 확실하게 알 수가 있음
### 하지만 저장 공간을 절약하거나 데이터 취합 방식에 따라 범주형 변수가 숫자로 인코딩 된 경우가 많음
### 예를들어 adult 데이터셋에 있는 인구조사 데이터가 설문지를 이용해 모은 것이라고 가정하면 workclass에 대합 대답은 0, 1 ,2 등이 됨 ==> 이 열은 0~8까지의 숫자로 채워지
### 게 되고 누군가 이 데이터셋을 보면 이 변수를 연속형으로 다뤄야할지 factor형으로 다뤄야할지 단번에 알아채기가 어려움. 그러나 숫자가 workclass를 나타낸다고 알게 되면
### 이 값은 이산적이므로 연속형 변수로 다루면 안된다는 것이 명확해짐
- 객체 타입(문자열 같은)이나 범주형을 가진 열을 자동으로 변환해줌 [본문으로]
'데이터 표현과 특성 > One-Hot-Encoding(' 카테고리의 다른 글
One-Hot-Encoding으로 wave 데이터셋 분석 (0) | 2018.03.28 |
---|