어제거 코드 다시 돌려보았다.(어차피 지금 df_encoded 데이터프레임이 범주형만 인코딩 한 것이기 때문에 price컬럼은 없다.) 일단 원-핫인코딩 진행하면서 컬럼수가 많아졌는데, 그런 모든 컬럼수까지 다 진행하면서 price랑 비교해서 feature importance를 알아보았는데- 일단은 이렇게 나왔다. 컬럼이 너무 많아서 상위 20개만 뽑아왔음.

from sklearn.ensemble import RandomForestClassifier

# 근데 이거는 그 범주형 데이터랑 프라이스의 피쳐중요도만 구하는 방식임,, 수치형이랑 해서 다시 구해야 함. 
from sklearn.ensemble import RandomForestClassifier

X_train = df_encoded
y_train = df1['price']
# x_train이랑 y_train이랑 같은 값이 들어가면 안된다. y_train에는 비교하고 싶은 값,
# 알아보고 싶은 것을 넣어야 한다. 지금 내가 구하고 싶은게 price 예측이니까, price컬럼을 넣었음.

model = RandomForestClassifier()
model.fit(X_train, y_train)
importances = model.feature_importances_

import matplotlib.pyplot as plt
# 중요도 데이터프레임 생성
feature_names = X_train.columns
importances = model.feature_importances_

importance_df = pd.DataFrame({
    'Feature': feature_names,
    'Importance': importances
})

# 중요도 기준으로 정렬
importance_df = importance_df.sort_values(by='Importance', ascending=False)

# 시각화
plt.figure(figsize=(12, 8))
sns.barplot(x='Importance', y='Feature', data=importance_df)

plt.title('Feature Importances')
plt.xlabel('Importance Score')
plt.ylabel('Feature')
plt.tight_layout()
plt.show()

top_features = importance_df.head(20)

plt.figure(figsize=(12, 8))
sns.barplot(x='Importance', y='Feature', data=top_features)
plt.title('Top 20 Feature Importances')
plt.tight_layout()
plt.show()

image.png

일단은 헷갈리니 파일을 하나 더 만들어서 지금까지 제거한 컬럼들 다시 다 제거하고 다시 시작하기로

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# index_col=0을 해줘서 저번처럼 unnamed: 0이라는 컬럼 빼주기!
df = pd.read_csv(r'C:\\Users\\User\\Desktop\\과제\\25.4.18project\\2025_Airbnb_NYC_listings.csv', index_col=0)

# 복사본 만들기
df1 = df.copy()

#현재 프레임 확인
df1.shape
(22308, 72) # 22308행, 72개의 컬럼

#모든 행이 결측치인 컬럼 제거 후, 값 다시 담아주기
df1 = df1.dropna(axis=1, how='all')
df1.shape
(22308, 71)

#어제 내가 제거했던 모든 컬럼 다시 제거(근거는 내 노션에 작성되어 있음)
df1 = df1.drop(['license','neighbourhood','host_about','first_review',
'host_location','id','availability_60','availability_90',
'number_of_reviews_ltm','calculated_host_listings_count_entire_homes',
'host_name','source','calendar_last_scraped','latitude', 'longtitude',
'host_acceptance_rate'],axis=1, errors='ignore')

df1.shape
(22308, 56)

💡이미 한번 제거한 컬럼들은 다시 제거하려고하면 키에러가 나니까 조심하기!!

여기서 어제 feature importance를 보려고 했던 건데, 잘못 나와서,, 일단은 컬럼 수를 30개까지 줄여봐야겠음.

#결측치 천단위 이상은 싹다날리고 싶다는 욕구가 올라온다,,,
df1.isna().sum().sort_values(ascending=False)
~~neighborhood_overview~~                           10046
review_scores_location                           6799
review_scores_accuracy                           6798
last_review                                      6798
review_scores_communication                      6798
review_scores_value                              6798
review_scores_rating                             6798
review_scores_cleanliness                        6798
review_scores_checkin                            6798
reviews_per_month                                6798
host_neighbourhood                               4730
host_response_rate                               4393
host_response_time                               4393
description                                       405
host_is_superhost                                 374
has_availability                                  246
beds                                               79
bedrooms                                           49
host_has_profile_pic                               20
host_identity_verified                             20
host_total_listings_count                          20
host_verifications                                 20
host_since                                         20
host_listings_count                                20
bathrooms_text                                     14

df1['neighborhood_overview'] 
# 지역 개요. 지역을 설명할 수 있는 대체컬럼을 찾아보자-description?

흐름 정리: 결측치 처리→이상치 처리→범주형 변수 인코딩→수치형 변수 스케일링→모델링+ 피처 중요도 시각화

neighborhood_overview결측치 1만개가 넘어가는 컬럼은 좀 힘들 것 같은데,, 만약 좀 중요한 컬럼이라고 생각하지만 결측치가 너무 많아버리면 어떻게 해야하지?-너무 많고, str형인데다가 다 너무 달라서 사용하기 어려울 것이라고 판단됨. →제거

df1 = df1.drop('neighborhood_overview',axis=1)
df1.shape
(22308, 55)

review_scores_location: 소수 2자리까지 있는 숫자임.

평균값:np.float64(4.729517699400348)

중앙값:np.float64(4.82)

둘 다 비슷해서 딱히 이상치는 없는 것 같고,, 다 비슷하다면 굳이 필요하지는 않을 것 같음. 하위 점수 볼려고 일단 결측치가 많아서→ 제거하려고 했으나