Search

[기초 프로젝트] 시애틀 Airbnb 데이터 분석

[수업 목표]
Airbnb 분석 프로젝트를 통해 **데이터 분석 5단계(문제 정의–수집–전처리–EDA–보고)**의 전체 프로세스를 이해한다.
실습을 통해 결측치 처리, 이상치 제거, 문자열·날짜·범주형 자료 변환 등 핵심 전처리 기술을 익힌다.
Room Type, 가격, 리뷰, 계절성, 위치 등을 활용하여 EDA(탐색적 데이터 분석)의 패턴 분석 방법을 이해한다.
Boxplot, IQR, 월별 리샘플링, 리뷰 Long-tail 구조 등 통계적·시각적 분석 기법을 실제 Airbnb 데이터에 적용한다.
최종적으로 “데이터 기반 인사이트 도출과 실무 의사결정 지원”이 가능한 분석 보고서를 구성하는 방법을 익힌다.
[목차]
1.
문제 정의(Problem Definition)
2.
데이터 수집(Data Collection)
3.
데이터 전처리(Cleaning & Preprocessing)
4.
EDA: Room Type, Price, Review, Location, Seasonality 분석
5.
Boxplot·IQR을 통한 가격 이상치 탐색
6.
월별 가격·예약률 리샘플링 및 패턴 분석
7.
리뷰 Long-tail 구조 및 인기 숙소 특성 분석
8.
위치 기반 분석(지역별 가격·리뷰·숙소 분포)
9.
결과 요약 및 실무 전략 제안(호스트·마케팅·경영진)

0. 데이터 분석 방법론 - 5단계

문제 정의 (Problem Definition)
해결해야 하는 문제는 무엇인가?
어떤 의사결정을 돕기 위한 분석인가?
프로젝트의 최종 산출물은 어떤 형태인가?
문제를 잘못 정의하면, 어떤 분석을 해도 의미가 없다.
팀 프로젝트에서 가장 중요한 단계이자, 분석의 방향을 결정하는 핵심 출발점이다.
데이터 수집 (Data Collection) → 데이터 셋 제공
어떤 데이터를 사용해야 문제를 해결할 수 있는가?
이미 제공된 데이터 외에 외부 데이터를 추가로 확보해야 하는가?
수집 방식은 API, 웹 크롤링, CSV/엑셀, DB 등 무엇인가?
"좋은 데이터" 확보가 분석 품질을 결정한다. 마치 요리에 필요한 재료를 고르는 과정과 같다.
데이터 전처리 (Data Cleaning & Preprocessing)
결측치(NaN), 이상치, 중복값은 어떻게 처리할 것인가?
데이터의 단위·형식·범주는 일관성 있는가?
파생 변수(Feature)를 생성해야 하는가?
전체 분석 시간의 **60~80%**를 차지하는 필수 단계. 깨끗한 데이터 없이 좋은 분석은 나올 수 없다.
데이터 분석 (Exploratory & Statistical Analysis)
EDA(탐색적 데이터 분석)를 통해 패턴을 찾았는가?
변수 간 관계는 어떻게 파악할 것인가?
시각화를 통해 데이터의 특징을 설명할 수 있는가?
데이터를 "읽는 능력"을 기르는 단계. 파이썬, Pandas, Matplotlib/Seaborn, Plotly 등을 활용해 → 트렌드 / 패턴 / 상관관계 / 분포 등을 확인한다.
결과 도출 및 보고 (Insight & Reporting)
분석 결과로부터 얻은 핵심 인사이트는 무엇인가?
팀 또는 클라이언트는 어떤 결정을 내릴 수 있는가?
스토리텔링이 가능한 시각화 및 보고서는 어떻게 구성할 것인가?
분석의 끝은 항상 "설득"이다.
데이터로 이야기하고, 분석 결과를 누구나 이해할 수 있는 형태로 전달하는 단계이다.

1. 문제 정의 (Problem Definition)

Airbnb 숙박 시장은 전통 호텔 산업과 경쟁하며 지역 경제 및 숙소 운영자 의사결정에 큰 영향을 미친다.
특히 시애틀은 관광·비즈니스 수요가 높아 숙소 유형·가격·입지가 수익성에 결정적인 차이를 만든다.

해결해야 하는 문제

어떤 요인이 숙소 가격(Price)에 가장 큰 영향을 미치는가?
계절·요일별 가격/예약 패턴은 어떤가?
리뷰 평점·리뷰 수는 예약률에 어떤 영향을 주는가?
도심 vs 교외 등 지역별 숙소 특성은 어떻게 다른가?

의사결정을 돕는 방향

