본문 바로가기
머신러닝 대회 풀이

[ML 대회 해설] Dacon 아파트 실거래가 예측 AI 경진대회 2등 풀이 - EDA (3): Object type Feature EDA

by 미역청 2025. 1. 28.

이번 포스트에선 object type featureEDA를 수행해보겠습니다. 

 

지난 글: 

 

[ML 대회 해설] Dacon 아파트 실거래가 예측 AI 경진대회 3등 풀이 - EDA (1): Numeric Feature EDA

오늘은 저번 포스트에서 뽑은 Numeric feature 들의 feature 중요도를 기반으로 본격적인 EDA에 들어가겠습니다. 지난 글 https://here-lives-mummy.tistory.com/15 [ML 대회 해설] Dacon 아파트 실거래가 예측 AI 경

here-lives-mummy.tistory.com

 

 

데이터에서 주어진 Object Type Feature는 다음과 같습니다:

  • city : 도시 이름
  • dong: 행정동 이름
  • jibun: 지번
  • apt: 아파트 이름
  • addr_kr: 지번 주소
  • transaction_date: 거래 날짜 (DD~DD)

Target Encoding 의 가능성을 고려하여 데이터 카테고리 뿐만 아니라 카테고리 별 Target의 분포까지 함께 살펴보겠습니다. 

 

Target Encoding이 뭔지 모른다면 다음 Object Type Feature 다루는 방법에 대한 설명을 참고해주세요:

 

[머신러닝 대회 입문] Label Encoding, One-Hot Encoding, Target Encoding - 문자열 Feature 다루기

데이터를 분석하면 간혹 data type이 'object'로 표현되는 것들이 있습니다.Object feature들은 numeric feature와 달리, 그대로 모델에 집어넣으면 에러가 발생합니다.그렇다면 이 feature들을 어떻게 다루어

here-lives-mummy.tistory.com

 

City

매물이 위치한 도시 이름 feature입니다.

unique value가 서울특별시, 부산광역시 두 가지이며, 서울의 매물 양이 부산에 비해 두 배 가량 많은 것을 확인할 수 있습니다.

unique value가 두 개 뿐이므로 단순히 binary encoding을 수행하면 될 것 같습니다.

이왕이면 target 값과 양의 상관관계를 갖도록, target의 평균값이 더 큰 서울특별시 1로, 작은 부산광역시를 0으로 지정해주면 될 것 같습니다.

Insight 3-1. City는 서울을 1로, 부산을 0으로 encoding한다.

 

Dong

서울과 부산의 행정동의 이름 feature입니다.

그런데, 서울과 부산 행정동 중 이름이 겹치는 것이 있지는 않을까요?

이 경우 완전히 다른 두 동이 하나로 묶이는 불상사가 발생할 수 있으니 확인해보겠습니다.

df = train.copy()
df.dong = df.city + ' '+df.dong
print(len(train.dong.unique()), len(df.dong.unique()))

위의 코드 실행 결과

같은 이름, 다른 시에 존재하는 동명이동 (?)이 네 쌍 존재합니다.

 

혹시 city가 잘못 매칭된 건 아닐지 확인하기 위해 동명이동을 모두 확인해보겠습니다.

dong_counts = train.groupby("dong")["city"].nunique()
ambiguous_dongs = dong_counts[dong_counts > 1].index
print(ambiguous_dongs)

검색해보면 네 행정동 모두 서울/부산에 있음을 확인할 수 있습니다.

 

이들을 서로 다른 동으로 취급하기 위해서 Dong feature는 City + Dong으로 바꿔줘도 될 것 같습니다.

ex) '사직동' -> '서울 사직동', '송정동' -> '부산 송정동'

Insight 3-2. Dong을 City + Dong 형식으로 바꾸어, 동명이동이 하나로 묶이는 것을 방지한다.

 

Jibun

토지에 붙인 지번입니다.

 

총 8961개의 unique value로 구성되어 있네요.

 

맨 앞 데이터 몇 건을 출력하여 addr_kr feature와 비교해보면, 도로명주소 맨 끝에 붙은 번호만 떼어온 것임을 확인할 수 있습니다.

 

Categorical feature를 engineering할 때, 만일 유사한 내용을 가진 feature 가 여러개 있다면, 보통 그 중 데이터를 더 세세하게 나눌 수 있는 feature를 취합니다. 모두 취할 경우 과적합이 발생할 수 있기 때문에 선택적으로 취하는 것이지요. (물론 언제나 예외는 존재합니다)

Insight 3-3. Jibun은 addr_kr과 공유하는 속성이 있어, 둘 중 하나를 골라야 할 수도 있다.

 

Addr_kr

각 매물의 도로명 주소입니다.

 

Unique값의 개수는 12,533개입니다.

train.addr_kr.unique()[:20]

 

/

저는 데이터의 형태를 보고 'dong' + 'jibun' + 'apt' 형식으로 구성된 것은 아닐까 하는 추측을 하였습니다.

addr_kr와 세 feature의 값을 비교해보겠습니다.

addr_kr과 dong, jibun, apt를 비교한 것. 매우 유사한 것을 알 수 있습니다.

addr_kr은 'dong' + 'jibun' + 'apt' 로 이루어진 것으로 보입니다.

