가변수(dummy variable)는 해당 범주(category)에 해당하는 경우 '1', 해당하지 않는 경우 '0'으로 값을 입력해주어서 통계나 기계학습을 할 때 컴퓨터가 범주형 자료의 값을 인식할 수 있도록 해줍니다. 


이번 포스팅에서는 Python pandas 라이브러리의 get_dummies() 함수를 사용하여, 


(1) 하나의 cell 당 값이 한개씩 들어있는 범주형 자료를 가지고 가변수 만들기

(2) 하나의 cell 당 범주 값이 여러개씩 들어있는 범주형 자료를 가지고 가변수 만들기


를 해보겠습니다. 


첫번째 것는 간단하구요, 두번째 것은 하나의 cell 안에 들어있는 복수개의 범주형 자료들을 분할(split) 한고 가변수 만드는 작업을 해야 해서 복잡합니다.  첫번째 것은 이전 포스팅(http://rfriend.tistory.com/273)에서 한번 소개했던 적이 있었구요, 이번 포스팅은 두번째 것을 살펴보기 위해서 글을 씁니다. 



  (1) 하나의 cell 당 값이 한개씩 들어있는 범주형 자료를 가지고 가변수 만들기



먼저 필요한 라이브러리들을 불러오고, 음악별 장르를 매핑해놓은 간단한 예제 데이터프레임을 만들어보겠습니다. 



# importing libraries

import numpy as np

import pandas as pd

from pandas import DataFrame

from pandas import Series



# make an example DataFrame

music_df = DataFrame({'music_id': [1, 2, 3, 4, 5], 

                      'music_genre': ['rock', 

                                      'disco', 

                                      'pop', 

                                      'rock', 

                                      'pop']}

                      , columns = ['music_id', 'music_genre'])


In [3]: music_df

Out[3]:

   music_id    music_genre

0 1              rock

1 2              disco

2 3              pop

3 4              rock

4 5              pop

 



위의 범주형 값이 들어있는 'music_genre' 범주형 변수에 대해서 pandas의 get_dummies() 함수를 사용하여 가변수(dummy variable) 을 만들어보겠습니다. 



In [4]: music_dummy_mat = pd.get_dummies(music_df['music_genre'])


In [5]: music_dummy_mat

Out[5]:

     disco       pop      rock

0         0         0         1

1         1         0         0

2         0         1         0

3         0         0         1

4         0         1         0

 



이번에는 (a) 가변수의 변수 이름들 앞에 'genre_' 라는 접두사(prefix)를 붙이고, (b) 원래의 music_df 데이터프레임에다가 가변수를 생성하면서 만든 music_dummy_mat 데이터프레임을 join() 함수를 사용하여 합쳐보겠습니다. 



In [6]: music_dummy_mat = music_df.join(music_dummy_mat.add_prefix('genre_'))


In [7]: music_dummy_mat

Out[7]:

   music_id  music_genre   genre_disco  genre_pop  genre_rock

0       1       rock                0               0                1

1       2       disco               1               0                0

2       3       pop                0                1                0

3       4       rock                0                0                1

4       5       pop                0                1                0

 




  (2) 하나의 cell에 범주 값이 여러개씩 들어있는 범주형 자료를 가지고 가변수 만들기


음악 한개당 구분자는 수직바('|') 로 해서 복수개의 음악 장르 범주 값이 들어있는 예제 데이터프레임을 만들어보겠습니다.  



# making example DataFrame

music_multi_df = DataFrame({'music_id': [1, 2, 3, 4, 5], 

                      'music_genre': ['rock|punk rock|heavy metal', 

                                      'hip hop|reggae', 

                                      'pop|jazz|blues', 

                                      'disco|techo', 

                                      'rhythm and blues|blues|jazz']}

                      , columns = ['music_id', 'music_genre'])

 


In [9]: music_multi_df

Out[9]:

     music_id      music_genre

0      1             rock|punk rock|heavy metal

1      2             hip hop|reggae

2      3             pop|jazz|blues

3      4             disco|techo

4      5             rhythm and blues|blues|jazz




'music_genre' 변수의 각 값에 수직바('|')로 구분되어 묶여있는 여러개의 범주 값들을 split() 문자열 메소드를 사용하여 분리를 한 후에, set.union() 함수를 사용하여 각 음악 장르 범주 값들을 원소로 가지는 하나의 집합을 만들어 보겠습니다. 



In [10]: music_genre_iter = (set(x.split('|')) for x in music_multi_df.music_genre)


In [11]: music_genre_set = sorted(set.union(*music_genre_iter))


In [12]: music_genre_set

Out[12]:

['blues',

 'disco',

 'heavy metal',

 'hip hop',

 'jazz',

 'pop',

 'punk rock',

 'reggae',

 'rhythm and blues',

 'rock',

 'techo']

 



다음으로, np.zeros() 함수를 사용하여 music_multi_df 의 행의 개수만큼의 행과 music_genre_set 의 개수만큼의 열을 가지는 '0'으로 채워진 데이터프레임을 만들어보겠습니다.  '0'만 채워진 데이터프레임은 다음번에 가변수의 '1' 값을 채워나갈 빈 집으로 보면 되겠습니다. 



In [14]: indicator_mat = DataFrame(np.zeros((len(music_multi_df), len(music_genre_set))),

    ...: columns=music_genre_set)


In [15]: indicator_mat

Out[15]:

blues disco heavy metal hip hop jazz pop punk rock reggae \

0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

4 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0


rhythm and blues rock techo

0 0.0 0.0 0.0

1 0.0 0.0 0.0

2 0.0 0.0 0.0

3 0.0 0.0 0.0

4 0.0 0.0 0.0  

 



이제 for loop 문을 사용하여 각 row 별로 music_genre 의 값을 순회하면서 split() 메소드로 분리를 한 다음에, 각 음악별로 해당 장르를 방금 위에서 '0'으로 자리를 채워두었던 indicator_mat 데이터프레임의 행, 열을 참조하여 해당 위치에 '1'의 값을 입력해주겠습니다. 



In [18]: for i, genre in enumerate(music_multi_df.music_genre):

              indicator_mat.loc[i, genre.split('|')] = 1


In [19]: indicator_mat

Out[19]:

     blues disco heavy metal hip hop jazz pop punk rock reggae \

0      0.0      0.0      1.0      0.0       0.0    0.0      1.0      0.0

1       0.0      0.0      0.0      1.0      0.0    0.0      0.0      1.0

2      1.0      0.0      0.0      0.0       1.0    1.0      0.0      0.0

3      0.0      1.0      0.0      0.0       0.0    0.0      0.0      0.0

4      1.0      0.0      0.0      0.0       1.0    0.0      0.0      0.0


     rhythm and blues      rock      techo

0      0.0                       1.0       0.0

1      0.0                       0.0       0.0

2      0.0                       0.0       0.0

3      0.0                       0.0       1.0

4      1.0                       0.0       0.0  

 



마지막으로, (a) 음악 장르 가변수의 앞 머리에 'genre_' 라는 접두사를 붙이고, (b) 원래의 'music_multi_df' 데이터프레임에 방금전에 새로 만든 'indicator_mat' 가변수 데이터프레임을 join() 함수를 이용하여 합쳐보겠습니다. 



In [20]: music_indicator_mat = music_multi_df.join(indicator_mat.add_prefix('genre_'))


In [21]: music_indicator_mat

Out[21]:

  music_id music_genre genre_blues genre_disco \

0 1 rock|punk rock|heavy metal 0.0 0.0

1 2 hip hop|reggae 0.0 0.0

2 3 pop|jazz|blues 1.0 0.0

3 4 disco|techo 0.0 1.0

4 5 rhythm and blues|blues|jazz 1.0 0.0


  genre_heavy metal genre_hip hop genre_jazz genre_pop genre_punk rock \

0 1.0 0.0 0.0 0.0 1.0

1 0.0 1.0 0.0 0.0 0.0

2 0.0 0.0 1.0 1.0 0.0

3 0.0 0.0 0.0 0.0 0.0

4 0.0 0.0 1.0 0.0 0.0


  genre_reggae genre_rhythm and blues genre_rock genre_techo

0 0.0 0.0 1.0 0.0

1 1.0 0.0 0.0 0.0

2 0.0 0.0 0.0 0.0

3 0.0 0.0 0.0 1.0

4 0.0 1.0 0.0 0.0  


 



많은 도움이 되었기를 바랍니다. 

728x90
반응형
Posted by Rfriend
,