호스트가 가격 전략을 어떻게 가져가야 하는지
신규 호스트는 리뷰를 어떻게 확보하고 경쟁력을 높일지
Airbnb 본사는 지역별·계절별 마케팅 전략을 어떻게 수립할지
→ 호스트에게 수익 극대화 전략을 제시하고, Airbnb 본사에서는 서비스 개선과 마케팅 방향성을 잡는 근거로 활용하는 것이 이번 비즈니스 목표이다!

최종 산출물

숙소 유형별 가격 분포 분석
지역 기반 시각화(숙소 분포 지도)
성수기/비수기 가격 및 예약 가능률 패턴
리뷰–가격/예약률 상관관계 분석
호스트/마케팅/경영진을 위한 전략 가이드라인

2. 데이터 수집 (Data Collection)

사용한 데이터는 Inside Airbnb 프로젝트에서 공개한 시애틀 Airbnb 데이터셋.
공개된 CSV형식이며 Kaggle에서도 동일한 데이터 이용 가능.
에어비앤비의 데이터 분석가 김에어가 되어서, APPASA를 기반으로 데이터 분석프로젝트를 진행합시다!

사용 데이터셋

listings.csv → 숙소 정보(가격, 위치, 유형, 리뷰 점수 등)
calendar.csv → 2016.1.1 ~ 2017.1.1 날짜별 예약 가능 여부 및 가격
reviews.csv → 숙소 리뷰(작성 날짜, 텍스트, 리뷰어 ID)

외부 데이터 필요 여부

호텔/Airbnb 경쟁 비교까지 하려면 추가 데이터가 필요하지만
본 프로젝트 목표(숙소 내부 패턴 분석)에는 현재 데이터만으로 충분하다.

데이터 접근 방식

CSV 파일 로컬 로드
(필요 시) API/크롤링은 사용하지 않음
모든 데이터는 개인정보 비식별 → 팀 협업에 적합

데이터 로드 코드

import pandas as pd listings = pd.read_csv('listings.csv') calendar = pd.read_csv('calendar.csv') reviews = pd.read_csv('reviews.csv')
Python
복사

3. 데이터 전처리 (Data Cleaning & Preprocessing)

Airbnb 데이터는 결측치·형식 오류·이상치가 꽤 많기 때문에 전처리 품질이 분석 정확도를 크게 좌우했다.

결측치 처리

결측치(Missing Values)
reviews.csv의 경우 텍스트가 없는 리뷰 존재
review_scores_rating이 없는 숙소 존재 (신규 숙소일 가능성 있음)
neighbourhood 정보가 비어 있는 숙소도 발견됨
review_scores_rating → "No Rating"
neighbourhood → "Unknown"
리뷰 텍스트 없음 → 해당 행 삭제
listings['review_scores_rating'] = listings['review_scores_rating'].fillna("No Rating") listings['neighbourhood'] = listings['neighbourhood'].fillna("Unknown") reviews = reviews.dropna(subset=['comments'])
Python
복사

이상치 처리

$0, $10,000 이상 등 비정상 가격 제거 / 기준: $10 이상 ~ $1,000 미만 유지
listings['price'] = listings['price'].replace('[\$,]', '', regex=True).astype(float) listings = listings[(listings['price'] > 10) & (listings['price'] < 1000)]
Python
복사

데이터 형식 통일

가격 데이터 이슈
price 컬럼에 달러 기호($), 쉼표(,)가 포함되어 있어 숫자로 변환 필요
price → 숫자(float)
available → True/False
날짜 컬럼 → datetime
room_type → category
calendar['available'] = calendar['available'].map({'t': True, 'f': False}) calendar['date'] = pd.to_datetime(calendar['date'], errors='coerce') calendar['price'] = calendar['price'].replace('[\$,]', '', regex=True).astype(float) listings['room_type'] = listings['room_type'].astype('category')
Python
복사

(4) 중복 및 일관성 검토

숙소 ID는 고유해야 하지만, listings.csvcalendar.csv, reviews.csv 간 조인 시 누락/불일치 가능성 있음
calendar.csv에는 같은 숙소가 여러 날짜에 반복 기록되어 있으므로, 분석 목적에 따라 집계 필요
숙소 ID 기준으로 listings/calendar/reviews 병합
중복 ID 및 일관성 없는 값 제거

데이터 병합 코드

df = listings.merge(calendar, left_on='id', right_on='listing_id', how='inner') df = df.merge(reviews, left_on='id', right_on='listing_id', how='left')
Python
복사

(5) 파생 변수 생성 (Feature Engineering)

월별 평균 가격
월별 예약 가능률
리뷰 수 기반 인기 지수

월별 리샘플링 코드

calendar_monthly = ( calendar.groupby(calendar['date'].dt.to_period("M")) .agg({'price': 'mean', 'available': 'mean'}) )
Python
복사

4. 데이터 분석 (Exploratory & Statistical Analysis)

EDA를 통해 트렌드–패턴–상관관계–군집 구조를 도출한다.

