Home DACON 여행 상품 분석 시각화 경진대회
Post
Cancel

DACON 여행 상품 분석 시각화 경진대회

DACON Basic 여행 상품 분석 시각화 경진대회

단순히 EDA와 시각화를 진행하는건데 가설 설정이 너무 어려운거 같다..
많은 시간을 두고 진행했지만 딱히 떠오르는게 없어서 스터디에서 다른 사람들이 해오는걸 보고 내용을 추가해봐야할꺼 같다

라이브러리

1
2
3
4
5
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import koreanize_matplotlib

Data Load

1
2
3
df = pd.read_csv("./train.csv")

df.head()
idAgeTypeofContactCityTierDurationOfPitchOccupationGenderNumberOfPersonVisitingNumberOfFollowupsProductPitchedPreferredPropertyStarMaritalStatusNumberOfTripsPassportPitchSatisfactionScoreOwnCarNumberOfChildrenVisitingDesignationMonthlyIncomeProdTaken
0128.0Company Invited110.0Small BusinessMale34.0Basic3.0Married3.00101.0Executive20384.00
1234.0Self Enquiry3NaNSmall BusinessFemale24.0Deluxe4.0Single1.01510.0Manager19599.01
2345.0Company Invited1NaNSalariedMale23.0Deluxe4.0Married2.00410.0ManagerNaN0
3429.0Company Invited17.0Small BusinessMale35.0Basic4.0Married3.00401.0Executive21274.01
4542.0Self Enquiry36.0SalariedMale23.0Deluxe3.0Divorced2.00310.0Manager19907.00
  • id : 샘플 아이디
  • Age : 나이
  • TypeofContact : 고객의 제품 인지 방법 (회사의 홍보 or 스스로 검색)
  • CityTier : 주거 중인 도시의 등급. (인구, 시설, 생활 수준 기준) (1등급 > 2등급 > 3등급)
  • DurationOfPitch : 영업 사원이 고객에게 제공하는 프레젠테이션 기간
  • Occupation : 직업
  • Gender : 성별
  • NumberOfPersonVisiting : 고객과 함께 여행을 계획 중인 총 인원
  • NumberOfFollowups : 영업 사원의 프레젠테이션 후 이루어진 후속 조치 수
  • ProductPitched : 영업 사원이 제시한 상품
  • PreferredPropertyStar : 선호 호텔 숙박업소 등급
  • MaritalStatus : 결혼여부
  • NumberOfTrips : 평균 연간 여행 횟수
  • Passport : 여권 보유 여부 (0: 없음, 1: 있음)
  • PitchSatisfactionScore : 영업 사원의 프레젠테이션 만족도
  • OwnCar : 자동차 보유 여부 (0: 없음, 1: 있음)
  • NumberOfChildrenVisiting : 함께 여행을 계획 중인 5세 미만의 어린이 수
  • Designation : (직업의) 직급
  • MonthlyIncome : 월 급여
  • ProdTaken : 여행 패키지 신청 여부 (0: 신청 안 함, 1: 신청함)

id는 버림

1
df.drop(columns=["id"], inplace=True)

결측치 확인

1
2
3
plt.figure(figsize=(12, 7))
sns.heatmap(df.isna())
plt.show()

png

시각화가 목적이므로 결측치는 모두 버림

1
df.dropna(inplace=True)

Age: 나이

1
2
3
plt.figure(figsize=(15, 5))
sns.countplot(data=df, x="Age")
plt.show()

png

Band Age

예측이나 분류에서는 주어진 데이터의 분포에 맞춰 정제하는 것이 좋은 성능의 모델을 만드는데 도움이 된다고 하지만, 시각화가 목표이므로 분포는 무시하고 일반적인 분포로 나눔

1
df["Band Age"] = df["Age"].map(lambda x: str(x)[0]+"0대")
1
2
3
4
5
6
plt.figure(figsize=(10, 5))
plt.subplot(221)
sns.countplot(data=df, y="Band Age", order=df["Band Age"].value_counts().index)
plt.subplot(222)
plt.pie(df["Band Age"].value_counts().values, labels=df["Band Age"].value_counts().index, autopct="%.2f%%")
plt.show()

