Graph2) 영업사원의 영업 관련 그래프

1. 시각화 목적:

1) 영업사원의 프로모션이 얼마큼 효과가 있었는지 확인하기 위한 그래프

2) 영업사원이 제시한 상품과 프리젠테이션 만족도 별 상품 신청률을 확인하여 향후 영업과 마케팅에 활용이 가능

2. 시각화 과정 소개:

1) 영업사원과 관련된 feature들만 따로 모아 df 분리
2) 추천 상품별 신청/미신청 건수를 그래프로 그림
3) 추천 제품에 대한 소비자들의 영업 만족도를 구분하여 신청률을 그래프로 표현
4) 평균선을 추가하여 전체 평균과 비교 가능하도록 표현

3. 피드백:

1) 색깔이랑 스타일 등이 조금 더 심미적인 그래프가 되도록 그릴 필요가 있음

Graph2-1) 추천 상품별 신청/미신청(ProdTaken) 건수

 
# 영업사원과 관련된 컬럼만 가져와 df 분리
pitch_list = ['DurationOfPitch', 'NumberOfFollowups', 'ProductPitched', 'PitchSatisfactionScore', 'ProdTaken']
pitch_df = df[pitch_list]
pitch_df.head(3)
 
plt.figure(figsize=(8,6))
sns.countplot(x="ProductPitched", hue="ProdTaken", data=pitch_df)
plt.title('<추천 상품별 신청/미신청 건수>')
plt.show()

Graph2-2) 상품의 프리젠테이션 만족도별 신청률

pd.DataFrame(pitch_df.groupby(['ProductPitched', 'PitchSatisfactionScore'])['ProdTaken'].mean().unstack())
# pd.DataFrame(pitch_df.pivot_table('ProdTaken', index = 'ProductPitched', columns = 'PitchSatisfactionScore'))
 

#평균선을 그리기 위한 평균값 구하기
mean_taken = np.round(pitch_df['ProdTaken'].mean(), 3)

plt.figure(figsize=(12,6))
sns.catplot(x = 'ProductPitched', hue = 'PitchSatisfactionScore', legend=False,
            y = 'ProdTaken', kind= 'bar', data = pitch_df, height = 7, aspect=2)

plt.axhline(mean_taken, label='평균', linestyle = '--', linewidth = 3, color = 'r') ## 평균값을 y좌표로 하는 수평선 생성
plt.text(4, mean_taken + 0.01, f'평균값 : {mean_taken}', fontsize=25, fontweight = 'semibold') ## 평균에 대한 텍스트 출력

plt.legend(title='PitchSatisfactionScore', loc='upper right', fontsize = 15)
plt.xlabel('추천 상품', fontsize=16);
plt.ylabel('신청률', fontsize=16);
plt.title('<추천 상품 & 만족도 별 신청률>', fontsize=20)
plt.tick_params(axis='both', which='major', labelsize=14)
plt.show()

Graph3) 연령대별 패키지 여행 신청(ProdTaken) 비율

1. 시각화 목적:

1) 각 연령대별로 패키지 여행을 얼마나 신청했는지 그 비율을 그래프로 표현

2) 신청율이 떨어지는 연령대에 대해 추가적인 마케팅과 영업을 통해 성공율을 높일 수 있을 것으로 기대

2. 시각화 과정 소개:

1) '연령대(Ageband)'와 '신청 여부('ProdTaken)'간 cross_tab_prop 테이블 생성

2) 테이블을 horizontal bar plot으로 전체 100% 기준 비율 그래프로 변환
3) 그래프의 각 비율에 몇 퍼센트인지 텍스트를 첨가

3. 피드백:

1) 'ProdTaken'에서 0은 미신청이고 1이 신청인데 그래프를 보게 되면 0에 색깔이 부여되어 미신청이 마치 신청인 것처럼 보이게 됨

2) 0과 1의 순서를 바꾸어 줄 필요가 있음

cross_tab = pd.crosstab(index=df['Ageband'],
                        columns=df['ProdTaken'],
                        normalize= False)

