업무에 파이썬 활용할 줄 알기
데이터 분석 종합반 5주차 복습 본문
<복습과정>
복습 내용 | |
월(12/4) | 강의 수강 프로덕트 개선은 정말 도움이 되었을까? 전처리/분석 코드 복습 ㄴ 주차별 컬럼 붙여주기 ㄴ 완주율을 범주화해주기 ㄴ 데이터 병합 ㄴ 컬럼명 변경 groupby, apply, pd.Series.nunique 이해하기 |
화(12/5) | 프로덕트 개선은 정말 도움이 되었을까? 피벗테이블/히트맵 코드 복습 변수 써야하는 경우, 함수만 써도 되는 경우 이해하기 문자포맷팅 방식 이해하기 Pandas at() 이해하기 숙제 / 즉문즉답 문의 |
수(12/6) | concat, merge 차이점 알기 숙제 오류나는 것 이해하기 → for c in range(5,0,-1)로 하면 오류나고, for c in range(5,-1,-1)로 하면 왜 괜찮은지 이해하기 2가지 가설에 대한 데이터에 대해 직접 코드 짜보기 내 기존 분석과정에서 무엇이 가설설정/검증에 해당하는건지 알아보자. 우리는 적절한 타겟에게 판매를 하고 있을까? 코드 복습 |
목(12/7) | 찐한관리를 하면 완주율이 높아질까? 코드 복습 managed = ['TRUE', 'FALSE'] 데이터 수정 왜 하는가 plt.xticks([0,1], labels=["찐한관리 비 신청자", "찐한관리 신청자"]) 코드 이해하기 |
5-1. 5주차 오늘 배운 것
- 분석하는 방법:
- 디테일하게 살펴보고 가설세우는 방법
- 파이썬 코드와 관련하여 새롭게 배운 것:
- 5-6~8번 수업에서 특히 다양한 전처리 케이스를 살펴볼 수 있었던게 가장 좋았다.
- 주차별 컬럼 붙여주기
- 완주율을 범주화 해주기
- 범주화해준 데이터를 기존 데이터에 병합해주기
- 컬럼명 변경하기
- 코호트 분석을 위한 피벗 데이블 만들기
- 코호트 분석을 위한 히트맵 만들기
- 어떤 전처리를 배웠는지 상세
5-2. 데이터 분석 시작하기
완주를 하기까지의 어떤 여정을 거치는지를 상세히 쪼개어보면 볼수록 어디에 문제가 있는지 좀 더 풍부한 가설을 세울 수가 있다
완주를 안하는 진짜 이유가 드러나게 될 것.
왜 이렇게 고객의 여정을 쪼개어 봐야하냐면
문제해결을 위해 가설을 세울 때 어떤 변수가 있을지. 그래서 우리가 어떤 데이터를 봐야되는지를 결정하기 위해서
내가 분석하면서 문제정의를 했던 방법과 유사하다.
아 이번 수업은 내가 몇주동안 고민했던거.. 내가 5년동안 분석했던 내용을 어떻게 정리하고 포트폴리오화 할 것인가에 대해 힌트가 되는 내용이다. 내가 분석흐름을 탔던것과 분명 비슷하고, 그것이 곧 문제해결과정이고, 그걸 어떻게 정리해야할지 감이 잡힌달까..
수업 | SEO 데이터 분석 | |
문제상황 | 8월 중순부터 완주율이 크게 떨어졌다 | 검색엔진 유입트래픽(클릭)이 전년대비 감소했다 |
가설세우기 이전 어떤 변수가 있을지 파악(영향을 주는 요소) | 고객의 입장에서 수업을 듣는 여정 생각해보기 [수강여정] 1. 강의를 들을 수 있는 시간적 여유가 생긴다. ㄴ 포지셔닝에 변화 2. 강의를 들어야겠다고 마음을 먹는다. ㄴ 찐한 관리 3. 강의를 듣기 위해 콘텐츠에 접근한다. ㄴ강의 접근 과정(웹페이지 불편사항, 영상 오류 등) ㄴ확인결과 문제없음 4. 목표한 만큼 강의 컨텐츠를 모두 수강 완료한다. ㄴ 컨텐츠가 재미있고 실용적인지 1,2,4번을 살펴보며 어떤 점을 개선하면 완주율을 높일 수 있을지 가설을 세워 확인 |
클릭이 발생하기까지의 검색여정 [검색여정] |
가설 | 우리는 적절한 타겟에게 판매를 하고 있을까? 가설: 다른 연령대에 비해 바쁜 20~30대의 수강 완주율이 상대적으로 낮을 것이다. 내 생각: 8월중순부터 떨어진 것은 간과된 가설인 것 같다 검증방법: 나이대별 완주율 비교 액션: 프로덕트 개선 및 광고 메인 타겟 변경 |
카테고리별 세부카테고리별 현황 살펴보며 감소 요인으로 보이는 패턴을 찾아나갔던 과정이 곧 가설을 세우는 과정인 것 같다. |
찐한 관리를 하면 완주율이 높아질까? 현황: 최근 3개월간 찐한 관리 신청 비율과 완주율이 모두감소하고 있다. 가설: 찐한 관리를 받은 인원이 그렇지 않은 인원보다 완주율이 높을 것이다. 내 생각: 가설이 뭔가 당연한 이야기를 하는 듯하고, 좀 억지스럽다. 마찬가지로 8월 중순 기간에 대한 포인트는 고려되지 않은 것 같다. 액션: 찐한관리 받은 인원의 완주율이 높으면, 찐한 관리 신청 비율 높이기 찐한관리를 받지 않은 인원의 완주율이 높으면, 다른 동기부여 방법 고안 |
||
프로덕트 개선은 정말 도움이 되었을까? 현황: 8월 2주차 개강반부터 새로 제작된 3주차 콘텐츠를 듣기 시작 가설: 8월 둘째주부터 변경된 3주차 강의의 완주율이 현저히 떨어졌을 것이다. 액션: 문제가 있는 경우, 이전 커리큘럼으로 돌아간다. 문제가 없는 경우, 다른 요인을 찾아본다. |
어떤 가설인지가 좀 헷갈린다
8월부터 완주율이 떨어진 이유에 대한 가설인지
완주율을 높이기 위한 가설인지
일맥상통하는 이야기인가? 완주율이 떨어진 이유가 파악이되면 그부분을 개선하면 완주율이 높아지니까.
위의 고민이 좋은가설의 조건을 이해하게했다.
좋은 가설이란?
1) 풀고자하는 문제의 방향성과 일치하는 가설 → 무슨 문제를 풀고자 하는지 명확히 알 것
2) 테스트 가능한 가설 → 데이터로 확인이 가능한 가설을 세울 것
3) 액션으로 이어질 수 있는 가설 → 가설 검증 후 결과에 따라 특정 액션으로 유도될 수 있을 것
5-3. 우리는 적절한 타겟에게 판매를 하고 있을까?
<복습코드>
#우리는 적절한 타겟에게 판매를 하고 있을까
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic') #한글 깨짐 방지 설정
sparta_data = pd.read_table('/content/sprata_data.csv', sep = ',')
print(sparta_data.head())
#세대별 완주율
#세대별 완주율 테이블구성
#progress_rate의 평균으로 계산을 하던데(이게 이해가 안가긴하지만..)
#groupby할때 avg계산으로 되는건가
#세대별 완주율 합계 계산
progress_rate_sum_by_age = sparta_data.groupby('age')['progress_rate'].sum() #avg는 못쓰나?
print(progress_rate_sum_by_age.head())
#세대별 수강생수 합계 계산
students_by_age = sparta_data.groupby('age')['_id'].count()
print(students_by_age.head())
#divde를 쓰나? 아 단순 나누기로..!
average = progress_rate_sum_by_age / students_by_age
print(average.head())
#바그래프 그리기
#숫자 레이블 나타내는거에 익숙해지기
plt.figure(figsize=(5,5))
plt.xticks([10,20,30,40,50])
bar = plt.bar(average.index, average, width=7)
#x,y축 위치지정, 숫자레이블타나내기, 정렬, 크기
for rect in bar:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width()/2.0, height, '%.1f' % height, ha='center', va='bottom', size=12)
plt.title('[나이대 별 평균 수강율]', fontsize=15, pad=20)
plt.xlabel('나이', fontsize=12, labelpad=20) #labelpad가 뭐야
plt.ylabel('수강생(명)', fontsize=14, rotation=360, labelpad=35)
plt.show()
5-4. 찐한 관리를 하면 완주율이 높아질까? _ 가설 및 전처리
5-5. 찐한 관리를 하면 완주율이 높아질까? _ 분석 및 시각화
<시행착오>
일부러 아무런 서식 적용안해 봄
x축에 true, false로 표기 안 됨
숫자 레이블 표기가 깔끔하지 않음
#찐한 관리를 하면 완주율이 높아질까?
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
sparta_data = pd.read_table('/content/sprata_data.csv', sep=',')
print(sparta_data.head())
sparta_data.head()
#찐한관리수행여부별 완주율
#테이블 구성
#managed에 true, false값 외 다른 값은 없는지 확인하고 싶으면? 값들을 중복제거해서 남기는 작업을 했었는데..!
progress_rate_sum_by_managed = sparta_data.groupby('managed')['progress_rate'].sum()
print(progress_rate_sum_by_managed.head())
students_by_managed = sparta_data.groupby('managed')['_id'].count()
print(students_by_managed.head())
average = progress_rate_sum_by_managed / students_by_managed
print(average.head())
#퍼센티지숫자로 연산을 하는게 안될텐데, 평균을 내는 계산을 이렇게 하는게 맞는지 확인해보자.
#그래프 구성
plt.figure(figsize=(7,7))
bar = plt.bar(average.index, average)
for rect in bar:
height = rect.get_height()
#x,y축 위치지정, 숫자기입
plt.text(rect.get_x() + rect.get_width()/2, height, '%.1f' % height)
plt.show()
<완성 코드>
#찐한 관리를 하면 완주율이 높아질까?
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic') #한글 깨짐 방지 설정
sparta_data = pd.read_table('/content/sprata_data.csv', sep=',')
print(sparta_data.head())
sparta_data.head()
managed= ['TRUE','FALSE'] #데이터 수정하기
#이 작업을 왜 해주는거지? 나중에 그래프 x축 표기에 영향을 미치나..
#이 수정작업을 안거치더라도 groupby 계산은 문제없이 true, false에 대해서 되던데..
#찐한관리수행여부별 완주율
#테이블 구성
#managed에 true, false값 외 다른 값은 없는지 확인하고 싶으면? 값들을 중복제거해서 남기는 작업을 했었는데..!
progress_rate_sum_by_managed = sparta_data.groupby('managed')['progress_rate'].sum()
print(progress_rate_sum_by_managed.head())
students_by_managed = sparta_data.groupby('managed')['_id'].count()
print(students_by_managed.head())
average = progress_rate_sum_by_managed / students_by_managed
print(average.head())
#퍼센티지숫자로 연산을 하는게 안될텐데, 평균을 내는 계산을 이렇게 하는게 맞는지 확인해보자.
#그래프 구성
plt.figure(figsize=(7,7))
bar = plt.bar(average.index, average)
for rect in bar:
height = rect.get_height()
#x,y축 위치지정, 숫자기입
plt.text(rect.get_x() + rect.get_width()/2, height, '%.1f' % height, ha='center', va='bottom', size=12)
plt.title('[찐한관리수행여부별 완주율]', pad=15)
plt.xticks([0,1],labels=["찐한관리 비 신청자", "찐한관리 신청자"], rotation=45)
plt.xlabel('찐한관리 여부', fontsize=12)
plt.ylabel('평균 완주율', fontsize=12, rotation=360, labelpad=30)
plt.show()
<해소하고 싶은 것>
#managed에 true, false값 외 다른 값은 없는지 확인하고 싶으면? 값들을 중복제거해서 남기는 작업을 했었는데..!
ㄴ 3주차 수업에서 df.drop_duplicates(['컬럼명'])
ㄴ 5주차 수업에서 set()
e.g. category_range = set(sparta_data['start_week'])
managed = ['TRUE', 'FALSE'] 데이터 수정 왜 하는가
ㄴ 아무코드에도 영향을 미치지 않는 수업 오류로 답변 받음
plt.xticks([0,1], labels=["찐한관리 비 신청자", "찐한관리 신청자"]) 코드 이해하기
ㄴ 바 2개에 대해 x축 2개로 표기하려고 그냥 [0,1] 로 표기한것으로 이해함
pad, labelpad는 여백(padding)을 지정할 수 있는 파라미터임.
5-6. 프로덕트 개선은 정말 도움이 되었을까? _ 가설
<좋은 가설을 세우기 위해 생각해야 할 것 (질문해야할 것)>
- 우리가 풀어야할 문제는 무엇인가요?
- 8월 중순부터 웹개발 종합반의 완주율이 크게 떨어진 이유를 밝혀야 한다.
- 위 상황에서 알 수 있는 점은 무엇인가요?
- 비슷한 시기에 진행한 프로덕트 개선이 영향을 미쳤을 수도 있다.
- 가설
- 8월 둘째주부터 변경된 3주차 강의의 완주율이 현저히 떨어졌을 것이다
- 가설에 따라 이후 액션이 어떻게 될까요?
- 문제있는 경우: 이전 커리큘럼으로 돌아간다
- 없제없는 경우: 다른 요인을 찾아본다
- 어떤 데이터를 볼 것 인가? (적절한 데이터 검증 방법)
- 8월 2주차 이전 개강반의 각 주차별 완주율 vs. 8월 2주차 이후 개강반의 각 주차별 완주율
- 8월 2주차 이후 개강반의 3주차 수업의 완주율이 8월 2주차 이전 개강반의 완주율과 비교했을 때 급격히 감소했는가? 확인
<코호트 차트란?>
코호트(동질 집단)
특정기간동안 공통된 특성이나 경험을 갖는 사용자 집단
소비자를 시간흐름 이나 서비스 단계로 나누어 같은 성질의 집단으로 구분한 것
코호트 차트
소비자의 전환율을 시간흐름과 서비스 단계와 같은 2가지 요인으로 복합적으로 보여줄 수 있는 차트
<데이터분석> 코호트 분석 파헤치기 · lee. ui dam
<데이터분석> 코호트 분석 파헤치기 18 Apr 2022 | 데이터분석 코호트분석 이번 시리즈에서는 실전 데이터 분석을 다룬다. 주로 SaaS 기업에서 행해지는 널리 알려진 여러 기법들을 소개하고, 실제
ud803.github.io
5-7. 프로덕트 개선은 정말 도움이 되었을까? _ 분석 및 시각화
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic')
sparta_data = pd.read_table('/content/cohort_data.csv', sep = ',')
print(type(sparta_data['created_at'][0]))
#1-1. 날짜타입 변환
format = '%Y.%m.%d'
sparta_data['start_time'] = pd.to_datetime(sparta_data['created_at'],
#format의 역할이 정확히 뭔지 모르겠다.
format=format,
#datetime이 어떤 형식으로 이루어졌는지 확인 후 자동으로 변환해주는 설정을 한 것
infer_datetime_format=True)
#1-2. start_time > 주차 정보 반환
sparta_data['start_week']= sparta_data['start_time'].dt.isocalendar().week
#처음 수강 시작한 주 범위 확인하기
category_range = set(sparta_data['start_week'])
category_range
#1-3. progress_rate > 커리큘럼 번호 반환
#a. 범주화할 데이터 리스트로 만들기
progress_rate = list(sparta_data['progress_rate'])
progress_rate
#b. 범주를 구분하는 기준 및 라벨(수강 주차) 만들기
bins = [0,4.11,26.03,41.10,61.64,80.82,100]
labels = [0,1,2,3,4,5]
#c. 범주화하기: 범주화에 사용하는 함수 pd.cut
#독스트링 보는 방법 확인하기
cuts = pd.cut(progress_rate,
bins,
right=True,
include_lowest=True,
labels=labels)
cuts
#d. 범주화 결과물을 테이블로 변경하기
cuts = pd.DataFrame(cuts)
cuts.tail()
#e. 기존테이블에 현재 수강주차 테이블 합치기
#저번시간에 merge메서드를 썼던것 같은데? 확인해보자
sparta_data = pd.concat([sparta_data, cuts],
axis=1,
join='inner')
sparta_data.head()
#f. 테이블 컬럼 이름 변경하기
sparta_data.columns = ['created_at','user_id','name','progress_rate','start_time','start_week','class_week']
sparta_data.head()
#2-1. 개강반주차별/현재수강주차별 테이블 구성
grouping = sparta_data.groupby(['start_week','class_week'])
#어떻게 묶는건지 잘모르겠음.. 중복제거와 다름없는게 아닌가 싶기도 하고..저 메소드를 썼을 때 정확하게 어떻게 처리되는지도 모르고 쓰는게 찝찝하다
grouping.head()
cohort_data = grouping['user_id'].apply(pd.Series.nunique)
cohort_data = pd.DataFrame(cohort_data)
cohort_data.head(20)
#아래와 같이 적어도 동일한 결과
#cohort_data = sparta_data.groupby(['start_week','class_week'])['user_id'].apply(pd.Series.nunique)
#cohort_data = pd.DataFrame(cohort_data)
#아래와 같이 적어도 동일한 결과
#cohort_data = sparta_data.groupby(['start_week','class_week'])['user_id'].count()
#cohort_data = pd.DataFrame(cohort_data)
#apply()메서드 뭐지?
#pd.Series.nunique? 왜 이렇게 작성하는거지? pd.Series가 지금 뭘 뜻하는거지?
#pd.DataFrame해주기전에는 그럼 어떤 타입이지?
#sparta_data가 이미 dataFrame 타입이고, 그 데이터에서 groupby해준건데 왜 cohort_data는 다시 Series 타입이 되는거지?
#어떤건 pd. 으로 라이브러리 명을 붙여줘야하고, groupby, apply같은 메소드 쓸때는 pd를 안붙여줘도 되고 어떻게 구분하나?
#그냥 내 느낌에 이미 dataframe타입을 가진 데이터에 메서드를 써줄때는 '데이터테이블명.메서드명()' 이렇게 써주는것 같고
#can I write a method only without module name(pd.) after dataframe data table? 즉문즉답에 글 남겨보자
#2-2. 완주한 수강생 총인원 계산
s=31
for i in range(6):
for c in range(5, 0, -1):
cohort_data.at[(s,c-1),'user_id'] = cohort_data.at[(s,c-1),'user_id'] + cohort_data.at[(s,c),'user_id']
s += 1
#at[행, 열]로 작성되는 함수인데, 행부분에 (f, j-1)로 작성이 딘게 단일 인덱스가 아니라 2개의 인덱스라 (f, j-1)형태로 작성할 수 있는건가?
#인덱스 새롭게 설정하기
cohort_data = cohort_data.reset_index()
cohort_data.head(20)
#2-3. 피벗테이블 만들기
cohort_counts = cohort_data.pivot(index = "start_week",
columns = "class_week",
values = "user_id")
cohort_counts
#2-4. 주차별 개강반 전체학생수 계산 > 아 이건 피벗테이블 만든다음이구나
#피벗테이블을 왜 retention 변수에 저장하는거지?
retention = cohort_counts
cohort_sized = cohort_counts.iloc[:,0]
cohort_sized.head()
#2-5. 완주율 계산
retention = cohort_counts.divide(cohort_sized, axis=0)
retention.round(3)*100
#3-1. 히트맵 그리기
#5주차에 그리는 히트맵이 이전주차수업에서의 히트맵과 다른가? 기억이 전혀 안니지 왜?
#코호트테이블? 리텐션테이블?
plt.figure(figsize=(10,8))
sns.heatmap(data = retention,
annot = True, #각 cell의 데이터 표기 유무
fmt = '.0%', #values(데이터의 값) 값의 소수점 표기
vmin = 0, #최소값 설정
vmax = 1, #최댓값 설정
cmap = "BuGn"
)
plt.xlabel('주차', fontsize=14, labelpad=30)
plt.ylabel('개강일',fontsize=14, rotation=360, labelpad=30)
plt.yticks(rotation=360)
plt.show()
2개 테이블 병합 방법 (pd.concat, pd. merge)
<5주차수업에서 pd.concat 예시>
5주차 수업에서 concat을 사용한 이유는
공통 컬럼을 기준으로 합치는 것이 아니라
단순 index기준으로 두 테이블을 합치면 되는거였기 때문
<3주차수업에서 merge 예시>
3주차 수업에서 merge를쓴 이유는 특정컬럼에 대해 값을 붙여주는 거 였기 때문
참고 출처: https://suy379.tistory.com/127
groupby, apply, pd.Series.nunique로 구성된 함수 이해 안되는 것
오마이갓.. 여기서 작성된 코드 전혀 이해가 안간다..
아 그냥 이렇게 이해하자
start_week, class_week 2개 컬럼으로 groupby할건데
groupby할 때는 다른 컬럼에 대해 집계를 어떻게 할건지 정의해줘야하잖아
start_week(반별), class_week(강의주차별) 수강생수를 중복되지 않게 세어줘. 인거임
이것과 다름없는 코드라는 것은 알겠다일단.
왜 그냥 이렇게 하면 안되는거지?
pd.Series.nunique 이해 안되는 것
pd.Series.nunique로 꼭 작성해야하나?
아래와 같이 pd.Series.nunique로 적어야하는구나
아래껀 그냥 메서드만 작성해도 되는데 왜지..
apply 이해하기
Pandas 라이브러리에서 제공하는 함수로 데이터프레임의 열 또는 행에 함수를 적용하기 위해 사용됨
데이터 프레임의 가공을 위해 마련된 함수를 데이터프레임의 각 요소에 적용하고 결과를 반영할 때 사용함
함수 작성 형태 혼란스러운 것
어떨 때 변수에 값을 심어넣어줘야하고, 어떨때 그냥 함수만 쓰면되는지 이해함
https://colab.research.google.com/drive/1K2QcLE0dUJHZScx-dY3mail5y6u1fP58
- 입력값과 결과값이 있는 함수 사용법
- 결과값을 받을 변수 = 함수명(입력 인수1, 입력 인수2, , ,)
- 변수를 써준다
def sum(a,b):
result = a + b
return result
a = sum(3,4) #이렇게
print(a)
#result
7
- 입력값이 없고, 결과값만 있는 함수 사용법
- 결과값을 받을 변수 = 함수명()
- 변수를 써준다
def say():
return 'HI'
a = say() #이렇게
print(a)
#result
Hi
- 입력값이 있고, 결과값이 없는 함수 사용법
- 함수명(입력 인수1, 입력 인수2, , ,)
- 함수만 써준다
def sum(a,b):
print("%d, %d의 합은 %d입니다." % (a, b, a+b))
sum(3,4) #이렇게
%result
3, 4의 합은 7입니다.
- 입력값도 결과값도 없는 함수 사용법
- 함수명()
- 함수만 써준다
def say():
print('Hi')
say() #이렇게
#reslut
Hi
즉문즉답에 물어볼 것
#앞에 다 적어주는 건.. 내장함수라서 그러는 것 같고
데이터테이블 뒤에 함수 작성해줄 때 모듈명을 안적어주는건 잘이해가 안간다.
이미 dataFrame, Series 데이터 유형에다가 적용하는거라 pd. 을 생략하는건가?
구글링했을 때, apply, groupby 이런 함수는 Pandas 모듈의 함수인데 분명.
파이썬 판다스 at 모르겠음
at() 함수를 이용하여 테이블의 하나의 요소에 접근 할 수 있음
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.at.html
pandas.DataFrame.at — pandas 2.1.3 documentation
Access a single value for a row/column pair by integer position.
pandas.pydata.org
<복습 코드>
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic')
sparta_data = pd.read_table('/content/cohort_data.csv', sep = ',')
print(type(sparta_data['created_at'][0]))
#1-1. 날짜타입 변환
format = '%Y.%m.%d'
sparta_data['start_time'] = pd.to_datetime(sparta_data['created_at'],
#format의 역할이 정확히 뭔지 모르겠다.
format=format,
#datetime이 어떤 형식으로 이루어졌는지 확인 후 자동으로 변환해주는 설정을 한 것
infer_datetime_format=True)
#1-2. start_time > 주차 정보 반환
sparta_data['start_week']= sparta_data['start_time'].dt.isocalendar().week
#처음 수강 시작한 주 범위 확인하기
category_range = set(sparta_data['start_week'])
category_range
#1-3. progress_rate > 커리큘럼 번호 반환
#a. 범주화할 데이터 리스트로 만들기
progress_rate = list(sparta_data['progress_rate'])
progress_rate
#b. 범주를 구분하는 기준 및 라벨(수강 주차) 만들기
bins = [0,4.11,26.03,41.10,61.64,80.82,100]
labels = [0,1,2,3,4,5]
#c. 범주화하기: 범주화에 사용하는 함수 pd.cut
#독스트링 보는 방법 확인하기
cuts = pd.cut(progress_rate,
bins,
right=True,
include_lowest=True,
labels=labels)
cuts
#d. 범주화 결과물을 테이블로 변경하기
cuts = pd.DataFrame(cuts)
cuts.tail()
#e. 기존테이블에 현재 수강주차 테이블 합치기
#저번시간에 merge메서드를 썼던것 같은데? 확인해보자
sparta_data = pd.concat([sparta_data, cuts],
axis=1,
join='inner')
sparta_data.head()
#f. 테이블 컬럼 이름 변경하기
sparta_data.columns = ['created_at','user_id','name','progress_rate','start_time','start_week','class_week']
sparta_data.head()
#2-1. 개강반주차별/현재수강주차별 테이블 구성
grouping = sparta_data.groupby(['start_week','class_week'])
#어떻게 묶는건지 잘모르겠음.. 중복제거와 다름없는게 아닌가 싶기도 하고..저 메소드를 썼을 때 정확하게 어떻게 처리되는지도 모르고 쓰는게 찝찝하다
grouping.head()
cohort_data = grouping['user_id'].apply(pd.Series.nunique)
cohort_data = pd.DataFrame(cohort_data)
cohort_data.head(20)
#아래와 같이 적어도 동일한 결과
#cohort_data = sparta_data.groupby(['start_week','class_week'])['user_id'].apply(pd.Series.nunique)
#cohort_data = pd.DataFrame(cohort_data)
#아래와 같이 적어도 동일한 결과
#cohort_data = sparta_data.groupby(['start_week','class_week'])['user_id'].count()
#cohort_data = pd.DataFrame(cohort_data)
#apply()메서드 뭐지?
#pd.Series.nunique? 왜 이렇게 작성하는거지? pd.Series가 지금 뭘 뜻하는거지?
#pd.DataFrame해주기전에는 그럼 어떤 타입이지?
#sparta_data가 이미 dataFrame 타입이고, 그 데이터에서 groupby해준건데 왜 cohort_data는 다시 Series 타입이 되는거지?
#어떤건 pd. 으로 라이브러리 명을 붙여줘야하고, groupby, apply같은 메소드 쓸때는 pd를 안붙여줘도 되고 어떻게 구분하나?
#그냥 내 느낌에 이미 dataframe타입을 가진 데이터에 메서드를 써줄때는 '데이터테이블명.메서드명()' 이렇게 써주는것 같고
#can I write a method only without module name(pd.) after dataframe data table? 즉문즉답에 글 남겨보자
#2-2. 완주한 수강생 총인원 계산
s=31
for i in range(6):
for c in range(5, 0, -1):
cohort_data.at[(s,c-1),'user_id'] = cohort_data.at[(s,c-1),'user_id'] + cohort_data.at[(s,c),'user_id']
s += 1
#at[행, 열]로 작성되는 함수인데, 행부분에 (f, j-1)로 작성이 딘게 단일 인덱스가 아니라 2개의 인덱스라 (f, j-1)형태로 작성할 수 있는건가?
#인덱스 새롭게 설정하기
cohort_data = cohort_data.reset_index()
cohort_data.head(20)
#2-3. 피벗테이블 만들기
cohort_counts = cohort_data.pivot(index = "start_week",
columns = "class_week",
values = "user_id")
cohort_counts
#2-4. 주차별 개강반 전체학생수 계산 > 아 이건 피벗테이블 만든다음이구나
#피벗테이블을 왜 retention 변수에 저장하는거지?
retention = cohort_counts
cohort_sized = cohort_counts.iloc[:,0]
cohort_sized.head()
#2-5. 완주율 계산
retention = cohort_counts.divide(cohort_sized, axis=0)
retention.round(3)*100
#3-1. 히트맵 그리기
#5주차에 그리는 히트맵이 이전주차수업에서의 히트맵과 다른가? 기억이 전혀 안니지 왜?
#코호트테이블? 리텐션테이블?
plt.figure(figsize=(10,8))
sns.heatmap(data = retention,
annot = True, #각 cell의 데이터 표기 유무
fmt = '.0%', #values(데이터의 값) 값의 소수점 표기
vmin = 0, #최소값 설정
vmax = 1, #최댓값 설정
cmap = "BuGn"
)
plt.xlabel('주차', fontsize=14, labelpad=30)
plt.ylabel('개강일',fontsize=14, rotation=360, labelpad=30)
plt.yticks(rotation=360)
plt.show()
5-8. 프로덕트 개선은 정말 도움이 되었을까? _ 잘 보이는 그래프 만들기
5-9. 5주차 끝 & 숙제 설명
각 주차별 완주율을 '(커리큘럼별 완주 수강생수) / (해당주차 개강반 전체학생수)'로 정의하는 것이 최선인지 의문이었는데,
그게 해소되는 주제이다.
기존 완주율 정의로 데이터를 보는 건 0~5주차까지의 리텐션 흐름을 파악하는 숫자로서 더 의미가 있을 것 같았다.
3주차의 커리큘럼에 문제가 있는지를 보려면 직전 커리큘럼의 완주 수강생수를 모수로 계산하는게 더 맞겠다.
(커리큘럼별 완주 수강생수) / (직전 커리큘럼의 완주 수강생수)
#숙제
f=31
for i in range(6):
for c in range(5, 1, -1):
retention.at[f,c] = retention.at[f,c]/retention.at[f,c-1]
f += 1
<시행착오>
아래와 같이 코드 작성하면 왜 안되는걸까. 즉문즉답에 물어보자.
숙제설명에서는 피벗테이블에서 커리큘럼별 전환율을 직전주차 전환율로 나누는 방식을 제안하고 있음.!
<즉문즉답으로 해결한 것>
range 범위 확인하기
range는 마지막 숫자는 포함하지 않는다
<목차>
5-1. 5주차 오늘 배울 것
5-2. 데이터 분석 시작하기
5-3. 우리는 적절한 타겟에게 판매를 하고 있을까?
5-4. 찐한 관리를 하면 완주율이 높아질까? _ 가설 및 전처리
5-5. 찐한 관리를 하면 완주율이 높아질까? _ 분석 및 시각화
5-6. 프로덕트 개선은 정말 도움이 되었을까? _ 가설
5-7. 프로덕트 개선은 정말 도움이 되었을까? _ 분석 및 시각화
5-8. 프로덕트 개선은 정말 도움이 되었을까? _ 잘 보이는 그래프 만들기
5-9. 5주차 끝 & 숙제 설명
'Python > [스파르타] 데이터 분석 종합반' 카테고리의 다른 글
데이터 분석 종합반 4주차 복습 (0) | 2023.12.01 |
---|---|
데이터 분석 종합반 3주차 복습 (0) | 2023.11.29 |
데이터 분석 종합반 2주차 (0) | 2023.11.28 |
데이터 분석 종합반 1주차 복습 (0) | 2023.11.21 |