숙소 유형(Room Type) vs 가격(Price)

Entire home/apt > Private room > Shared room
→ 집 전체 대여는 개인실 대비 평균 2배 이상 비쌈
Room Type
평균 가격
Entire home
약 $155
Private room
약 $75
Shared room
약 $47
이는 가격 결정의 1차적 요인이 숙소 유형임을 보여준다.

가격 분포 시각화 코드

import matplotlib.pyplot as plt import seaborn as sns plt.figure(figsize=(10,5)) sns.boxplot(data=listings, x='room_type', y='price') plt.show()
Python
복사

시간 흐름 분석 – 월별 가격 & 예약 가능률

패턴
1~3월: 가격 낮음(비수기)
6~8월: 가격 상승 + 예약 가능률 하락 → 여름 성수기
12월: 가격 최고점($175 수준) → 겨울 휴가 성수기
계절성이 강한 숙박 시장
여름·겨울 = “가격 인상하기 좋은 구간”

월별 가격·예약률 시각화 코드

calendar_monthly['price'].plot(figsize=(12,4), title='Monthly Average Price') calendar_monthly['available'].plot(figsize=(12,4), title='Monthly Availability') plt.show()
Python
복사

리뷰 데이터 분석

리뷰 수 Long-tail
대부분 50개 이하
일부 숙소는 300~470개의 리뷰 보유 → 시장 집중 구조
인기 숙소 특징
Downtown / Capitol Hill / U District
접근성 좋음
아파트/스튜디오 형태 다수

리뷰 상위 10개 시각화 코드

top_reviews = listings.nlargest(10, 'number_of_reviews') plt.figure(figsize=(12,4)) plt.bar(top_reviews['id'], top_reviews['number_of_reviews']) plt.show()
Python
복사

위치 기반 패턴 분석

도심에 숙소가 집중
도심일수록 가격·리뷰 수 모두 높음
→ 입지가 수익성과 강하게 연결됨

지도 시각화 기본 코드

import folium m = folium.Map([47.6062, -122.3321], zoom_start=12)
Python
복사

5. 결과 도출 및 보고 (Insight & Reporting)

핵심 인사이트

① Room Type = 가격 결정의 가장 강력한 변수
Entire home/apt는 Private room의 2배 가격 이상
② 계절성(Seasonality)은 가격·예약률을 크게 좌우
성수기: 가격 상승 + 예약 가능률 ↓
비수기: 장기 숙박 및 할인 정책 필요
③ 리뷰 수 = 신뢰도 + 예약률
20~30개 리뷰만 확보해도 예약률 급등
신규 호스트에게 가장 중요한 초기 전략
④ 위치(Location)가 성과를 규정
도심 = 높은 가격 + 높은 리뷰 수 + 수요 집중
교외 = 가격 경쟁력 전략 필요

의사결정 도움

호스트
성수기 가격 인상
비수기 주중 할인·장기 숙박 할인
신규 호스트: 리뷰 확보 전략
마케팅팀
도심 지역 중심 프로모션
시즌별 테마 마케팅
평점·리뷰 기반 추천 시스템 개선
경영진(EXEC)
가격 가이드라인 정책
신규 호스트 지원 프로그램
성수기 수요 예측 기반 전략

 전체 코드 모음

모든 전처리·병합·EDA 코드가 한 번에 정리된 버전입니다.
# -----------------------# 데이터 로드# -----------------------import pandas as pd listings = pd.read_csv('listings.csv') calendar = pd.read_csv('calendar.csv') reviews = pd.read_csv('reviews.csv') # -----------------------# 결측치 처리# ----------------------- listings['review_scores_rating'] = listings['review_scores_rating'].fillna("No Rating") listings['neighbourhood'] = listings['neighbourhood'].fillna("Unknown") reviews = reviews.dropna(subset=['comments']) # -----------------------# 이상치 처리# ----------------------- listings['price'] = listings['price'].replace('[\$,]', '', regex=True).astype(float) listings = listings[(listings['price'] > 10) & (listings['price'] < 1000)] # -----------------------# 형식 통일# ----------------------- calendar['available'] = calendar['available'].map({'t': True, 'f': False}) calendar['date'] = pd.to_datetime(calendar['date'], errors='coerce') calendar['price'] = calendar['price'].replace('[\$,]', '', regex=True).astype(float) listings['room_type'] = listings['room_type'].astype('category') # -----------------------# 데이터 병합# ----------------------- df = listings.merge(calendar, left_on='id', right_on='listing_id', how='inner') df = df.merge(reviews, left_on='id', right_on='listing_id', how='left') # -----------------------# 월별 리샘플링# ----------------------- calendar_monthly = ( calendar.groupby(calendar['date'].dt.to_period("M")) .agg({'price': 'mean', 'available': 'mean'}) )
Python
복사