png

TypeofContact: 인지 방법

1
2
3
4
5
6
plt.figure(figsize=(12, 7))
plt.subplot(221)
sns.countplot(data=df, x="TypeofContact")
plt.subplot(222)
plt.pie(df["TypeofContact"].value_counts().values, labels=df["TypeofContact"].value_counts().index, autopct="%.2f%%")
plt.show()

png

CityTier: 주거 중인 도시 등급

1
sns.countplot(data=df, x="CityTier");

png

DurationOfPitch: 고객에게 제공하는 프레젠테이션 기간

1
2
plt.figure(figsize=(15, 4))
sns.countplot(data=df, x="DurationOfPitch");

png

Gender: 성별

Fe MaleFemale은 같은 것 아닌가..?

1
df["Gender"] = df["Gender"].str.replace("Fe Male", "Female")
1
sns.countplot(data=df, x="Gender");

png

NumberOfPersonVisiting: 고객과 함께 여행을 계획 중인 총 인원

1
sns.countplot(data=df, x="NumberOfPersonVisiting");

png

NumberOfFollowups: 영업 사원의 프레젠테이션 후 이루어진 후속 조치 수

정확히 의미하는게 뭔지 모르겠음

1
sns.countplot(data=df, x="NumberOfFollowups");

png

ProductPitched: 영업 사원이 제시한 상품

1
2
3
4
5
6
plt.figure(figsize=(12, 7), facecolor="white")
plt.subplot(221)
plt.pie(df["ProductPitched"].value_counts().values, labels=df["ProductPitched"].value_counts().index, autopct="%.2f%%")
plt.subplot(222)
sns.countplot(data=df, x="ProductPitched")
plt.show()

png

PreferredPropertyStar: 선호 호텔 숙박업소 등급

1
2
3
4
5
6
plt.figure(figsize=(12, 7), facecolor="white")
plt.subplot(221)
plt.pie(df["PreferredPropertyStar"].value_counts().values, labels=df["PreferredPropertyStar"].value_counts().index, autopct="%.2f%%")
plt.subplot(222)
sns.countplot(data=df, x="PreferredPropertyStar")
plt.show()

png

MaritalStatus: 결혼여부

1
2
3
4
5
6
plt.figure(figsize=(12, 7))
plt.subplot(221)
plt.pie(df["MaritalStatus"].value_counts().values, labels=df["MaritalStatus"].value_counts().index, autopct="%.2f%%")
plt.subplot(222)
sns.countplot(data=df, y="MaritalStatus")
plt.show()

png

NumberOfTrips: 평균 연간 여행 횟수

1
sns.countplot(data=df, x="NumberOfTrips");

png

Passport: 여권 보유 여부 (0: 없음, 1: 있음)

1
sns.countplot(data=df, x="Passport");

png

PitchSatisfactionScore : 영업 사원의 프레젠테이션 만족도

1
2
3
4
5
6
plt.figure(figsize=(12, 7))
plt.subplot(221)
plt.pie(df["PitchSatisfactionScore"].value_counts().values, labels=df["PitchSatisfactionScore"].value_counts().index, autopct="%.2f%%")
plt.subplot(222)
sns.countplot(data=df, y="PitchSatisfactionScore")
plt.show()

png

OwnCar: 자동차 보유 여부 (0: 없음, 1: 있음)

1
sns.countplot(data=df, x="OwnCar");

png

NumberOfChildrenVisiting: 함께 여행을 계획 중인 5세 미만의 어린이 수

1
sns.countplot(data=df, y="NumberOfChildrenVisiting");

png

Designation: (직업의) 직급

1
2
3
4
5
6
plt.figure(figsize=(12, 7))
plt.subplot(221)
plt.pie(df["Designation"].value_counts().values, labels=df["Designation"].value_counts().index, autopct="%.2f%%")
plt.subplot(222)
sns.countplot(data=df, x="Designation")
plt.show()

png

MonthlyIncome: 월 급여

1
sns.scatterplot(data=df, x="Designation", y="MonthlyIncome");