cross_tab_prop = pd.crosstab(index=df['Ageband'],
                             columns=df['ProdTaken'],
                             normalize= 'index')
cross_tab_prop
 
cross_tab_prop.plot(kind='barh', 
                        stacked=True, 
                        colormap='Pastel1', 
                        figsize=(10, 6))

plt.legend(loc="lower right", ncol=3)
plt.ylabel("연령", fontsize= 'large')
plt.xlabel("신청 비율", fontsize= 'large')
plt.title('<연령대별 신청율 차이>', fontsize= 'xx-large', fontweight= 'bold')


for n, x in enumerate([*cross_tab.index.values]):
    for (proportion, count, y_loc) in zip(cross_tab_prop.loc[x],
                                          cross_tab.loc[x],
                                          cross_tab_prop.loc[x].cumsum()):
                
        plt.text(x=(y_loc - proportion) + (proportion * 1/4),
                 y=n - 0.11,
                 s=f'{count} ({np.round(proportion * 100, 1)}%)', 
                 color="Black",
                 fontsize=10,
                 fontweight="normal")

plt.show()

ㄴㅇㄹㄴㅇㄹ

info) 정규세션 2주차 Tourism 데이터 시각화

Tourism 데이터를 활용하여 시각화 그래프 그리기


1. 초기 환경설정 

from IPython.core.display import display, HTML
display(HTML("<style>.container {width:80% !important;}</style>"))
%matplotlib inline

import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy import stats
import warnings
warnings.filterwarnings('ignore')

mpl.rcParams['figure.figsize'] = (12,8)  #시각화 figure default 설정
mpl.rcParams['font.family'] = 'NanumGothic' #폰트 디폴트 설정
mpl.rcParams['font.size'] = 10    #폰트 사이즈 디폴트 설정
plt.rcParams['axes.unicode_minus'] = False
%config InlineBackend.figure_format='retina' # 그래프 글씨 뚜렷

2. Tourism 데이터 로드

import pandas as pd
import numpy as np

df = pd.read_csv('./tourism.csv')
df.head(3)

공간 상 일부 컬럼 생략되었습니다


3. 데이터 전처리

3.1 Gender의 'Fe Male' 오기 수정

# 오타가 발생한 'Fe Male'을 'Female'로 수정
df['Gender'].replace('Fe Male', 'Female', inplace=True)

# 수정된 결과 확인
df['Gender'].unique()

3.2 'Age' 결측치 처리

# 성별 나이 중앙값
male_median_age = df.loc[df['Gender'] == 'Male', 'Age'].median() #남자의 나이 중앙값
female_median_age = df.loc[df['Gender'] == 'Female', 'Age'].median() #여자의 나이 중앙값

print('남성 나이 중앙값: ', male_median_age, '여성 나이 중앙값: ', female_median_age)
# Age의 결측치를 중앙값으로 대치
median_age = df['Age'].median()
df['Age'].fillna(median_age, inplace = True)

# Age 값들 확인
df['Age'].unique()
 
array([28., 34., 45., 29., 42., 32., 43., 36., 35., 31., 49., 52., 33.,
       22., 50., 23., 41., 37., 40., 56., 54., 39., 20., 46., 27., 38.,
       25., 26., 24., 30., 21., 51., 47., 55., 44., 53., 48., 18., 57.,
       60., 59., 19., 58., 61.])

3.3 연령대(Ageband) 파생변수 생성

# 연령대를 반환하는 ageband() 정의
def ageband(x):
    if x < 10:
        return '10세 이하'
    elif x < 20:
        return '10대'
    elif x < 30:
        return '20대'    
    elif x < 40:
        return '30대'
    elif x < 50:
        return '40대'
    elif x < 60:
        return '50대'
    elif x < 70:
        return '70대'
    else:
        return '80대 이상'
df['Ageband'] = df['Age'].apply(lambda x: ageband(x)) 

4. 그래프 그리기

Graph1) EDA 그래프

1. 시각화 목적:

