본문 바로가기

AI

[Kaggle] Melbourne 집값 예측하기 - 3 Categorical Variables

비어있는 데이터를 처리하는 법 다음으로는 숫자가 아닌 값들을 가지고 있는 데이터를 처리해보았다

Categorical Variable은 매우 높음, 높음, 보통, 낮음, 매우 낮음처럼 단계별로 나누어져있을 수도 있고

선호하는 카페의 종류라는 질문의 대답처럼 다양한 대답이 나올 수도 있다

이때 이런 Categorical Variable은 파이썬 머신 러닝 모델에 들어가기 전에 전처리가 필요하다

 

세가지의 방법으로 Categorical Variable을 처리해보았다

 

학습을 시키고 error를 구하기 전에 먼저 비어있는 데이터를 처리할 때 처럼 trainging data, test data를 나누어주었다

그리고 지금은 연습하는 단계니까 간단하게 연습해보기 위해서 비어있는 값이 있는 행은 버려주고 종류가 너무 많이 나뉘어지는 Categorical Variable을 가진 행도 버려주었다

이렇게 사용할 데이터들만 남은 데이터셋에서 numeric한 값을 갖는 행과 그렇지 않은 행을 구분해주었다

두 종류의 행들을 합하여 my_cols라는 사용할 행을 지정해주었다

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Drop columns with missing values (simplest approach)
cols_with_missing = [col for col in X_train.columns if X_train[col].isnull().any()] 
print(cols_with_missing)
X_train.drop(cols_with_missing, axis=1, inplace=True)
X_valid.drop(cols_with_missing, axis=1, inplace=True)
 
# "Cardinality" means the number of unique values in a column
# Select categorical columns with relatively low cardinality (convenient but arbitrary)
low_cardinality_cols = [cname for cname in X_train.columns if X_train[cname].nunique() < 10 and 
                        X_train[cname].dtype == "object"]
 
# Select numerical columns
numerical_cols = [cname for cname in X_train.columns if X_train[cname].dtype in ['int64''float64']]
 
my_cols = low_cardinality_cols + numerical_cols
cs

 

전체 데이터에서 사용할 행만 골라 X_train과 X_valid에 재지정 해준 후 encoding을 시작했다

인코딩 할 feature들은 다음과 같이 구해주었다

 

1
2
3
4
5
6
# Get list of categorical variables
= (X_train.dtypes == 'object')
object_cols = list(s[s].index)
 
print("Categorical variables:")
print(object_cols)
cs

 

 

Type과 Method, Regionname이 encoding 해 줄 feature들이다

 

1. Drop Categorical Values

 

가장 간단한 방법으로 Categorical value가 있는 행을 버려버리는 방법이다

비어있는 데이터를 처리할 때도 써봤지만 error를 줄이는데 도움이 되는 방법은 아니었다

 

1
2
3
4
5
drop_X_train = X_train.select_dtypes(exclude=['object'])
drop_X_valid = X_valid.select_dtypes(exclude=['object'])
 
print("MAE from Approach 1 (Drop categorical variables):")
print(get_mae(drop_X_train, drop_X_valid, y_train, y_valid))
cs

 

이렇게 Categorical value를 가진 행을 버리고 mae를 구해보았더니 175703.48185157913라는 값을 얻을 수 있었다

 

2. Label Encoding

 

두번째 사용해본 방법은 라벨 인코딩이었다

라벨 인코딩은 Categorical Value마다 특정 값을 지정해주는 방법이다

예를 들어 매우 높음은 5, 높음은 4, ... ,매우 낮음은 1 처럼 numeric한 value로 바꾸어 줄 수 있다

tree based model(decision tree, random forest)에서 순서가 있는 ordinal value를 처리할 때 유리하다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from sklearn.preprocessing import LabelEncoder
 
# Make copy to avoid changing original data 
label_X_train = X_train.copy()
label_X_valid = X_valid.copy()
 
# Apply label encoder to each column with categorical data
label_encoder = LabelEncoder()
for col in object_cols:
    label_X_train[col] = label_encoder.fit_transform(X_train[col])
    label_X_valid[col] = label_encoder.transform(X_valid[col])
 
print("MAE from Approach 2 (Label Encoding):"
print(get_mae(label_X_train, label_X_valid, y_train, y_valid))
cs

 

이 때 mae는 165936.40548390493가 나왔다

 

3. One-Hot Encoding

 

원래 데이터에서 나올 수 있는 모든 값을 이름으로 하는 행을 각각 만들어준다

만약 선호하는 카페의 종류로 스타벅스, 투썸, 이디야가 나왔다면 각 이름을 가진 행을 새로 만들어주고

각 열별로 기존에 가지고 있던 값의 이름을 가진 행을 1로 나머지 행을 0으로 채워주는 것이다

스타벅스를 가장 좋아하던 사용자는 스타벅스 행은 1의 값을 가지고 투썸과 이디야라는 행은 0으로 채워진다

Label Encoding과 다르게 데이터별로 순서가 없는 nominal value에 사용한다

15개 이상의 다른 값을 가진 행에는 잘 사용하지 않는다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from sklearn.preprocessing import OneHotEncoder
 
# Apply one-hot encoder to each column with categorical data
OH_encoder = OneHotEncoder(handle_unknown='ignore', sparse=False)
OH_cols_train = pd.DataFrame(OH_encoder.fit_transform(X_train[object_cols]))
OH_cols_valid = pd.DataFrame(OH_encoder.transform(X_valid[object_cols]))
 
# One-hot encoding removed index; put it back
OH_cols_train.index = X_train.index
OH_cols_valid.index = X_valid.index
 
# Remove categorical columns (will replace with one-hot encoding)
num_X_train = X_train.drop(object_cols, axis=1)
num_X_valid = X_valid.drop(object_cols, axis=1)
 
# Add one-hot encoded columns to numerical features
OH_X_train = pd.concat([num_X_train, OH_cols_train], axis=1)
OH_X_valid = pd.concat([num_X_valid, OH_cols_valid], axis=1)
 
print("MAE from Approach 3 (One-Hot Encoding):"
print(get_mae(OH_X_train, OH_X_valid, y_train, y_valid))
cs

 

이처럼 One-Hot Encoding을 사용해서 mae를 계산하면 166089.4893009678라는 값이 나왔다