png

상관 관계로 본 시각화

1
df.drop(columns=["id"]).corr(method="pearson").style.background_gradient()
 AgeCityTierDurationOfPitchNumberOfPersonVisitingNumberOfFollowupsPreferredPropertyStarNumberOfTripsPassportPitchSatisfactionScoreOwnCarNumberOfChildrenVisitingMonthlyIncomeProdTaken
Age1.0000000.0078750.0257790.0107950.009834-0.0267890.1781430.0301620.0328600.0602980.0394950.440733-0.135832
CityTier0.0078751.0000000.0560100.0180710.023532-0.011882-0.0208870.013665-0.0281680.0141770.0253590.0577050.085583
DurationOfPitch0.0257790.0560101.0000000.0962680.039485-0.0044480.0222360.0434780.011926-0.0150870.0477700.0160110.072899
NumberOfPersonVisiting0.0107950.0180710.0962681.0000000.3337380.0170570.2148950.023638-0.0129810.0185450.6101930.1687010.006483
NumberOfFollowups0.0098340.0235320.0394850.3337381.000000-0.0491510.135183-0.005332-0.0071950.0519200.2939420.1946680.105038
PreferredPropertyStar-0.026789-0.011882-0.0044480.017057-0.0491511.0000000.0350640.014701-0.0196200.0313550.027038-0.0243380.114923
NumberOfTrips0.178143-0.0208870.0222360.2148950.1351830.0350641.0000000.0044180.0348160.0059820.1895170.1370930.044922
Passport0.0301620.0136650.0434780.023638-0.0053320.0147010.0044181.0000000.018526-0.0451330.0305120.0170440.293726
PitchSatisfactionScore0.032860-0.0281680.011926-0.012981-0.007195-0.0196200.0348160.0185261.0000000.0730970.023842-0.0054970.067736
OwnCar0.0602980.014177-0.0150870.0185450.0519200.0313550.005982-0.0451330.0730971.0000000.0364160.109662-0.040465
NumberOfChildrenVisiting0.0394950.0253590.0477700.6101930.2939420.0270380.1895170.0305120.0238420.0364161.0000000.1792550.006060
MonthlyIncome0.4407330.0577050.0160110.1687010.194668-0.0243380.1370930.017044-0.0054970.1096620.1792551.000000-0.140617
ProdTaken-0.1358320.0855830.0728990.0064830.1050380.1149230.0449220.2937260.067736-0.0404650.006060-0.1406171.000000

상관 계수의 경우,

  • 0.8 <= r : 강한 상관
  • 0.6 <= r < 0.8 : 상관
  • 0.4 <= r < 0.6 : 약한 상관
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
corr = pd.DataFrame(df.drop(columns=["id", "ProdTaken"]).corr(method="pearson"))

plt.figure(figsize=(12, 5))

mask = np.zeros_like(corr, dtype=np.bool_)
mask[np.triu_indices_from(mask)] = True
sns.heatmap(corr,
            cmap="RdYlBu_r",
            annot=True,
            mask=mask,
            linewidths=.5,
            cbar_kws={"shrink": .5},
            vmin=-1,
            vmax=1
);

png

가설 설정

  1. 중장년층의 급여가 높을것이다 (Age-MonthlyIncome)
  2. 총 여행 인원이 많은 경우는 아이가 많은 경우일 것이다 (NumberOfPersonVisiting-NumberOfChildrenVisiting)
[가설] 중장년층의 급여가 높을 것이다
1
sns.scatterplot(data=df, x="Age", y="MonthlyIncome");

png

30대 후반부터 임금이 증가해 비슷한 추이를 갖는 모습을 볼 수 있음

[가설] 총 여행 인원이 많은 경우는 아이가 많은 경우일 것이다
1
sns.scatterplot(data=df, x="NumberOfChildrenVisiting", y="NumberOfPersonVisiting");

png

This post is licensed under CC BY 4.0 by the author.

[TF로 정리하는 DL] 6-1. 텍스트 데이터 다루기

[TF로 정리하는 DL] 6-2. RNN, LSTM, GRU

Comments powered by Disqus.