이항 변수화
In [0]:
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder
In [0]:
#범주형 변수 생성
# [ 성별( 0, 1 ), 연령대( 0, 1, 2 ), 성적( 0, 1, 2, 3, 4 ) ]
data = np.array( [ [ 0, 1, 1 ], # 여성 30대 비학점
[ 0, 2, 2 ], # 여성 40대 씨학점
[ 1, 0, 3 ], # 남성 20대 디학점
[ 1, 1, 4 ], # 남성 20대 에프학점
[ 0, 0, 0 ] # 여성 20대 에이학점
])
OneHotEncoder 사용
In [0]:
ohe = OneHotEncoder()
ohe.fit( data ) # data 변수에 저장된 데이터에 맞추어 이항변수화 fitting
/usr/local/lib/python3.6/dist-packages/sklearn/preprocessing/_encoders.py:415: FutureWarning: The handling of integer data will change in version 0.22. Currently, the categories are determined based on the range [0, max(values)], while in the future they will be determined based on the unique values. If you want the future behaviour and silence this warning, you can specify "categories='auto'". In case you used a LabelEncoder before this OneHotEncoder to convert the categories to integers, then you can now use the OneHotEncoder directly. warnings.warn(msg, FutureWarning)
Out[0]:
OneHotEncoder(categorical_features=None, categories=None, drop=None, dtype=<class 'numpy.float64'>, handle_unknown='error', n_values=None, sparse=True)
In [0]:
#원핫 인코딩을 했을때 사용된 피쳐의 갯수를 리턴한다 성별 0 , 1 두개 성적 나이대 3개 성적 5개 즉 10개의 피쳐가 바이너리 스트링으로 표현된다.
# [ 남, 여, 20대, 30대, 40대, 에이학점, 비학점, 씨학점, 디학점, 에프학점 ]
ohe.active_features_
/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:100: DeprecationWarning: The ``active_features_`` attribute was deprecated in version 0.20 and will be removed 0.22. warnings.warn(msg, category=DeprecationWarning)
Out[0]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [0]:
## 종류의 갯수, 즉 성별은 두가지 종류 , 연령대 세가지 , 학점 다섯가지가 나온다, 각 피쳐별 범주의 갯수를 출력해준다.
ohe.n_values_
/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:100: DeprecationWarning: The ``n_values_`` attribute was deprecated in version 0.20 and will be removed 0.22. warnings.warn(msg, category=DeprecationWarning)
Out[0]:
array([2, 3, 5])
In [0]:
# 0이상 2 미만 => 성별을 표시하는 값의 범위
# 2, 5 => 2이상 5 미만,
# 5, 10 => 5이상 10 미만
# 한 피쳐가 차지하는 인덱스 범위를 알려주는 속성이다.
ohe.feature_indices_
/usr/local/lib/python3.6/dist-packages/sklearn/utils/deprecation.py:100: DeprecationWarning: The ``feature_indices_`` attribute was deprecated in version 0.20 and will be removed 0.22. warnings.warn(msg, category=DeprecationWarning)
Out[0]:
array([ 0, 2, 5, 10])
In [0]:
# 예시 ) 여성, 20대, 30대, 디학점, => [ 0, 1, 3 ]
# 이항변수화 => 10, 010, 00010
test = np.array( [[0, 1, 3]] )
ohe.transform(test) # 기본 반환형 sparse matrix
Out[0]:
array([[1., 0., 0., 1., 0., 0., 0., 0., 1., 0.]])
In [0]:
ohe.transform(test).toarray()
# 아래와 같은 변수를 사용해서 위의 인코딩된 데이터를 구분해서 이해할 수 있다.
ohe.feature_indices_
ohe.active_features_
Out[0]:
array([[0, 1, 3]])
예를 들어 타이타닉 데이터에서 호칭, 티켓 등급 등을 원핫 인코딩 할 수 있다.
In [0]:
# 연속형 변수 -> 이산화
# np.digitize(), np.where() : 연속형 변수 -> 이산화( 2개 이상 )
from pandas import DataFrame
np.random.seed(75)
df = DataFrame( {
'd1' : np.random.randn(10),
'd2' : [ 'x', 'x', 'x', 'x', 'x', 'y', 'y', 'y', 'y', 'y' ]
})
df
Out[0]:
d1 | d2 | |
---|---|---|
0 | -0.709502 | x |
1 | 0.112694 | x |
2 | 0.477022 | x |
3 | 1.935981 | x |
4 | 0.450415 | x |
5 | -1.188847 | y |
6 | 0.613631 | y |
7 | -0.178142 | y |
8 | 1.346521 | y |
9 | 1.161150 | y |
d1 컬럼에 있는값을 기준으로 5개의 구간으로 나누고 몇번째 범주에 속하는 값인지 추가 피처를 생성
In [0]:
# 몇번째 구간에 속하는지 표시할 컬럼. d1컬럼에 있는 최소값 ~ 최대값을 5개의 균등한 구간으로 나누겠다.
# 넘파이 min, max 함수 사용
## 대괄호 하나 = > 시리즈로 리턴.
#df['d1']
## 대괄호 둘 = > df로 리턴.
df[['d1']].min()
# 또는
df.d1.min()
df.d1.max()
bins = np.linspace(df.d1.min(), df.d1.max(), 5 )
In [0]:
# 특정 구간에대한 정보를 담고 있는 bins에 맞게 속한 구간을 리턴해준다. 1~5 구간 (최소 ~ 최대) 5는 최대값을 의미한다.
np.digitize(df['d1'], bins)
Out[0]:
array([1, 2, 3, 5, 3, 1, 3, 2, 4, 4])
In [0]:
df['d1_bin'] = np.digitize(df['d1'], bins)
In [0]:
#구간화의 장점, 그룹화해서 1번그룹인 애들만 모아서 평균을 구하는등의 연산이 가능해진다,
df
Out[0]:
d1 | d2 | d1_bin | |
---|---|---|---|
0 | -0.709502 | x | 1 |
1 | 0.112694 | x | 2 |
2 | 0.477022 | x | 3 |
3 | 1.935981 | x | 5 |
4 | 0.450415 | x | 3 |
5 | -1.188847 | y | 1 |
6 | 0.613631 | y | 3 |
7 | -0.178142 | y | 2 |
8 | 1.346521 | y | 4 |
9 | 1.161150 | y | 4 |
In [0]:
df.groupby( by = "d1_bin")
Out[0]:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fa2eaf73828>
In [0]:
# 각 구간별로 2개 2개 3개 2개 1개 가 있음을 알 수 있다.
df.groupby( by = "d1_bin")['d1'].size()
Out[0]:
d1_bin 1 2 2 2 3 3 4 2 5 1 Name: d1, dtype: int64
In [0]:
# 각 그룹별 d1컬럼의 평균.
df.groupby( by = "d1_bin")['d1'].mean()
Out[0]:
d1_bin 1 -0.949175 2 -0.032724 3 0.513689 4 1.253836 5 1.935981 Name: d1, dtype: float64
In [0]:
# d1_bin 을 기준으로 그룹화 한후 d2 컬럼을 참조.
# 그룹화 이후로 d2 컬럼의 x 또는 y가 몇건씩 있는지 확인,
df.groupby( by = "d1_bin")['d2'].value_counts()
Out[0]:
d1_bin d2 1 x 1 y 1 2 x 1 y 1 3 x 2 y 1 4 y 2 5 x 1 Name: d2, dtype: int64
In [0]:
# 3번째 구간에 속하는 데이터만 추출하고 싶을때, 불린 참조 사용
## 3번 구간에 속하는 데이터만 따로 df2에 담았다.
df2 = df[ df['d1_bin'] == 3 ]
Out[0]:
d1 | d2 | d1_bin | |
---|---|---|---|
2 | 0.477022 | x | 3 |
4 | 0.450415 | x | 3 |
6 | 0.613631 | y | 3 |
In [0]:
# where를 사용하는 조건 참조, digitaize가 아니라 조건으로만 으로도 구간화 할 수 있다.
# 조건, 참, 거짓
# where( 조건, 참, 거짓 )
# D1 컬럼에 대해서 평균을 구하고자 할때는 그냥 mean(), 평균을 기준으로 평균보다 크다, 작다의 정보를 가지고있는 새로운 컬럼을 만들고 싶을때,
df['hl'] = np.where( df['d1'] >= df['d1'].mean() , 'high', 'low')
In [0]:
df
Out[0]:
d1 | d2 | d1_bin | hl | |
---|---|---|---|---|
0 | -0.709502 | x | 1 | low |
1 | 0.112694 | x | 2 | low |
2 | 0.477022 | x | 3 | high |
3 | 1.935981 | x | 5 | high |
4 | 0.450415 | x | 3 | high |
5 | -1.188847 | y | 1 | low |
6 | 0.613631 | y | 3 | high |
7 | -0.178142 | y | 2 | low |
8 | 1.346521 | y | 4 | high |
9 | 1.161150 | y | 4 | high |
In [0]:
# high low 갯수
df.groupby('hl')['d1'].size()
Out[0]:
hl high 6 low 4 Name: d1, dtype: int64
In [0]:
df.groupby('hl')['d1'].mean()
Out[0]:
hl high 0.997453 low -0.490949 Name: d1, dtype: float64
In [0]:
df.groupby('hl')['d1'].std()
Out[0]:
hl high 0.591084 low 0.576501 Name: d1, dtype: float64
In [0]:
## high low만이 아니라 미들 추가.
# 25% 지점에 해당하는 수를 리턴.(오름차순)
Q1 = np.percentile(df['d1'], 25) ## 실제 데이터 셋에는 존재하지 않는 값이다. 데이터 구간을 100분위로 나눠서 25%지점.
Q3 = np.percentile(df['d1'], 75)
# np.where를 사용해서 Q3보다 크거나 같다면 high, Q1보다 크거나 같다면 Medium , 나머지는 low
df['hml'] = np.where( df['d1'] >= Q3 , 'high',
np.where(df['d1'] >= Q1 , 'Medium', 'low'))
In [0]:
df
Out[0]:
d1 | d2 | d1_bin | hl | hml | |
---|---|---|---|---|---|
0 | -0.709502 | x | 1 | low | low |
1 | 0.112694 | x | 2 | low | Medium |
2 | 0.477022 | x | 3 | high | Medium |
3 | 1.935981 | x | 5 | high | high |
4 | 0.450415 | x | 3 | high | Medium |
5 | -1.188847 | y | 1 | low | low |
6 | 0.613631 | y | 3 | high | Medium |
7 | -0.178142 | y | 2 | low | low |
8 | 1.346521 | y | 4 | high | high |
9 | 1.161150 | y | 4 | high | high |
다항 차수를 이용한 비선형적인 관계에대한 패턴을 표현하고 할때 다항변수화 해야 할 경우가 있다. polynimial features
In [0]:
data = np.arange(6).reshape(3,2)
data
Out[0]:
array([[0, 1], [2, 3], [4, 5]])
In [0]:
# 데이터를 2차항 변수 만들기,
# x1과 x2라는 변수가 있을떄, 1, x1, x2, x1^2, x1*x2 , x2^2를 만들어 내는 함수.
# [ 0, 1 ] = > 1, 0, 1, 0, 0, 1 와 같이 두개의 변수를 다항변수 화 한다.
# [ 2, 3 ] = > 1, 2, 3, 4, 6, 8
# [ 4, 5 ] = > 1, 4, 5, 16, 20, 25
data
Out[0]:
array([[0, 1], [2, 3], [4, 5]])
In [0]:
# 다항변수화 하기위한 poly객체가 있다 2차항 이상의 식으로 줄 수도 있다.
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures()
poly.fit_transform(data)
Out[0]:
array([[ 1., 0., 1., 0., 0., 1.], [ 1., 2., 3., 4., 6., 9.], [ 1., 4., 5., 16., 20., 25.]])
'딥러닝 모델 설계 > Machine Learning' 카테고리의 다른 글
Day 4. Grouping, sorting, visualizing (0) | 2019.07.06 |
---|---|
Day 4. Data Reconstruction (0) | 2019.07.06 |
Day 03. Scaler (0) | 2019.07.03 |
Day 03. Replacement (0) | 2019.07.03 |
Day 02. Pandas Review - 2 (0) | 2019.07.02 |