본문 바로가기
데이터 분석/데이터 전처리

[Pandas] 17. 범주형 데이터 가변수/더미 변수(dummy variable)로 바꾸기

by 부자 꽁냥이 2021. 1. 19.

안녕하세요~ 꽁냥이에요. 회귀 모형을 적합할 때 범주형 변수를 더미 변수로 바꾸어주는데요. Pandas에서는 범주형 변수를 더미 변수로 바꾸어주는 get_dummies함수를 제공합니다. 이번 포스팅에서는 Pandas를 이용하여 범주형 변수를 가변수로 바꿔보는 방법에 대해서 소개합니다.


여기서는 가변수, 더미 변수 혼용했습니다. 둘 다 같은 뜻입니다.

 

get_dummies 함수의 기본적인 사용법은 다음과 같습니다.


get_dummies(데이터프레임, columns = [칼럼명1, 칼럼명2, . . . ] , . . )


get_dummies의 첫 번째 인자에는 가변수로 바꾸어줄 데이터를 넣어줍니다. 그리고 columns에는 가변수로 바꿔줄 범주형 칼럼 이름을 넣어줍니다. columns를 따로 지정해주지 않으면 문자(열) 데이터로 이루어진 칼럼이 자동으로 지정됩니다. 설명으로는 감이 안 오실 수 있으니 코드를 통해서 확인해봅시다.

 

필요한 모듈을 임포트하고 예제 데이터를 생성합니다.

 

import pandas as pd
import numpy as np

## 데이터 생성 
data = {
    'gender' : ['male','female','male','male','female'],
    'height' : [175,165,180,169,188],
    'nation' : ['USA','Korea','China','Korea','Brazil'],
    'married' : [0,1,1,1,0]
}
df = pd.DataFrame(data)

 

 

아래 코드를 실행해보세요.

 

pd.get_dummies(df)

 

 

범주형 칼럼을 따로 지정하지 않아서 문자로 이루어진 gender, nation이 자동적으로 가변수(더미 변수)로 바뀌었습니다. 가변수로 처리된 칼럼은 '칼럼명_값'의 형태로 새로운 칼럼 이름이 생성됩니다. 여기서 married 칼럼도 범주형 변수이지만 숫자로 이루어졌기에 가변수로 처리되지 않았습니다. 이번엔 칼럼을 지정해보겠습니다.

 

pd.get_dummies(df, columns = ['married','gender','nation'])

 

 

married 칼럼까지 가변수로 변환되었습니다.

 

여기서 눈여겨 보실점은 범주형 변수의 범주 개수만큼 가변수 칼럼이 생성되었다는 건데요. 회귀 모형에서 범주형 변수의 범주 개수가 $K$개일 경우 $K$개 가변수 모두 사용할 경우 문제가 생기는데요. 선형 종속인 칼럼이 생겨 회귀 계수를 구할 수 없게 되지요. 따라서 이러한 선형 종속을 방지하기 위하여 $K-1$ 개의 가변수만을 사용합니다. get_dummies 함수에는 이를 위하여 drop_first 옵션을 제공하는데요. 이를 True로 하게 되면 가변수를 하나를 제외시켜줍니다. 제외되는 가변수는 숫자인 경우는 가장 작은 수, 문자열이면 알파벳순으로 가장 앞에 있는 문자열인 것 같아요.

 

## 가변수 하나 제거
pd.get_dummies(df, columns = ['married','gender','nation'],drop_first=True)

 

 

그런데 가끔은 해석을 위해서 제외해야 할 가변수, 즉 제외시킬 범주를 지정해야 할 때가 있을 것입니다. 그런데 get_dummies 함수는 우리가 원하는 범주를 제외시켜주는 기능이 없습니다. 따라서 우리가 원하는 범주를 제외하기 위해서는 함수를 따로 만들어 줘야 합니다. 아래 코드는 이를 위한 함수입니다. 꽁냥이가 만들어보았어요. 함수에 대한 설명은 주석으로 대체하겠습니다.

 

def get_dummy(df,columns,base_value=None):
    '''
    df : 데이터프레임
    columns : 가변수로 변환할 칼럼들
    base_value : {가변수로 변환할 칼럼명 : 제외시킬 범주}
    '''
    for c in columns:
        num_level = len(set(df[c])) ## 유니크한 원소의 개수
        uniq_element = sorted(list(set(df[c])))[1:] ## 정렬했을 때 첫 번째 범주를 제외
        
        if base_value: ## 제외시킬 범주가 있을 경우 해당 범주를 제외
            if c in base_value.keys():
                assert base_value[c] in list(set(df[c])), f'{base_value[c]} is not contained in {c}'
                uniq_element = sorted(list(set(df[c])-{base_value[c]}))
                    
        data = dict()
        for i in range(num_level-1):
            dummy_data = []
            val = uniq_element[i]
            for d in df[c]: ## 해당 범주인 경우만 1 나머지는 0
                if d == val:
                    dummy_data.append(1)
                else:
                    dummy_data.append(0)
            col_name = c+'_'+str(val) ## 갸변수의 칼럼명 지정
            data[col_name] = dummy_data
        
        temp_df = pd.DataFrame(data)
        df = pd.concat([df.reset_index(drop=True),temp_df],axis=1) ## 가변수 칼럼을 원 데이터 뒤에 결합
        ## reset_index를 이용하여 로우 인덱스를 초기화해야함.

    return df.drop(columns=columns) ## 원 범주 칼럼은 제외

 

아래 코드는 위 함수를 이용하여 married 칼럼에는 1, nation 칼럼에는 Korea를 제외시키고 가변수로 변환합니다.

 

get_dummy(df,['married','nation','gender'],{'married':1,'nation':'Korea'})

 

 

보시는 바와 같이 원하는 범주가 제외되고 더미 변수로 바뀌었습니다.


이번 포스팅에서는 범주형 변수를 가변수로 바꾸는 방법에 대하여 알아보았습니다. 부디 데이터를 다루실 때 도움이 되었으면 합니다. 지금까지 꽁냥이의 글 읽어주셔서 감사합니다~~

 


댓글


맨 위로