1) 전반적인 데이터의 상황을 한눈에 확인하기 위한 목적
2) 개괄적으로 데이터를 살핀 후 필요에 따라 drill-down하여 세부적으로 확인 가능

2. 시각화 과정 소개:

1) 범주형 변수 연속형 변수를 분리하여 따로 그래프를 그림
2) subplots를 통해 한번에 여러 그래프를 확인할 수 있도록 함
3) 색상은 구매선택과 미선택 사이에 극명한 차이를 둘 수 있도록 대조되는 컬러 사용
4) 연속형 변수에 대한 그래프의 경우, kde(커널 밀도 추청) 그래프를 추가하여 히스토그램에 대한 확률밀도함수를 추정하여 정밀 표현

3. 피드백:

1) 색상 지정에서 hue의 각 변수에 대해 새상을 따로 지정할 수 있는지 확인이 필

2) 가령, 0(미선택)에 대해 부정을 의미하는 빨간색, 1(선택)에 대해 긍정을 의미하는 파란색 부여가 가능한지

Graph1-1) 카테고리형 변수별 상품 신청률(ProdTaken)
 
#카테고리 변수만 따로 리스트로 분리하고 개수 출력
categorical_list = ['TypeofContact', 'CityTier', 'Occupation', 'Gender', 'NumberOfPersonVisiting', 'PreferredPropertyStar', 'MaritalStatus',
       'NumberOfTrips', 'OwnCar','NumberOfChildrenVisiting', 'Designation']
print('카테고리 변수 개수: ', len(categorical_list))

#subplot으로 11개의 변수를 한번에 표시
fig, axes = plt.subplots(3, 4, figsize = (24, 24))

for idx, cat in enumerate(categorical_list):
    row = idx // 4
    col = idx % 4
    sns.countplot(x = cat, hue = "ProdTaken", palette = 'deep', data=df, ax=axes[row][col])
    
plt.tight_layout()
plt.show()

Graph1-2) 연속형 변수별 신청률(ProdTaken)

#연속형 변수만 따로 리스트로 분리하고 개수 출력
continuous_list = ['Age', 'DurationOfPitch', 'MonthlyIncome']
print('연속형 변수 개수: ', len(continuous_list))

#subplot으로 11개의 변수를 한번에 표시
fig, axes = plt.subplots(1, 3, figsize = (12, 6), squeeze=False)

for idx, con in enumerate(continuous_list):
    row = idx // 4
    col = idx % 4
    sns.histplot(data=df, x=con, hue="ProdTaken", palette = 'Set1', kde= True, multiple='stack', ax=axes[row][col])
    
plt.tight_layout()
plt.show()

 

 

'Text Analysis' 카테고리의 다른 글

[Text Mining] LSTM, Seq2Seq  (0) 2023.03.14
[Text Mining] Language Model, RNN  (0) 2023.03.14
[Text Mining] Word Embedding, Word2Vec  (0) 2022.11.18
[Text Mining] Frequency Analysis  (0) 2022.09.19
[Text Mining] Tokenizing  (0) 2022.09.17

'Text Analysis' 카테고리의 다른 글

[Text Mining] LSTM, Seq2Seq  (0) 2023.03.14
[Text Mining] Language Model, RNN  (0) 2023.03.14
[Text Mining] CBOW, Skip-gram, Word2Vec 속도 개선  (0) 2022.11.18
[Text Mining] Frequency Analysis  (0) 2022.09.19
[Text Mining] Tokenizing  (0) 2022.09.17

info) 서브세션 3주차


[문제 1] While문을 활용하여 달러, 원화, 유로의 환산표를 만드는 프로그램을 작성하시오.

참조) • 1$당 환율 : 1443원(원화), 1.02€(유로)

from IPython.display import Image
Image("screenshot.png", width = 300)

[풀이]

import numpy as np

print("-" * 30)
print("달러($)  원화(원)  유로(€)")
print("-" * 30)
d = 10
while d <= 100:
    print("{}       {}        {}".format(d, d*1440, np.round((d*1.02), 1)))
    d = d + 10
print("-" * 30)

[문제2] 세 정수를 입력받아 중앙값을 리턴하는 함수를 작성하시오.

