[과제] 부동산 데이터셋 - 개인 프로젝트 과제 회고 📄

😵‍💫 추석연휴 기간 개인 과제

2018 ~ 2024년도 부동산 데이터셋을 가지고 개인프로젝트(?) 과제를 진행했다.

아직은 미숙한지라 2~3일 정도 걸리긴 했지만, 헷깔린 부분 제외 16번까지 풀어보았다.

 

🤪 문제점 발견

목요일 14시 팀원들과 젭에 모여 공유하는 시간을 가졌다.(3명 모임)

우선 다들 과제를 진행 중이라고 하셨고, 나는 모두 풀어는 보았으니 내가 진행한 내용들을 공유했다.

그렇게 화면공유를 하면서 설명하며 공유하다보니까 혼자 생각할 때는 몰랐던 것들 그리고 이상했던 것의 원인을 발견하게 되었다.

 

> 중복값 처리 

일단 나는 분석 전처리 과정에서 분석에서 중요하지 않거나 필요하지 않은 컬럼(열)들은 과감히 삭제하는 판단을 내렸다.

전체 컬럼들 중에서

print(df.columns.to_list())
'접수연도', '자치구코드', '자치구명', '법정동코드', '법정동명', '지번구분', '지번구분명', '본번', '부번', '건물명', '계약일', '물건금액(만원)', '건물면적(㎡)', '토지면적(㎡)', '층', '권리구분', '취소일', '건축년도', '건물용도', '신고구분', '신고한 개업공인중개사 시군구명'
df.drop(['지번구분', '지번구분명', '본번', '부번', '토지면적(㎡)', '층', '권리구분', '신고구분', '신고한 개업공인중개사 시군구명'], axis=1, inplace=True)

이렇게 모두 삭제를 해버렸다...

 

그러다보니 전체 약 83만 행에서 중복을 삭제하니 약 1만 행으로 줄어들어버렸다.

"이거는 말도 안된다." 싶은 생각이 들어서, 일단은 중복 처리는 하지 않고 진행하게 되었다.


❌ 문제점 발견

팀원들과 의견을 나누다 보니, 섣불리 컬럼을 삭제하면 안됐던 것 같다. 컬럼이 많을 때 여러 컬럼들을 단지 필요없을 것 같다는 판단 하에 삭제 처리를 해버리면 중복을 찍어보았을 때 *문제가 생길 수 있다는 점을 알게되었다.

* 문제 = 원래 중복 행보다 많아지게 되는 케이스 | 즉, 중복행 증폭 현상 발생

 

⭕️ 문제점 해결 방안

중복행들을 먼저 확인하고 처리 후에 필요없는 컬럼을 삭제처리 하도록 하자!!

| 선 중복 확인 및 처리 → 후 불필요 컬럼 삭제 처리

 

위의 방안대로 진행 결과:

df[df.duplicated() == True]
# ✅중복 : 13,919행

중복된 행이 13,919행인 것을 확인했고,

df_copy = df.copy()

df_copy.drop_duplicates()
# 🔍 이렇게 중복처리를 해보니 원래 약 83만행에서 위 중복행을 제거한 약 81만행이 되는구나!
# 이전에 내가 컬럼 삭제하고 중복을 확인했던 것은 잘못된 거였어!

복사 후 중복값 처리를 시도해 본 결과, 819,695행으로 나온 것을 확인하였다.

"이게 맞는 것 같다." 앞으로는 같은 실수를 하지 않도록 주의하자!

 

이렇게 중복 처리한 것으로 과제를 수정해야겠다.


중복을 먼저 확인한 것은 잘못된 것이 없다. 그러나,,,

삐이이이~~~~~비상! 비상!🚨🚨🚨🚨🚨🚨

처음부터 다시 진행해보고 있는데, 결측치 처리 과정에서 다시 궁금증이 생겼다.

우선 컬럼 삭제를 하지 않고, 대부분의 컬럼을 대체값으로 채워보았다.

[예외- 건축년도 결측치 행은 삭제, 취소일은 비결측치 행 삭제(취소된 거래 데이터)]

df['자치구명'] = df['자치구명'].fillna('강북구')