만약 그럴 경우, 'addr_kr'과 'dong' + 'jibun' + 'apt'을 비교하여 데이터에 오차값이 있는 지를 확인할 수 있으며, 'addr_kr'이 세 개의 feature에 종속된 셈이 되기 때문에 addr_kr과 다른 세 feature 중 선택을 해야 할 수도 있습니다.

 

df = train.copy()
df['addr_maybe'] = df.dong + ' '+df.jibun+ ' '+df.apt
len(df[df.addr_maybe != df.addr_kr])

addr_kr은 대체적으로 dong+jibun+apt 형태가 맞았던 것으로 보입니다.

 

형태가 맞지 않는 549개는 무엇일까요? 한 번 확인해보겠습니다.

df[df.addr_maybe != df.addr_kr].head(20)

아파트명은 'J.S'인데, addr_kr에선 이것이 'J-S'로 바뀌었습니다.

이는 원본데이터 전처리 과정에서 '.'이 '-'로 바뀐 것으로 보입니다.

Insight 3-4. Addr_kr 는 dong + jibun + apt와 거의 똑같은 패턴을 가진 feature이다. addr_kr과 다른 세 feature 중 하나를 택해야 할 수 있다.

 

Apt

아파트 이름입니다. Unique 값이 10,000개 정도로, 상당히 많이 세분화되어 있어 모델에 적용 시 과적합에 걸릴 수도 있습니다.

 

apt값으로 데이터를 그룹핑하여, count 분포를 살펴보겠습니다. 

train.groupby('apt').apt.value_counts().sort_values(ascending=False).head(20)
train.groupby('apt').apt.value_counts().sort_values(ascending=False).tail(20)

 

apt unique값 별 count, average 분포

count가 13,000개에 달하는 apt값도 있는 반면, count가 1개인 값도 상당히 많은 것을 확인할 수 있습니다.

이 경우 count가 1개인 apt값이 있도록 두는 것 보다, 유사한 속성을 갖는 것끼리 그룹핑을 하는 것이 더 효과적입니다. 

저는 여기서 그룹핑을 할 수 있는 두 가지 방법을 고안했습니다:

1. count값이 큰 top 30개의 apt값을 골라 리스트를 작성한 후, count가 작은 apt값들 중 이름에 리스트에 있는 이름이 포함되었을 경우, 리스트의 이름으로 대체한다.

2. 이름에 '빌라'가 포함되어있다면 '빌라'로 대체한다.

 

2번의 경우, count값이 작은 apt 중 빌라가 상당히 많이 보여 고안했습니다. 

Insight 3-5. apt는 속성값이 다양하고 count가 1인 것들이 많아, 비슷한 값들끼리 그룹핑을 해줄 필요가 있다.

 

Transaction_date

아파트 매매거래가 이루어진 날짜입니다.

1~10, 11~20, 21~말일 중 하나의 값을 가집니다.

달을 10일씩 나누어 계산한 듯 하나 월에 따라 말일이 달라 unique값이 6개가 된 것으로 보입니다.

필요 시 21~28, 21~29, 21~30, 21~31을 모두 하나로 그룹핑해줄 수 있을 것입니다.

Insight 3-6. Transaction_date는 1~10, 11~20, 21~말일로 이루어져있으나, 매달 말일이 달라 실제보다 많은 unique값을 갖게 되었으니 이를 하나로 그룹핑해줄 수 있다.

 

결론

지금까지 object type feature를 EDA하며 얻은 아이디어를 정리하면 다음과 같습니다: 

Insight 3-1. City는 서울을 1로, 부산을 0으로 encoding한다.
Insight 3-2. Dong을 City + Dong 형식으로 바꾸어, 동명이동이 하나로 묶이는 것을 방지한다.
Insight 3-3. Jibun은 addr_kr과 공유하는 속성이 있어, 둘 중 하나를 골라야 할 수도 있다.
Insight 3-4. Addr_kr 는 dong + jibun + apt와 거의 똑같은 패턴을 가진 feature이다. addr_kr과 다른 세 feature 중 하나를 택해야 할 수 있다.
Insight 3-5. apt는 속성값이 다양하고 count가 1인 것들이 많아, 비슷한 값들끼리 그룹핑을 해줄 필요가 있다.
Insight 3-6. Transaction_date는 1~10, 11~20, 21~말일로 이루어져있으나, 매달 말일이 달라 실제보다 많은 unique값을 갖게 되었으니 이를 하나로 그룹핑해줄 수 있다.

 

추후 이 정보들을 사용해 파생 feauture을 만들거나, 이상치/결측치를 보정하는 feature engineering을 수행해 모델의 성능을 높여볼게요.


다음 글에서는 본격적으로 feature engineering과 그에 따른 성능 변화를 확인하겠습니다.

 

다음 글:

 

[ML 대회 해설] Dacon 아파트 실거래가 예측 AI 경진대회 2등 풀이 - Feature Engineering (성공편)

지난 글에서는 EDA를 통해 각 데이터의 특성을 분석하여데이터 전처리 방법과 파생 Feature 아이디어를 얻어냈습니다. 지난 글: [ML 대회 해설] Dacon 아파트 실거래가 예측 AI 경진대회 2등 풀이 - EDA

here-lives-mummy.tistory.com

 

도움이 되었다면 하트 눌러주세요 :)

구독하시면 더 많은 데이터사이언스 정보와 대회풀이를 보실 수 있습니다!