이전에 올렸던 '서울시 공공 자전거 대여 패턴 분석 및 이용 활성화 전략 도출' 게시물에서는 2023년 6월부터 2024년 6월까지의 데이터를 가지고 진행했었다. 이번에는 데이터를 더 추가해서 2022년7월부터 2024년 5월까지의 데이터를 기반으로 같은 방법으로 분석 및 모델 예측을 진행했다.
기존의 게시물에서 데이터를 2022년부터 사용하지 않고 2023년 6월부터 사용한 이유는 필자의 컴퓨터 메모리가 부족했기 때문이다. 2022년 7월부터 2024년 5월까지의 데이터를 다룰 때 사용된 메모리는 아래 사진과 같다. 중간에 캡쳐를 했을 때 RAM이 18GB까지 사용했으며, 최고 31GB까지 사용했다. 8GB RAM을 가진 필자의 노트북으로는 불가능한 작업이었다. 따라서 이번엔 구글 코랩 PRO를 결제해서 새롭게 보충해서 프로젝트를 진행했다. 또한, 2022년 7월부터 2024년 5월까지의 데이터를 합쳤을 때 데이터는 84,157,637개의 행으로 굉장히 많은 것을 확인할 수 있다.
RAM 사용을 최대한 줄이기 위해 아래와 같이 함수를 만들어 하나의 데이터를 불러옴과 동시에 불필요한 카테고리를 제거하는 작업을 진행했다. 이후 pd.concat() 메서드를 이용해 모든 데이터를 합쳤다. 결과적으로 11개의 불필요한 feature를 제거한 후 생년, 성별, 이용자종류, 대여일자 4개의 feature만 남겼다.
def clean_bike_data_old(folder, files):
df = pd.read_csv(folder + files, encoding='cp949')
df.drop(['자전거번호', '대여 대여소번호', '대여 대여소명', '대여거치대', '반납일시', '반납대여소번호', '반납거치대', '대여대여소ID',
'반납대여소ID', '반납대여소명', '이용거리(M)', '이용시간(분)'], axis=1, inplace=True)
df = df.dropna()
df['대여일시'] = pd.to_datetime(df['대여일시'], errors='coerce')
df = df.dropna(subset=['대여일시'])
df['대여일자'] = pd.to_datetime(df['대여일시'])
df['대여일자'] = df['대여일자'].dt.strftime('%Y-%m-%d-%H')
df.drop(['대여일시'], axis=1, inplace=True)
return df
def clean_bike_data_new(folder, files):
df = pd.read_csv(folder + files, encoding='cp949')
df.drop(['자전거번호', '대여 대여소번호', '대여 대여소명', '대여거치대', '반납일시', '반납대여소번호', '반납거치대', '대여대여소ID',
'반납대여소ID', '반납대여소명', '이용거리(M)', '이용시간(분)', '자전거구분'], axis=1, inplace=True)
df = df.dropna()
df['대여일시'] = pd.to_datetime(df['대여일시'], errors='coerce')
df = df.dropna(subset=['대여일시'])
df['대여일자'] = pd.to_datetime(df['대여일시'])
df['대여일자'] = df['대여일자'].dt.strftime('%Y-%m-%d-%H')
df.drop(['대여일시'], axis=1, inplace=True)
return df
이후 생년, 성별, 대여일자에 feature를 수정한 후 대여일자 중 시간을 기준으로 그룹화를 진행했다.
def process_bike_data(pred_bike_1):
# 생년과 성별에서 '\N' 값을 NaN으로 변환
pred_bike_1['생년'].replace('\\N', pd.NA, inplace=True)
pred_bike_1['성별'].replace('\\N', pd.NA, inplace=True)
# 생년과 성별의 NaN 값을 가진 행을 별도로 저장하고 기존 데이터프레임에서 제거
NaN_bike = pred_bike_1[pred_bike_1[['생년', '성별']].isna().any(axis=1)]
pred_bike_5 = pred_bike_1.dropna(subset=['생년', '성별'])
# 성별 컬럼에서 'M'과 'F' 외의 값은 '기타'로 처리
pred_bike_5['성별'] = pred_bike_5['성별'].replace({'M': '남성', 'F': '여성'}).fillna('기타')
# 생년을 9년 단위로 그룹화
bins = list(range(1900, 2025, 10))
labels = [f'{year}~{year+9}' for year in bins[:-1]]
pred_bike_5['생년대'] = pd.cut(pred_bike_5['생년'].astype(float), bins=bins, labels=labels, right=False)
# 생년을 1920~2020 사이 값으로 필터링
pred_bike_5 = pred_bike_5[pred_bike_5['생년'].astype(float).between(1920, 2020)]
# 성별별 대여일자별 집계
gender_grouped = pred_bike_5.groupby(['대여일자', '성별']).size().unstack(fill_value=0).reset_index()
# 성별 이름 통일
gender_grouped = gender_grouped.rename(columns={'F': '여성', 'M': '남성'})
if 'f' in gender_grouped.columns and 'm' in gender_grouped.columns:
gender_grouped['남성'] = gender_grouped['남성'] + gender_grouped['f']
gender_grouped['여성'] = gender_grouped['여성'] + gender_grouped['m']
gender_grouped.drop(columns=['f', 'm'], inplace=True)
# 대여일자별 이용자 유형 및 생년대별 집계
bike_sum = pred_bike_5.groupby('대여일자').size().reset_index(name='대여')
user_type_grouped = pred_bike_5.groupby(['대여일자', '이용자종류']).size().unstack(fill_value=0).reset_index()
birth_grouped = pred_bike_5.groupby(['대여일자', '생년대']).size().unstack(fill_value=0).reset_index()
# 집계된 데이터를 병합
merged_df = pd.merge(gender_grouped, user_type_grouped, on='대여일자', how='outer')
merged_df = pd.merge(merged_df, birth_grouped, on='대여일자', how='outer')
merged_df = pd.merge(merged_df, bike_sum, on='대여일자', how='outer')
# 불필요한 열 삭제
if '1900~1909' in merged_df.columns and '1910~1919' in merged_df.columns:
merged_df.drop(['1900~1909', '1910~1919'], axis=1, inplace=True)
# NaN 값을 가진 데이터프레임의 집계
NaN_sum = NaN_bike.groupby('대여일자').size().reset_index(name='기타회원')
# 날짜 형식 맞추기
merged_df['대여일자'] = pd.to_datetime(merged_df['대여일자'])
NaN_sum['대여일자'] = pd.to_datetime(NaN_sum['대여일자'])
# 최종 데이터 병합
final_df = pd.merge(merged_df, NaN_sum, on='대여일자', how='outer')
return final_df
공공 자전거 대여에 대한 데이터뿐만 아니라 날씨에 대한 데이터 역시 함수화를 진행했다. 날씨의 경우 데이터가 많지는 않지만 추후에 더 추가될 수 있는 데이터와 테스트 데이터에 적용하기 위해 진행했다.
def clean_weather_data(folder, files):
df = pd.read_csv(folder + files, encoding='cp949')
df.drop(['지점', '지점명'], axis=1, inplace=True)
df = df.rename(columns={'일시': '대여일자'})
df['대여일자'] = pd.to_datetime(df['대여일자'])
df['대여일자'] = df['대여일자'].dt.strftime('%Y-%m-%d-%H')
df_sorted = df.sort_values(by='대여일자')
return df_sorted
2022년 7월부터의 데이터를 이용한 이유는 서울시에서 공개한 2022년 7월 이전까지의 데이터는 성별, 나이와 같은 개인 정보에 해당하는 데이터가 없어서 연령대별 공공 자전거 수요를 파악하지 못 할 뿐만아니라 데이터의 구조가 2022년 7월부터 달라졌기 때문에 분석에서 제외하고 진행했다.
2022년 7월부터 2023년 5월까지의 데이터를 추가했다. 하지만 시각화를 추가적으로 진행했을 때 기존과 달라진 점은 없었다.
그래프1을 보면 여전히 출퇴근 시간에 가장 많이 공공 자전거를 대여했다는 것을 확인할 수 있다.
뿐만 아니라 그래프2에서도 이전과 같이 0~4인 월, 화, 수, 목, 금에 출퇴근 시간에 대여 건수가 많이 있다. 5~6인 주말에는 점심 이후 저녁 전까지 증가하다가 감소하는 것을 확인할 수 있다. 공휴일과 공휴일이 아닌 경우에도 같은 양상을 보여준다는 것 또한 확인할 수 있다.
계절과 날씨 역시 달라진 부분이 없다. 그래프3을 보면 겨울(3)에 비해 봄(0), 여름(1), 가을(2)에 공공 자전거 대여를 많이 하는 것을 확인할 수 있다. 특히, 여름(1)에는 가장 더운 시간대인 11시~17시까지는 공공 자전거 대여 건수가 봄, 가을에 비해 낮은 것을 확인할 수 있다.
그래프4를 보면 구름의 경우 맑음인 0보다 대체로 맑음인 1, 대체로 흐림인 2일 때 대여 건수가 많은 것을 알 수 있다. 즉, 맑은 날씨에 공공 자전거 대여가 줄어 든 것 역시 기존과 같다. 또한, 비의 경우 맑은 날씨(0)에 가장 대여 건수 많으며, 약한 비(1)가 내릴 때 그래프의 높낮이가 특정 시간 대에 계속 변화하는 것을 확인할 수 있다. 약한 비가 올 때는 다른 날씨와 다르게 출퇴근 시간 이외에 12시, 15시, 17시에 대여 건수가 증가하는 것을 확인할 수 있다. 공공 자전거의 경우 만 13세 이상이면 누구나 이용이 가능하다. 15시의 경우 중학생의 하교 시간이며, 17시의 경우 고등학생의 하교 시간이다. 따라서 약한 비가 올 때는 학생들의 하교 시간에 맞춰서 증가한다고 추측할 수 있다. 특히, 주목할 점은 강한 비가 내리는 날에 퇴근 시간에 급격하게 증가한 모습을 볼 수 있다. 즉, 우산이 없는 직장인의 경우 빠르게 집에 가기 위해 공공 자전거를 타고 급하게 집으로 가는 것이라 추측할 수 있다. 추측에 대한 근거는 아래 그래프5, 6, 7, 8를 통해 확인할 수 있다.
각각 그래프는 연령대 별 공공 자전거 대여 건수를 시각화한 것이다. 일반적으로 직장인 연령대인 1980~1999년은 출퇴근 시간 대에 가장 많이 공공 자전거를 대여했다. 반면 학생 연령대인 2000~2019년은 출퇴근 시간뿐만 아니라 하교 시간인 12시 이후부터 대여 건수가 증가하고 있다. 이런 부분 역시 기존 게시물과 같은 양상을 보여주고 있다. 위에서 확인 부분 외에도 모든 그래프에서 같은 양상을 보여주었기 때문에 추가적으로 작성하지는 않았다.
추가적으로 이전에는 하지 않았던 이상치를 제거하기 위해 IsolationForest로 이상치를 제거를 했다. 하지만 제거하지 않았을 때의 차이는 그렇게 크지 않아서 오히려 더 다양한 데이터를 학습할 수 있도록 이상치를 제거하지 않고 진행했다. 또한, 모델의 경우 이전에는 하이퍼파라미터 튜닝을 하지 않았지만 이번에는 하이퍼파라미터 튜닝을 추가해 진행했다.
하이퍼파라미터 튜닝을 진행하면서 오랜 시간이 걸려 성능이 가장 좋았던 XGBoost, CatBoost, LightGBM만 이용했다. XGBoost, CatBoosts는 GPU를 이용해 진행했다. 반면 LightGBM은 구글링을 했지만 코랩에서 GPU 사용하는 방법을 찾지 못 해서 cpu로 진행했다.
이전 게시물
RMSLE: 0.3445544191120903
XGBoost | CatBoost | LightGBM |
0.57234 | 0.29610 | 0.29016 |
XGBoost
{'max_leaves': 56, 'max_depth': 13, 'min_child_weight': 8.12119905536219, \
'subsample': 0.950809957248349, 'colsample_bytree': 0.9232265017852777, \
'learning_rate': 0.08398744116169907, 'reg_alpha': 1.6634720120556756, \
'reg_lambda': 8.469551560678203, 'n_estimators': 952}
CatBoost -> 하이퍼파라미터 튜닝을 하지 않았을 때 더 좋은 점수를 보여줬음
random_state=0
Lgbm
best_params = {'n_estimators': 409, 'learning_rate': 0.07059598427094783, \
'num_leaves': 174, 'max_depth': 20, 'min_child_samples': 9, \
'subsample': 0.6372901222707613, 'colsample_bytree': 0.6526970337764204}
결과적으로 기능이 많이 향상되었고 이전 게시물과 같이 Lgbm을 사용했을 때 가장 좋은 성능을 보여줬다. feature importance도 많이 변했다. 그래프9를 보면 달라졌음을 확인할 수 있다.
뿐만 아니라 군집화를 통해서 군집화를 하는 부분에 있어서도 하이퍼파라미터 튜닝을 통해 새롭게 분석을 해보았다. 특히, 군집화 부분에서 필자가 실수했던 부분이 있어서 새롭게 다시 분석했다.
기존 게시물에서는 그래프9의 왼쪽 분포를 가지고 했다. 하지만 왼쪽 그래프를 만들 때 사용한 데이터셋은 예측 모델을 만들 때 정답이 될 수 있는 정보를 제거한 데이터이기 때문에 데이터가 특정 패턴 없이 전체적으로 분포되어 있어 군집화를 통해 명확한 군집 구조를 찾기 어려웠다. 즉, 나이, 회원 유무에 대한 정보를 제거한 데이터기 때문에 특정한 패턴이 없었던 것이다. 따라서 이번엔 잘못된 부분을 바로 잡고자 새롭게 분석을 진행했다.
반면 오른쪽 그래프는 데이터가 한쪽으로 퍼져있으며 일부 데이터 포인트가 외곽에 위치하고 있다. 군집화는 이전과 같이 KMeans, GMM, DBSCAN을 이용했다.
KMeans의 경우 그래프10 처럼 실루엣 스코어가 나왔다. 실루엣 스코어를 기준으로 했을 때 군집을 2개로 나눌 때가 좋을 수 있지만 데이터에 대한 해석에 따라 군집을 3개로 나누는 것도 괜찮을 수 있다. 반면 GMM의 경우 그래프11 처럼 하이퍼파라미터 튜닝을 하기 전에는 값이 매우 좋지 않게 나왔다. DBSCAN의 경우 하이퍼파라미터 튜닝을 했을 때도 최종 스코어가 -1로 현재 데이터셋이 맞지 않다고 판단하고 분석에서 제외했다.
kmeans_params_2 = {'n_clusters': 2, 'init': 'k-means++', 'max_iter': 317, \
'n_init': 12, 'tol': 0.0006850592283329993, 'algorithm': 'elkan'}
kmeans_params_3 = {'n_clusters': 3, 'init': 'k-means++', 'max_iter': 415, \
'n_init': 20, 'tol': 0.000289090266994302, 'algorithm': 'elkan'}
GMM_best_3 = {'n_components': 3, 'covariance_type': 'spherical', \
'tol': 0.00048774218221173864, 'reg_covar': 1.6113286798050956e-06, \
'max_iter': 162, 'n_init': 6, 'init_params': 'random', 'warm_start': True}
GMM_best_2 = {'n_components': 2, 'covariance_type': 'spherical', \
'tol': 0.00010033429392216301, 'reg_covar': 0.00019279700384210727, \
'max_iter': 211, 'n_init': 8, 'init_params': 'random', 'warm_start': True}
하이퍼파라미터 튜닝 후 KMeans는 다음과 같다. 두 개 군집, 세 개 군집 각각 실루엣 스코어는 0.597, 0.558이다. GMM의 경우 두 개 군집, 세 개 군집 각각 0.4774, 0.4974이다. 두 개의 그래프를 비교했을 때 비슷한 양상을 보여주기 때문에 더 좋은 실루엣 스코어를 보여준 KMeans를 기반으로 군집을 2개, 3개로 나눴을 때 모두 앞에서 봤던 feature importance 상위 6개를 기반으로 분석하고자 한다.
KMeans 특성 2개
1. 기온
- Cluster 0 평균 기온: 11.03°C
- Cluster 1 평균 기온: 19.57°C
Cluster 1의 평균 기온이 Cluster 0에 비해 약 8.5°C 높다. 이를 통해 Cluster 1은 기온이 높은 날에 자전거를 대여하는 사용자들로 구성될 가능성이 높다. 높은 기온에서 자전거 대여가 활발해지는 경향을 보이며, Cluster 1의 사용자들은 따뜻한 날씨에 대여 수요가 증가하는 경향을 보인다.
2. 습도
- Cluster 0 평균 습도: 68.78%
- Cluster 1 평균 습도: 58.91%
Cluster 0은 상대적으로 습도가 높은 환경에서 대여하는 사용자가 많고, Cluster 1은 습도가 낮을 때 대여가 이루어지는 경향이 있다. 이는 기온과 함께 사용자가 선호하는 날씨 조건이 다름을 나타내며, Cluster 1 사용자들이 더 건조한 날씨에서 자전거를 선호하는 것으로 보인다.
3. 지면 온도
- Cluster 0 평균 지면온도: 11.71°C
- Cluster 1 평균 지면온도: 21.65°C
지면온도는 기온과 관련이 있지만, 햇빛의 직접적인 영향으로 온도가 상승하기도 한다. Cluster 1의 평균 지면온도가 약 10°C 더 높다. Cluster 1 사용자들은 지면온도가 높은 환경에서 자전거 대여를 더 선호하는 반면, Cluster 0은 상대적으로 차가운 지면에서 자전거를 대여하는 경향이 있다.
4. 일
- Cluster 0 평균 일: 15.83일
- Cluster 1 평균 일: 15.78일
두 클러스터의 평균 일자에는 큰 차이가 없으며, 이 변수만으로 특성을 파악하기는 어렵다. 다만, 특정 일자에 대한 선호도가 강하지 않음을 나타낼 수 있으며, Cluster 0과 Cluster 1 모두 중간 일자에서 유사한 대여 패턴을 보인다.
5. 시간
- Cluster 0 평균 시간: 9.87시
- Cluster 1 평균 시간: 15.54시
Cluster 0은 오전 10시 정도에 대여가 집중되는 반면, Cluster 1은 오후 3시에서 4시 사이에 대여가 활발하다. 이를 통해 Cluster 0은 아침에 출퇴근이나 일상적인 용도로 자전거를 이용하는 사용자가 많을 가능성이 크고, Cluster 1은 여가 시간대인 오후에 자전거를 대여하는 사용자들로 구성될 가능성이 있다.
6. 바람
- Cluster 0 평균 바람 속도: 0.50
- Cluster 1 평균 바람 속도: 0.71
Cluster 1은 평균 바람 속도가 높음에도 불구하고 자전거 대여가 이루어지는 경향이 있다. 이는 바람이 어느 정도 불어도 Cluster 1의 사용자들에게 큰 영향을 미치지 않거나, 오히려 더 활동적인 날씨 조건에서 대여를 선호할 수 있음을 시사한다.
요약
- Cluster 0: 상대적으로 차가운 기온과 높은 습도, 낮은 지면온도를 선호하며, 아침 시간대에 자전거를 대여하는 경향이 강하다. 출근 시간대 할인 프로모션이나 습도가 높은 날의 대여 혜택을 고려할 수 있다.
- Cluster 0이 상대적으로 차가운 기온, 높은 습도, 낮은 지면온도를 선호하는 것처럼 보이는 이유는 출근 시간대는 아침으로 기온이 낮고, 햇빛이 상대적으로 적기 때문에 높은 습도, 낮은 지면온도이기 때문으로 판단하고 있다.
- Cluster 1: 따뜻한 날씨와 낮은 습도, 높은 지면온도에서 자전거 대여가 활발하며, 오후 시간대에 여가 목적으로 자전거를 대여하는 경향이 강하다. 여가 시간대 할인 이벤트나 기온이 높을 때의 대여 혜택을 제공하여 Cluster 1 사용자를 타겟팅할 수 있다.
- Cluster 1이 따뜻한 날씨와 낮은 습도, 높은 지면온도를 선호하는 것처럼 보이는 이유는 주 활동 시간이 15.54시로 햇빛이 강할 시기이 때문으로 판단하고 있다.
마케팅 제안
Cluster 0 - 출근 시간 중심의 사용자
- 출근 시간 할인 캠페인: Cluster 0 사용자들은 아침 시간대에 주로 대여하는 경향이 강하므로, 출근 시간(7시~10시) 할인 이벤트를 운영할 수 있다. 출근길에 자전거 대여 시 할인 쿠폰 제공, 출근 시간대에 대여할 경우 추가 포인트 적립 등의 혜택을 제공하면 좋다.
- 아침 대여 장려 캠페인: Cluster 0 사용자는 주로 출근 목적으로 자전거를 대여하는 경향이 있다. 출근 시간 자전거 대여 장려 캠페인을 통해, 출근 시간 자전거 이용 시 추가 할인 혜택을 제공하거나, 주기적인 대여 시 추가 혜택을 제공하여 장기적인 고객 유도를 할 수 있다.
Cluster 1 - 여가 시간 중심의 사용자
- 여가 시간 할인 이벤트: Cluster 1 사용자들은 오후 3시~4시 사이의 여가 시간대에 주로 대여를 한다. 여가 시간(12시~17시) 할인 이벤트를 통해, 점심 이후부터 저녁 전까지 대여 시 추가 할인 혜택을 제공하여 Cluster 1 사용자의 대여를 장려할 수 있다.
- 따뜻한 날씨 맞춤 캠페인: 기온이 높은 날 대여가 활발한 Cluster 1 사용자들을 겨냥하여, 따뜻한 날씨에 대여 혜택을 제공할 수 있다. 예를 들어, 기온이 15°C 이상일 때 대여료를 할인하거나 특정 기온 이상일 때 추가 포인트 적립 혜택을 제공하여 따뜻한 날씨에 자전거 대여를 촉진할 수 있다.
- 휴일 여가 활동 혜택: Cluster 1은 여가 시간에 자전거를 이용하므로, 주말이나 공휴일에 대여료 할인을 제공하거나, 특정 휴일 대여 시 포인트 2배 적립과 같은 이벤트를 통해 대여를 촉진할 수 있다.
- 학생 대상 타겟 마케팅: 여가 시간대인 오후 3시, 5시에 대여가 증가하는 경향이 있어, 중·고등학생을 대상으로 한 마케팅도 효과적이다. 예를 들어, 학생 인증 시 추가 할인 혜택이나, 학생 대여 시 추가 포인트 제공 이벤트를 통해 학생 사용자들을 유인할 수 있다.
전체 사용자 대상
- 미세먼지: 분석결과 미세먼지가 많을 때 구름이 적은 것으로 분석되었다. 공공 자전거는 지자체에서 운영하는 것이기 때문에 미세먼지가 많은 날에 자전거 대여 건수를 늘리기 위한 활동은 적절하지 않다고 생각한다. 따라서 미세먼지가 많을 때에는 대여시 당일 미세먼지가 많다는 알림을 보여주거나 실내 활동을 유도하는 이벤트를 진행하는 것이 적절하다고 본다.
- 주말, 휴일: 주말과 공휴일에는 출퇴근 시간 외의 여가 시간대에 대여가 증가하는 경향이 있다. 주말·휴일 대여 할인 캠페인을 통해 다양한 시간대에 자전거를 대여하도록 장려할 수 있다. 특히, 늦은 오후 시간까지 대여료 할인을 적용하거나, 주말에 대여 시 추가 포인트 적립 등의 혜택을 제공할 수 있다.
- 날씨: 맑은 날씨보다 구름이 조금 끼거나 약한 비가 내릴 때 대여가 증가하는 점을 고려하여, 맑은 날씨와 구름 낀 날에 대한 차별화된 프로모션을 적용할 수 있다. 구름이 끼거나 약한 비가 올 때 할인 혜택을 제공하여 다양한 날씨 조건에서도 자전거 이용을 촉진할 수 있다.
KMeans 특성 3개
1. 기온
- Cluster 0 평균 기온: 8.69°C
- Cluster 1 평균 기온: 20.88°C
- Cluster 2 평균 기온: 17.12°C
Cluster 1의 평균 기온이 가장 높고, Cluster 0이 가장 낮다. 이는 Cluster 1 사용자가 따뜻한 날씨에 자전거 대여를 선호하는 반면, Cluster 0 사용자는 기온이 낮을 때에도 대여하는 경향이 있음을 보여준다. Cluster 2는 중간 기온에서 대여가 이루어지며, 기온이 다소 높지만 Cluster 1만큼은 아니다.
2. 습도
- Cluster 0 평균 습도: 72.05%
- Cluster 1 평균 습도: 58.16%
- Cluster 2 평균 습도: 60.69%
Cluster 0은 상대적으로 높은 습도 환경에서 대여가 이루어지며, Cluster 1과 Cluster 2는 비교적 낮은 습도에서 대여가 많다. Cluster 1과 2는 더 건조한 날씨를 선호하는 사용자들로 구성될 가능성이 있다.
3. 지면 온도
- Cluster 0 평균 지면온도: 8.21°C
- Cluster 1 평균 지면온도: 21.88°C
- Cluster 2 평균 지면온도: 20.34°C
Cluster 1과 Cluster 2 사용자는 지면온도가 높은 환경에서 자전거를 대여하는 경향이 있으며, Cluster 0은 상대적으로 차가운 지면에서 대여하는 경향이 있다.
4. 일
- Cluster 0 평균 일자: 15.97일
- Cluster 1 평균 일자: 15.86일
- Cluster 2 평균 일자: 15.59일
세 클러스터 모두 특정 일자에 대한 차이가 크지 않으므로, 일자 자체로 특성을 파악하기는 어렵다. 각 클러스터는 달 중간에 유사한 대여 패턴을 보인다.
5. 시간
- Cluster 0 평균 시간: 8.17시
- Cluster 1 평균 시간: 15.97시
- Cluster 2 평균 시간: 14.28시
Cluster 0은 오전 대여가 집중되는 반면, Cluster 1과 Cluster 2는 오후에 대여가 활발하다. Cluster 0은 출근 또는 아침 운동에 자전거를 사용하는 사용자들이 많을 가능성이 크고, Cluster 1과 2는 여가 시간에 자전거를 이용하는 경향을 보인다.
6. 바람
- Cluster 0 평균 바람 속도: 0.46
- Cluster 1 평균 바람 속도: 0.79
- Cluster 2 평균 바람 속도: 0.62
Cluster 1은 평균 바람 속도가 가장 높음에도 불구하고 자전거 대여가 이루어지는 경향이 있다. Cluster 1 사용자들은 바람이 다소 강하게 불어도 야외 활동을 선호할 가능성이 크다.
요약
- Cluster 0: 상대적으로 차가운 기온과 높은 습도, 낮은 지면온도를 선호하며, 아침 시간대에 자전거를 대여하는 경향이 강하다. 출근 시간대 할인 프로모션이나 습도가 높은 날의 대여 혜택을 고려할 수 있다.
- Cluster 0이 상대적으로 차가운 기온, 높은 습도, 낮은 지면온도를 선호하는 것처럼 보이는 이유는 출근 시간대는 아침으로 기온이 낮고, 햇빛이 상대적으로 적기 때문에 높은 습도, 낮은 지면온도이기 때문으로 판단하고 있다.
- Cluster 1: 따뜻한 날씨와 낮은 습도, 높은 지면온도에서 자전거 대여가 활발하며, 오후 시간대에 여가 목적으로 자전거를 대여하는 경향이 강하다. 여가 시간대 할인 이벤트나 기온이 높을 때의 대여 혜택을 제공하여 Cluster 1 사용자를 타겟팅할 수 있다.
- Cluster 1이 따뜻한 날씨와 낮은 습도, 높은 지면온도를 선호하는 것처럼 보이는 이유는 주 활동 시간이 15.97시로 햇빛이 강할 시기이 때문으로 판단하고 있다.
- Cluster 2: 간 기온과 중간 습도에서 대여가 활발하며, 오후와 여가 시간대에 대여가 집중되어 있다. 봄과 가을에 할인 이벤트 제공해 적당한 기온에 자전거를 많이 대여하도록 장려할 수 있다.
- Cluster 1과 2는 거의 비슷한 특징을 보여주기 때문에 Cluster를 분리하는 것보다 실루엣 스코어를 따라서 두 개의 클러스터로 보는 것이 더 정확하다고 판단하고 있다.
- 특히, 평균 대여 시간 14.28시로 적당한 운동 또는 Cluser 1과 같이 여가 목적으로 공공 자전거를 대여하는 것으로 판단하고 있다.
마케팅 제안
Cluster 0 - 출근 시간 중심의 사용자
- 출근 시간 할인 캠페인: Cluster 0 사용자들은 아침 시간대에 주로 대여하는 경향이 강하므로, 출근 시간(7시~10시) 할인 이벤트를 운영할 수 있다. 출근길에 자전거 대여 시 할인 쿠폰 제공, 출근 시간대에 대여할 경우 추가 포인트 적립 등의 혜택을 제공할 수 있다.
- 아침 대여 장려 캠페인: Cluster 0 사용자는 주로 출근 목적으로 자전거를 대여하는 경향이 있다. 출근 시간 자전거 대여 장려 캠페인을 통해, 출근 시간 자전거 이용 시 추가 할인 혜택을 제공하거나, 주기적인 대여 시 추가 혜택을 제공하여 장기적인 고객 유도를 할 수 있다.
Cluster 1 - 여가 시간 중심의 사용자
- 여가 시간 할인 이벤트: Cluster 1 사용자들은 오후 3시~4시 사이의 여가 시간대에 주로 대여를 한다. 여가 시간(12시~17시) 할인 이벤트를 통해, 점심 이후부터 저녁 전까지 대여 시 추가 할인 혜택을 제공하여 Cluster 1 사용자의 대여를 장려할 수 있다.
- 따뜻한 날씨 맞춤 캠페인: 기온이 높은 날 대여가 활발한 Cluster 1 사용자들을 겨냥하여, 따뜻한 날씨에 대여 혜택을 제공할 수 있다. 예를 들어, 기온이 15°C 이상일 때 대여료를 할인하거나 특정 기온 이상일 때 추가 포인트 적립 혜택을 제공하여 따뜻한 날씨에 자전거 대여를 촉진할 수 있다.
- 휴일 여가 활동 혜택: Cluster 1은 여가 시간에 자전거를 이용하므로, 주말이나 공휴일에 대여료 할인을 제공하거나, 특정 휴일 대여 시 포인트 2배 적립과 같은 이벤트를 통해 대여를 촉진할 수 있다.
- 학생 대상 타겟 마케팅: 여가 시간대인 오후 3시, 5시에 대여가 증가하는 경향이 있어, 중·고등학생을 대상으로 한 마케팅도 효과적이다. 예를 들어, 학생 인증 시 추가 할인 혜택이나, 학생 대여 시 추가 포인트 제공 이벤트를 통해 학생 사용자들을 유인할 수 있다.
Cluster 2 - 여가 및 운동 목적의 사용자
- 봄·가을 시즌 캠페인: Cluster 2 사용자는 중간 기온을 선호하므로 봄과 가을 시즌에 집중적인 마케팅을 진행할 수 있다. 특정 기간 동안 대여료 할인 혜택을 제공하여 계절에 맞는 자전거 이용을 장려할 수 있다.
- 운동용 자전거 추천 이벤트: 운동 목적으로 자전거를 이용하는 Cluster 2 사용자에게는 산악 자전거나 하이브리드 자전거와 같은 모델을 추천하는 이벤트를 진행할 수 있다.
- 특정 요일 및 시간대 할인: 여가 시간 외에도 다양한 요일과 시간대에 대여 혜택을 제공하여 자전거 이용을 유도할 수 있다. 특히, 오후 시간대 할인이나 포인트 적립을 통해 사용자의 대여 빈도를 높일 수 있다.
전체 사용자 대상
- 미세먼지: 분석결과 미세먼지가 많을 때 구름이 적은 것으로 분석되었다. 공공 자전거는 지자체에서 운영하는 것이기 때문에 미세먼지가 많은 날에 자전거 대여 건수를 늘리기 위한 활동은 적절하지 않다고 생각한다. 따라서 미세먼지가 많을 때에는 대여시 당일 미세먼지가 많다는 알림을 보여주거나 실내 활동을 유도하는 이벤트를 진행하는 것이 적절하다고 본다.
- 주말, 휴일: 주말과 공휴일에는 출퇴근 시간 외의 여가 시간대에 대여가 증가하는 경향이 있다. 주말·휴일 대여 할인 캠페인을 통해 다양한 시간대에 자전거를 대여하도록 장려할 수 있다. 특히, 늦은 오후 시간까지 대여료 할인을 적용하거나, 주말에 대여 시 추가 포인트 적립 등의 혜택을 제공할 수 있다.
- 날씨: 맑은 날씨보다 구름이 조금 끼거나 약한 비가 내릴 때 대여가 증가하는 점을 고려하여, 맑은 날씨와 구름 낀 날에 대한 차별화된 프로모션을 적용할 수 있다. 구름이 끼거나 약한 비가 올 때 할인 혜택을 제공하여 다양한 날씨 조건에서도 자전거 이용을 촉진할 수 있다.
'머신러닝' 카테고리의 다른 글
RFM과 머신러닝을 활용한 모바일 게임 유저 행동 분석 및 마케팅 전략 (2) | 2024.11.29 |
---|---|
서울시 공공 자전거 대여 패턴 분석 및 이용 활성화 전략 도출 (18) | 2024.10.01 |
군집화 - 데이터 기반 고객 세그먼테이션 및 맞춤형 마케팅 전략 수립: UCI Online Retail 분석 (9) | 2024.09.21 |
Feature Selection Guide on Kaggle (0) | 2024.09.10 |