df['지번구분'] = df['지번구분'].fillna("-")
df['지번구분명'] = df['지번구분명'].fillna("Unknown")
df['본번'] = df['본번'].fillna("-")
df['부번'] = df['부번'].fillna("-")
df['건물명'] = df['건물명'].fillna("Unknown")
df['토지면적(㎡)'] = df['토지면적(㎡)'].fillna("-")
df['층'] = df['층'].fillna("-")
df['권리구분'] = df['권리구분'].fillna("Unknown")
df['신고구분'] = df['신고구분'].fillna("Unknown")
df['신고한 개업공인중개사 시군구명'] = df['신고한 개업공인중개사 시군구명'].fillna("NONE")

df = df.dropna(subset=['건축년도'])

df = df[df['취소일'].isna()]
df['취소일'] = df['취소일'].fillna('NONE')

처리 한 후에 중복 데이터 확인을 해보니?

df[df.duplicated() == True]

어라? 중복행이 존재하지 않게 된 건가? 😵‍💫

이렇게 나왔다. "이게 찐으로 맞는 건가?"

그렇다면 중복 데이터는 그냥 확인해본 것을 끝으로 넘어가보자!! 그리고 컬럼 삭제는 하지 않도록 하겠다!


😭🚨 초비상

df.describe()

를 찍어보니,,,

무엇이 문제인거지?

무엇이 문제인가? 컬럼 삭제를 막 해도 안되지만, 대체값을 채우는 것도 가려서 해야하는 것인가? 그런 것 같은데.... 😠


🔥 재재재 시도

중복 처리를 해놓은 다음 결측치 처리 순서 유지하고,

결측치를 수치형과 범주형 컬럼에 구분을 두지 않고 대체값을 채워넣은 것이 문제인 것 같다.

구분해서 다시 해보았다.

num_cols = df.select_dtypes(include=['int64', 'float64']).columns
cat_cols = df.select_dtypes(include='object').columns

이렇게 하면 원하는 데이터타입을 포함해서 뽑아올 수 있다!!

 

1. num_cols 의 결측치를 확인해보자

df[num_cols].isnull().sum()

결측치가 있는 수치형 컬럼들을 확인하고서 결측치를 어떻게 처리할지 전략을 세운다.

#1. 지번구분 컬럼 삭제
df.drop(columns='지번구분', inplace=True)

#2. 토지면적 중앙값으로 대체
df['토지면적(㎡)'] = df['토지면적(㎡)'].fillna(df['토지면적(㎡)'].median())

#3. 층 평균값으로 대체
df['층'] = df['층'].fillna(df['층'].mean())

#4. 취소일 비결측치 행 삭제 후, 열 삭제 
df = df[df['취소일'].isnull() > 0]
df.drop(columns='취소일', inplace=True)

#5. 건축년도 중앙값으로 대체
df['건축년도'] = df['건축년도'].fillna(df['건축년도'].median())

 

2. cat_cols 의 결측치를 확인해보자.

df[cat_cols].isnull().sum()

결측치가 있는 범주형 컬럼 처리

#1. 자치구명 결측치 대체
df.loc[df['자치구명'].isnull()>0, '법정동명']   # 미아동
df.loc[df['법정동명'] == '미아동', '자치구명']    # 강북구
df['자치구명'] = df['자치구명'].fillna('강북구')

#2. 지번구분명, 본번, 부번: '미입력'으로 대체
df[['지번구분명', '본번', '부번']] = df[['지번구분명', '본번', '부번']].fillna('미기입')

#3. 건물명 '미상'으로 대체
df['건물명'] = df['건물명'].fillna('미상')

#4. 권리구분, 신고구분, 신고한 개업공인중개사 시군구명 삭제
df.drop(columns=['권리구분', '신고구분', '신고한 개업공인중개사 시군구명'], inplace=True)

이렇게 결측치 처리를 완료! 

df.describe()도 찍어보니 이번엔 NaN값이 아닌 수치들로 채워져 있었다.

 

끝.

 

 

 

 

Q1. 중복값 처리에 있어서 문제점? 열 삭제후 중복값을 확인하면 그 중복된 것들이 더 많아지게 될 수 있다(문제점)

Q2. 80만 행 중 2만5천 행의 중복값은 삭제하고 진행해도 될까? drop.duplicated()