# 각 bedrooms 값별로 bedrooms의 최빈값(mode)을 구해서 결측치에 채워넣기
mode_bedrooms = airbnb1.groupby('beds')['bedrooms'].transform(lambda x: x.mode().iloc[0] if not x.mode().empty else np.nan)
airbnb1['bedrooms'] = airbnb1['bedrooms'].fillna(mode_bedrooms)
# 각 beds 값별로 bedrooms의 최빈값(mode)을 구해서 결측치에 채워넣기
mode_beds = airbnb1.groupby('bedrooms')['beds'].transform(lambda x: x.mode().iloc[0] if not x.mode().empty else np.nan)
airbnb1['beds'] = airbnb1['beds'].fillna(mode_beds)
내가 도저히 감이 안잡혀서 지피티한테 하소연을 했는데... 애가 다 짜준다.. 어쩜 이리 똑똑하지...
# 데이터 로딩 및 전처리
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
# 데이터 불러오기
airbnb = pd.read_csv("/content/2025_Airbnb_NYC_listings.csv")
airbnb.head()
# 주요 컬럼 선택 (컬럼명 수정됨)
airbnb = airbnb[[
'price', 'room_type', 'neighbourhood_group_cleansed', 'minimum_nights',
'number_of_reviews', 'availability_365', 'review_scores_rating'
]]
# 결측치 처리
airbnb.dropna(inplace=True)
# 범주형 변수 인코딩
cat_cols = ['room_type', 'neighbourhood_group_cleansed']
le = LabelEncoder()
for col in cat_cols:
airbnb[col] = le.fit_transform(airbnb[col])
# EDA - 가격 분포, 리뷰 수 관계 시각화
import matplotlib.pyplot as plt
import seaborn as sns
# 가격 컬럼 전처리 (문자 -> 숫자)
airbnb['price'] = airbnb['price'].replace('[\$,]', '', regex=True).astype(float)
# 로그 스케일 변환
airbnb['log_price'] = np.log1p(airbnb['price'])
# 로그 가격 분포 시각화
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(8, 4))
sns.histplot(airbnb['log_price'], bins=50, kde=True)
plt.title("Log-Transformed Price Distribution")
plt.xlabel("log(price + 1)")
plt.ylabel("Count")
plt.tight_layout()
plt.show()
# 리뷰 수 vs 가격
plt.figure(figsize=(8, 4))
sns.scatterplot(data=airbnb, x='number_of_reviews', y='price', alpha=0.5)
plt.title("review_cnt vs price")
plt.ylim(0, 500) # 이상치 컷
plt.show()
# 모델링 - CatBoost
!pip install catboost
from catboost import CatBoostRegressor
from sklearn.metrics import mean_squared_error, r2_score
X = airbnb.drop(columns=['price'])
y = airbnb['price']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = CatBoostRegressor(verbose=0)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
from sklearn.metrics import mean_squared_error
import numpy as np
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
print("R^2:", r2_score(y_test, y_pred))
print("RMSE:", rmse)
R^2: 0.7521792887189541
RMSE: 136.90901089024948
print(feat_imp['Feature Id'].head())
print(type(feat_imp['Feature Id'][0]))
plt.figure(figsize=(8, 5))
sns.barplot(data=feat_imp, x='Importances', y='Feature Id') # Feature Id가 곧 컬럼명
plt.title("Feature Importance (CatBoost)")
plt.tight_layout()
plt.show()
# T-test - 리뷰 평점 그룹별 가격 차이
from scipy.stats import ttest_ind
airbnb['review_group'] = airbnb['review_scores_rating'].apply(lambda x: 'high' if x >= 4.5 else 'low')
group_high = airbnb[airbnb['review_group'] == 'high']['price']
group_low = airbnb[airbnb['review_group'] == 'low']['price']
stat, p = ttest_ind(group_high, group_low, equal_var=False)
print("T-test 결과:")
print("T-statistic:", round(stat, 3))
print("P-value:", p)
print("그룹별 평균 가격:")
print(airbnb.groupby('review_group')['price'].mean())
T-test 결과:
T-statistic: 2.912
P-value: 0.0036211462422494596
그룹별 평균 가격:
review_group high 183.466220
low 165.904556
Name: price, dtype: float64
얘는 이렇게 간편하게 짜는걸 나는 왜 못할까.........
ㅈㅓㅇ말 우울하다....