내일배움캠프

[본캠프] 데이터기반 QA/QC 부트캠프 5일차

min0jun 2026. 5. 15. 20:47

1. 오늘 학습 목표

- 데이터 분석으로 기획서 뽀개기 2 (문제에 대한 가설을 직접 세워보고 그걸 검증하는 연습)

 

2. 오늘 학습 한 내용

📚 문제에 대한 가설을 직접 세워보고 검증하는 연습을 해보자.

💡 김르탄 팀장 🧑🏻‍💻:

“스파르타코딩클럽에서 수강 완주율은

좋은 컨텐츠 제공 여부 및 수강생 관리가 잘 되어 가고 있는지에 대한 가장 중요한 지표 입니다.

그런데 지난 8월 중순 부터 웹개발 종합반의 완주율이 크게 떨어졌습니다.”

이번 주는 무엇이 수강생들의 완주율에 가장 큰 영향을 미쳤는지 함께 고민 해 보고 개선해 봅시다.

 

데이터 분석 기본 세팅 순서

  1. pandas 사용 선언하기
  2. 데이터 가져오기
  3. 데이터 살펴보기
  4. 분석에 필요한 데이터 가공하기
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic') #한글 깨짐 방지 설정

sparta_data = pd.read_csv('파일경로') #분석할 데이터 불러오기

#마지막 5개의 데이터 확인 하기
sparta_data.tail()

 

  • 배경 확인 및 가설 세우기
    - 광고 메인 타겟은 2~30대이다
    - 이번에 완주 후 퀴즈를 제출하는 이벤트에서 2~30대의 참여율이 저조했다
    = 다른 연령대에 비해 바쁜 2~30대의 수강 완주율이 상대적으로 낮을 것이다.

 

  • 데이터 분석하기

#나이대별로 수강률 합 구하기
progress_rate_by_age = sparta_data.groupby('age')['progress_rate'].sum()
progress_rate_by_age

#나이대별 수강인원 구하기
number_people_by_age = sparta_data.groupby('age')['_id'].count()
number_people_by_age

#나이대별 완주율 평균 구하기
average = progress_rate_by_age/number_people_by_age
average

#plt.figure(width, height) : 넓이와 높이 만큼 이미지를 생성한다는 것을 말해줍니다!
plt.figure(figsize=(6,6))

#그래프의 x축 눈금 설정
plt.xticks([10,20,30,40,50])

#plt.bar(X축값, Y축값)
plt.bar(average.index, average,width=8)


#그래프의 바에 각 수치율을 추가 해 볼까요?
bar = plt.bar(average.index, average,width=8)
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)

#그래프의 x축 라벨 이름
plt.xlabel('나이',fontsize=12,labelpad=20)

#그래프의 y축 라벨 이름
plt.ylabel('수강생(명)',fontsize=14,rotation=360,labelpad=35)

#그래프를 화면에 나타나도록 합니다.
plt.show()

  • 결론
    2~30대가 비교적 완주율이 적을 것이라는 가설을 세웠지만 실제론 다른 나이대와 비슷하다는 것을 확인함

 

Tip. 좋은 가설이란?
풀고자 하는 문제의 방향성과 일치하는 가설, 테스트 가능한 가설, 액션으로 이어질 수 있는가설

 

3. 오늘의 과제 - 코호트차트 만들어서 문제점 찾기

문제 1. 직전 주차가 분모인 경우로 코호트 차트를 시각화해주세요!

#라이브러리 불러오기
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=',')
sparta_data.tail()

#날짜 데이터 타입 변경
sparta_data['start_time'] = pd.to_datetime(sparta_data['created_at'], errors='coerce')
sparta_data.tail()

#시작 week 구하기
sparta_data['start_week']= sparta_data['start_time'].dt.isocalendar().week
sparta_data.tail()

#시작 주 범위 알기
category_range = set(sparta_data['start_week'])
category_range

# 범주화 하기
#번주화할 데이터
progress_rate = list(sparta_data['progress_rate'])
progress_rate

#범주를 구분하는 기준 bins
bins = [0,4.11,26.03,41.10,61.64,80.82,100]

#구분한 범주의 라벨 labels
labes=[0,1,2,3,4,5]

#범주화에 사용하는 함수 pd.cut
cuts = pd.cut(progress_rate,bins, right=True,include_lowest=True, labels=labes)
cuts
cuts = pd.DataFrame(cuts)
cuts.tail()


# 표 합치기
sparta_data = pd.concat([sparta_data,cuts],axis=1, join='inner')
sparta_data.head()

#표 인덱스 변경하기
sparta_data.columns=['created_at','user_id','name','progress_rate','start_time','start_week',"week"]
sparta_data.head()

#시작주와, 수강 주차별 기준으로 표 grouping 하기
grouping = sparta_data.groupby(['start_week','week'])
grouping.head()

#시작주와, 수강 주차별에 해당하는 수강생 수 구하기
cohort_data = grouping['user_id'].apply(pd.Series.nunique)
cohort_data = pd.DataFrame(cohort_data)
cohort_data.head(10)

#각 주차별 수강한 수강생 총 합 구하기
k=31
for i in range(6):
  for j in range(5, 0, -1):
    cohort_data.at[(k,j-1), 'user_id'] = int(cohort_data.at[(k,j),'user_id']) +  int(cohort_data.at[(k,j-1),'user_id'])
  k=k+1
cohort_data = cohort_data.reset_index()
cohort_data.head()


cohort_counts = cohort_data.pivot(index="start_week",
                                  columns="week",
                                  values="user_id")
cohort_counts

# 앞서 만든 피벗 테이블을 retention 변수에 저장하기
retention = cohort_counts
#각 주(week) 별 최초 수강생 수만 가져오기
cohort_sizes = cohort_counts.iloc[:,0]
cohort_sizes.head()

# 최초 수강생 수를 각 데이터에 나눠주기
retention = cohort_counts.divide(cohort_sizes, axis=0)
retention

#각 수치 퍼센트로 변경하기
retention.round(3)*100

#주차별 수강 전환율 구하기
w=31
for i in range(6):
  for j in range(1, 6):
	  if retention.at[(w, j - 1)] != 0:
		  retention.at[(2, j)] = retention.at[(w, j)] / retention.at[(w, j- 1)]
  w=w+1


retention

#주차별 수강 전환율 히트맵
plt.figure(figsize=(10,8))

sns.heatmap(data=retention,
           annot=True,
           fmt='.0%',
           vmin=0,
           vmax=1,
           cmap="BuGn")



plt.title('개강일별 주차 간 전환율', fontsize=20)
plt.xlabel('주차', fontsize=14,labelpad=30)
plt.ylabel('개강일', fontsize=14,rotation=360,labelpad=30)
plt.yticks(rotation=360)

plt.show()

 

 

 

 

나의 간단 소감

- 확실히 마지막인만큼 제일 과제도 어려웠다. 오류가 계속 나서 왜인가 했더니 겨우 날짜 포맷 문제였다. 신버전에서는 날짜 포맷은 안넣어도 된다고 한다. 5주차도 복습은 필수인듯.