데이터분석

pandas.qcut, 구간 나누기, categorical 변수

still..epochs 2023. 8. 21. 21:19

데이터 분석을 하다보면 카테고리 변수를 다루는 일이 자주 있다. 예를 들어 동물의 크기에 따라 small, medium, large 세 경우로 나뉜다고 하였을 때, 이를 머신러닝에 활용하기 위해서는 이를 float이나 int 형으로 표현해주어야 한다. 이런 과정을 할때 보통 onehot-encoding을 사용한다.

 

그런데 만약 '나이'와 같은 변수를 카테고리 변수로 바꾸고 싶다면 어떻게 해야 할까?

 

당연히 판다스에는 이에 해당하는 적절한 메서드가 존재한다.

 

https://pandas.pydata.org/docs/reference/api/pandas.qcut.html

 

pandas.qcut — pandas 2.0.3 documentation

Number of quantiles. 10 for deciles, 4 for quartiles, etc. Alternately array of quantiles, e.g. [0, .25, .5, .75, 1.] for quartiles.

pandas.pydata.org

 

공식 문서를 살펴보면 해당 메서드는 다음과 같이 사용할 수 있다.

 

pandas.qcut(x, q, labels=None, retbins=False, precision=3, duplicates='raise')

 

x : 데이터 프레임의 column을 넣는다. 1차원 행렬이나 Series 데이터를 사용한다.

q : 나누고 싶은 구간을 설정한다

label : 라벨을 지정하여 각 구간의 이름을 설정한다.

 

 

예시코드

# 1
pd.qcut(range(5), 4)

>> [(-0.001, 1.0], (-0.001, 1.0], (1.0, 2.0], (2.0, 3.0], (3.0, 4.0]]
   Categories (4, interval[float64, right]): [(-0.001, 1.0] < (1.0, 2.0] ...
   

# 2
pd.qcut(range(5), 3, labels=["good", "medium", "bad"])

>> [good, good, medium, bad, bad]
   Categories (3, object): [good < medium < bad]

이를 활용해서 직접 데이터 프레임의 형태를 변경해보자.

내가 사용하는 데이터 프레임의 나이의 유니크한 값은 105개나 된다. 만약 각 나이들을 카테고리 변수로 변경한다면 최소 50개 이상의 열이 새롭게 생성될 것이다. ( 더 많아질 지도...?) 그렇다면 데이터를 학습시켰을때 모델이 너무 많은 열로 인하여 제대로 학습하지 못하거나 성능이 떨어지는 문제가 발생할지도 모른다. 이럴 경우에 전체 나이의 0~20%, 20~40%, 40~60%, 60~80%, 80~100% 로 구간을 설정하면 최소 5개의 열로 모든 나이들을 카테고리 변수로 만들 수 있을 것이다.

 

 

코드

ptile_labels = ['ptile1', 'ptile2', 'ptile3', 'ptile4', 'ptile5']
features = features.join(pd.get_dummies(pd.qcut(features['Age'], q=[0, .2, .4, .6, .8, 1], labels=ptile_labels), prefix='Age'))
features

 

위 코드를 설명하자면 먼저 ptile_labels 는 내가 설정한 카테고리 변수 컬럼의 이름이다. 

features의 'Age' 컬럼을 5구간으로 변경해 줄 것이므로 q에는 각 구간을 설정하여 넣어준다. 이렇게 하면

'Age' 컬럼의 105개나 되는 unique 한 값을 5개의 카테고리 변수로 정리할 수 있다.

 

종종 써먹도록