ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1. 데이터 분석가 프로젝트 1~2주차 수행일지
    마케터 관점의 데이터분석/데이터분석 프로젝트 2025. 8. 19. 12:54

     

    프로젝트 주제는 관광 데이터 기반 외국인 관광객 특성별 패턴 분석이다.
     
    이 주제를 선택한 이유는
     
    거시적(국가 정책) → 중간(기업/시장) → 미시적(고객 경험) 측면에서 볼 때 관광마케팅은 필요하다.
    마케팅 실무 + 정부기관 프로젝트 모두에 관심이 있는데, 이 주제는 두 영역을 동시에 포함할 수 있어서 선택했다.

     

    • 거시적 관점: 국가 정책 & 글로벌 트렌드

      최근 정부와 지자체는 외국인 관광객 유치를 국가적 과제로 삼고 있다.
      문화체육관광부한국관광공사는 외래관광객 유치를 위해 도약을 준비 중이고,
      서울 / 부산 / 제주/ 전주경북 지자체는 “세분화된 관광객 타겟팅 + 맞춤형 캠페인” 전략을 추진 중이다.

      관광 산업은 단순한 여행 서비스가 아니라 국가 이미지, 지역 경제, 고용 창출까지 직결되는 산업으로 보인다.
      따라서 데이터 기반 관광 마케팅 전략은 국가 정책과 산업 트렌드를 뒷받침할 수 있는 중요한 인사이트라고 생각했다.

     

    • 중간 관점: 시장 & 기업 마케팅

      거시적으로는 국가 정책이지만, 현장에서 이걸 실행하는 주체는 기업/에이전시 이다.

      특히 마케팅 에이전시는 
      데이터 기반 의사결정: “어떤 국가에서 어떤 세그먼트가 긍정 경험을 하고, 어떤 부분에서 불편을 느끼는가?”
      캠페인 전략 제안: 단순 홍보가 아니라 세그먼트별 맞춤 메시지를 설계해야 한다.
      성과 검증: A/B 테스트, ROI 분석 같은 실무적 방법론이 요구된다.

      그래서 최종 프로젝트는 실제 마케팅 실무에 바로 적용 가능한 전략 프레임워크를 만드는 것이 목표이다.

     

    • 미시적 관점: 고객 & 경험
      마케팅은 결국 기업/서비스/상품을 사람과 연결하는 하나의 다리이다.
      최종 프로젝트를 통해 누가 한국을 찾고 어떤 경험이 긍정/부정으로 이어졌는지
      이를 바탕으로 세그먼트별 페르소나와 마케팅 메시지를 구체화 할 예정이다.

     
    방문객 수 + 감성 기반 마케팅 인사이트 도출하기


    [멀티캠퍼스 KDT 데이터 분석가 최종 프로젝트 1~2주차 수행일지]

     

    1. 프로젝트 개요

    • 메인 주제: 관광 데이터 기반 외국인 관광객 특성별 패턴분석 및 세분화
    • 서브 주제:
      • 비용-효과 기반 마케팅 믹스 모델링(MMM)
      • 외국인 관광객 맞춤형 A/B 테스트 전략 시뮬레이션
    • 최종 목표: Top 5 국가별 관광객 행동 데이터를 기반으로, ROI가 높은 채널을 찾아내어 마케팅 인사이트 발굴

    2. 데이터셋 확보 현황

    • 관광청/관광공사 제공 13개 CSV (성별·연령별, 목적별, 지역별 방문, 만족도, 긍부정 추이 등)
    • 리뷰 데이터 (외부 논문/공공데이터)
    • marketing_AB.csv → 국가별/채널별 A/B 테스트 결과
    • Advertising.csv → 채널별 광고 투자액
    • market-mix-modeling-using-sales-data.ipynb → MMM 예제 코드 확장
    • 데이터셋

    3. 분석 진행 상황

    (0) 데이터 전처리

    import pandas as pd
    csv_files = {
        "국가별 외국인 방문 현황": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813163808_국가별 외국인 방문 현황 CSV 다운로드.csv",
        "방한여행 요약(국적별)": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164248_방한여행 요약(국적별).csv",
        "방한여행 요약(대륙별)": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164248_방한여행 요약(대륙별).csv",
        "방한 외래관광객 특성(교통수단별)": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164323_방한 외래관광객 특성(교통수단별).csv",
        "방한 외래관광객 특성(성·연령별)": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164323_방한 외래관광객 특성(성·연령별).csv",
        "방한 외래관광객 특성(목적별)": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164323_방한 외래관광객 특성(목적별).csv",
        "방한여행 행태 및 만족도 평가": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164343_방한여행 행태 및 만족도 평가.csv",
        "방한 여행 이미지": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164348_방한 여행 이미지.csv",
        "관광객 지역별 방문비율": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164557_관광객 지역별 방문비율 CSV 다운로드.csv",
        "긍부정 점유율 추이": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164536_한국 관광 관련 긍부정 점유율 추이.csv",
        "국가별 관광 포지셔닝 맵": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164533_국가별 한국 관광 관련 언급 포지셔닝 맵.csv",
        "국가별 언급량·노출량": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164525_한국 관광 관련 국가별 언급량 인게이지먼트 잠재적 노출량 합산표.csv",
        "관광 언급량 추이": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164522_한국 관광 관련 언급량 인게이지먼트 추이 언급량.csv",
        "offerings": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/offerings.csv",
        "marketing_AB": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/marketing_AB.csv",
        "Advertising": "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/Advertising.csv"
    }
    
    headers_preview = {}
    for name, path in csv_files.items():
        try:
            df = pd.read_csv(path, nrows=5)
            headers_preview[name] = df.head()
        except Exception as e:
            headers_preview[name] = f"Error: {e}"
    
    headers_preview

    결과:

    012


    (1) 탐색적 데이터 분석 (EDA)

    목적: 관광객 기본 특성(연령·성별·방문 목적 등) 및 소셜 언급량 분석
     

    # 폰트설치
    !sudo apt-get update -qq
    !sudo apt-get install -y fonts-nanum
    !sudo fc-cache -fv
    !rm -rf ~/.cache/matplotlib
    # 한글 제목 깨짐 해결하기
    import matplotlib.pyplot as plt
    import matplotlib.font_manager as fm
    font_path = '/usr/share/fonts/truetype/nanum/NanumGothic.ttf'
    font_name = fm.FontProperties(fname=font_path).get_name()
    plt.rc('font', family=font_name)
    plt.rcParams['axes.unicode_minus'] = False
    print(f"Matplotlib font set to: {plt.rcParams['font.family']}")
    import pandas as pd
    import matplotlib.pyplot as plt
    
    try:
        df = pd.read_csv("/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164323_방한 외래관광객 특성(성·연령별).csv")
        # '남성'과 '여성' 열을 더하여 총 방문객 수를 계산하고 시각화
        df["총 방문객수"] = df["남성"] + df["여성"]
        df.groupby("연령대")["총 방문객수"].sum().plot(kind="bar")
        plt.title("Visitor Distribution by Age Group")
        plt.show()
    except FileNotFoundError:
        print("Error: The file '20250813164323_방한 외래관광객 특성(성·연령별).csv' was not found.")
        print("Please ensure the file is in the correct directory or provide the full path.")
    except KeyError as e:
        print(f"KeyError: {e}. Please check the column names in your CSV file.")

    인사이트: 20~30대 방문객 비중이 가장 높음 → 마케팅 타겟 우선순위 확보
     


    (2) 리뷰 기반 예측 모델링

    목적: 리뷰/만족도 데이터 기반으로 관광객 재방문율 예측 모델 구축

    import pandas as pd
    # CSV 불러오기
    file_path = "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164343_방한여행 행태 및 만족도 평가.csv"
    df = pd.read_csv(file_path)
    
    # 데이터 확인 (앞부분 5행, 컬럼명, 기본 통계)
    df_head = df.head()
    df_columns = df.columns.tolist()
    df_info = df.describe(include="all")
    
    df_head, df_columns[:20], len(df_columns)

    import pandas as pd
    from sklearn.model_selection import train_test_split, cross_val_score
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import classification_report, confusion_matrix
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    # 데이터 불러오기
    file_path = "/content/drive/My Drive/데이터분석/외래객방한데이터(한국관광공사)/20250813164343_방한여행 행태 및 만족도 평가.csv"
    df = pd.read_csv(file_path)
    
    # Feature / Target 설정
    X = df[["체재 기간(일)", "1인 평균 지출 경비(USS)", "1일 평균 지출 경비(USS)",
            "전반적 만족도(긍정 응답 비율)", "타인 추천 의향(긍정 응답 비율)"]]
    
    # target: 재방문 의향 → 85% 이상 긍정(1), 미만은 부정(0)
    y = (df["관광목적 재방문 의향(긍정 응답 비율)"] >= 85).astype(int)
    
    # train/test split
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
    
    # 모델 학습
    model = RandomForestClassifier(random_state=42)
    model.fit(X_train, y_train)
    
    # 예측
    y_pred = model.predict(X_test)
    
    # 평가
    print(classification_report(y_test, y_pred))
    
    # 교차 검증
    scores = cross_val_score(model, X, y, cv=5)
    print("교차검증 Accuracy:", scores)
    print("평균 Accuracy:", scores.mean())
    
    # 변수 중요도 시각화
    importances = model.feature_importances_
    feat_imp = pd.Series(importances, index=X.columns).sort_values(ascending=False)
    
    plt.figure(figsize=(8,5))
    sns.barplot(x=feat_imp, y=feat_imp.index)
    plt.title("Feature Importance (재방문 의향 예측)")
    plt.show()


    (3) XGBoost + SHAP 기반 보완 모델

    • SMOTE를 활용해 클래스 불균형 보정
    • XGBoost로 재방문율 예측
    • SHAP을 통해 주요 영향 요인 해석
    import xgboost as xgb
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import accuracy_score, roc_auc_score, classification_report
    from imblearn.over_sampling import SMOTE
    import shap
    import pandas as pd 
    
    # -----------------------------
    # 1. Train / Test Split
    # -----------------------------
    # stratify=y를 사용하여 타겟 변수의 분포를 고려하여 분할
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, stratify=y, random_state=42
    )
    
    # -----------------------------
    # 2. SMOTE로 클래스 불균형 보정
    # -----------------------------
    # 소수 클래스 샘플 수에 맞춰 k_neighbors 값을 줄임
    # 현재 데이터에서는 소수 클래스 샘플이 3개이므로 k_neighbors를 2로 설정
    sm = SMOTE(random_state=42, k_neighbors=2)
    X_train_res, y_train_res = sm.fit_resample(X_train, y_train)
    
    # -----------------------------
    # 3. XGBoost 모델 학습
    # -----------------------------
    xgb_model = xgb.XGBClassifier(
        n_estimators=300,
        learning_rate=0.05,
        max_depth=6,
        subsample=0.8,
        colsample_bytree=0.8,
        random_state=42,
        eval_metric="logloss"
    )
    
    xgb_model.fit(X_train_res, y_train_res)
    
    # -----------------------------
    # 4. 성능 평가
    # -----------------------------
    y_pred = xgb_model.predict(X_test)
    y_prob = xgb_model.predict_proba(X_test)[:,1]
    
    print("Accuracy:", accuracy_score(y_test, y_pred))
    print("ROC-AUC:", roc_auc_score(y_test, y_prob))
    print(classification_report(y_test, y_pred))
    
    # -----------------------------
    # 5. SHAP 값 계산 (모델 설명)
    # -----------------------------
    explainer = shap.TreeExplainer(xgb_model)
    shap_values = explainer.shap_values(X_test)
    
    # Summary Plot (전체 Feature 중요도)
    shap.summary_plot(shap_values, X_test)
    
    # Force Plot (개별 예측 이유 시각화 - 첫 번째 샘플 예시)
    shap.initjs()
    shap.force_plot(explainer.expected_value, shap_values[0,:], X_test.iloc[0,:])


    프로젝트 2주차 예정

    2주차: 심화 분석 & 패턴 발견
     

    • 목표: 시장·고객 특성에 따라 의미 있는 패턴 찾기
    • 프로젝트 진행 순서
      • 연도별 & 카테고리별(성별, 연령, 교통수단, 목적) 세분화 분석
      • 방문객 트렌드와 감성 변화를 동시에 시각화
      • 상관분석 & 시계열 트렌드 분석으로 “시기별 감성-방문객 연결고리” 도출
    • 마케팅 전략에 참고할 고객 세그먼트별 특성 인사이트
Designed by Tistory.