median3(a, b, c)

[풀이1]

def median3(a, b, c):
    num_list = []
    num_list.append(a)
    num_list.append(b)
    num_list.append(c)
    num_list.sort()
    result = num_list[1]
    return result
median3(245, 23, 198)

[풀이2]

def median(a, b, c):
    if a >= b:
        if b >= c:
            return b
        elif a <= c:
            return a
        else:
            return c
    elif a >= c:
        return a
    elif b <= c:
        return b
    else:
        return c
median(9, 7, 8)

[문제3] 리스트내에서 중앙값을 리턴하는 함수를 작성하시오.

median_list(num_list)

< 검증 데이터 >

even_len = [8, 46, 9, 83, 20, 37, 3, 43, 19, 96]
odd_len = [49, 5, 67, 39, 61, 92, 71, 57, 58, 2, 89]

median_list(even_len) 결과 ⇒ 28.5
medain_list(odd_len) 결과 ⇒ 58

[풀이]

def median_list(num_list):
    num_list.sort()
    if len(num_list) % 2 == 0:
        result = (num_list[len(num_list) // 2] + num_list[(len(num_list) // 2) - 1]) / 2
    else:
        result = num_list[len(num_list) // 2]
    return result
even_len = [8, 46, 9, 83, 20, 37, 3, 43, 19, 96]
odd_len = [49, 5, 67, 39, 61, 92, 71, 57, 58, 2, 89]

print("np.median() 사용: ", np.median(even_len))
print("median_list() 사용: ", median_list(even_len))
print("")
print("np.median() 사용: ", np.median(odd_len))
print("median_list() 사용: ", median_list(odd_len))

[문제4] 문자열의 위치를 바꾸는 함수를 작성하시오. 조건은 다음과 같습니다.

shiftStringLeft(string)

return 값 : 문자열에 속한 글자의 위치가 다음처럼 변경된 새로운 문자열 하나

  • 입력 파라메타로 받은 문자열의 맨 왼쪽의 글자는 새로운 문자열에서 맨 오른쪽으로 이동함
  • 입력 파라메타로 받은 문자열 중 맨 왼쪽의 글자가 아닌 경우는, 왼쪽으로 한칸씩 이동함
  • 예를 들어, 입력파라메타로 ‘ABCDEF’를 받으면, return 값은 ‘BCDEFA’임
def shiftStringLeft(string):
    new_string = ''
    for i in range(1, len(string)):
        new_string += string[i]
    new_string += string[0]
    return new_string        
string = 'ABCDE'
shiftStringLeft(string)
 

[문제5] 리스트 내에서 최대값을 반환하는 함수를 작성하시오.

num_max(num_list)

단, max(), np.max() 등의 함수를 사용하는 것이 아니며, 제어문으로 작성해야 합니다.

[풀이 1]

def num_max(num_list):
    max = num_list[0]
    for num in num_list:
        if max < num:
            max = num
    return max
num_list = [2,3,6,107,24,53,44,3,7,8,1]
num_max(num_list)
 
 

[풀이 2]

def num_max1(num_list):
    max = num_list[0]
    idx = 1
    while idx <= (len(num_list)-1):
        if max >= num_list[idx]:
            max
        else:
            max = num_list[idx]
        idx += 1
    return max
num_list = [2,3,6,107,24,53,44,3,70,8,1]
num_max1(num_list)
 

[문제6] 리스트의 길이를 반환하는 함수를 작성하시오.

length(num_list)

단, len() 등의 함수를 사용하는 것이 아니며, 제어문으로 작성해야 합니다.

def length(num_list):
    count = 0
    for i in num_list:
        count += 1
    return count
num_list = [2,3,6,7,24,543,2342,3,7,8,1]
print("len() 사용: ", len(num_list))
print("length() 사용: ", length(num_list))

'BACS > 서브세션' 카테고리의 다른 글

[BACS] 서브세션 2주차  (0) 2022.10.01
[BACS] 서브세션 1주차  (0) 2022.09.27

+ Recent posts