이번 포스팅에서는 캐글의 Open University Learning Analytics Dataset을 이용하여 랭글링의 단계 중 Sturcture와 Enriching을 중심으로 정리하려 한다.
데이터 랭글링은 raw data를 쉽고 효율적으로 가공하고 분석할 수 있도록 변환하는 과정이다.
보통 아래 6단계를 거친다.
여러개로 흩어져 있는 table을 merge하기 전에 어떤 문제를 해결할지 정해야한다.
주어진 data로 설정할 수 있는 문제는 다음과 같다.
#학생의 수업 등록정보와 수업 정보, 학생정보를 merge하여 <어떤 특성의 학생>이 <어떤 수업>을 <언제 등록하고, 등록취소>했는지 확인할 수 있는 table을 만듦
#다음 학기 수업을 계속 들을지, 중도에 취소할지 예측할 수 있는 feature로 활용할 수 있음
reg_courses = reg.merge(courses, on = ['code_module', 'code_presentation'], how = 'inner')
reg_courses_info = reg_courses.merge(info, on = ['code_module', 'code_presentation', 'id_student'], how = 'inner')
reg_courses_info.T
#수업의 활동 유형을 설명하는 material과 학생의 활동 정도(클릭수)를 merge하여 수업의 유형 별로 학생의 참여도(클릭수)를 설명하는 data를 만듦
vle_material = vle.merge(materials, on=['code_module', 'code_presentation', 'id_site'], how='inner')
vle_material.isnull().sum()
vle_material.drop(columns=['week_from', 'week_to', 'date'], inplace=True) #대부분이 결측치인 columns 삭제
vle_material.T
#<수업의 시험(평가) 정보>와 <평가 결과> 결합
ass_result = ass.merge(results, on = ['id_assessment'], how = 'inner')
ass_result.T
7개의 테이블을 이렇게 3개로 merge했다.
1) 학생의 개인정보(성별, 지역, 나이, 수업 등록일, 수업 취소일 등) table
2) 학생의 수업 활동 참여도 table
3) 시험(수업) 평가 결과 table
Enriching는 기본적으로 feature engineering을 포괄하는 개념이다.
아래의 과정은 feature engineering과 같다.
#수업의 평가 정보와 평가 결과 결합
ass_result = ass.merge(results, on = ['id_assessment'], how = 'inner')
ass_result
#제출일이 지나서 과제를 제출한 경우(feature engineering)
ass_result['late_submission'] = ass_result['date'] - ass_result['date_submitted']
ass_result['late_submission'] = ass_result['late_submission'] < 0
ass_result
#학생 당 지각제출의 횟수 계산
total_late_count = ass_result.groupby(['id_student', 'code_module', 'code_presentation']).agg(total_late_submission = ('late_submission', sum)).reset_index()
total_late_count.head()
#학생 당 전체 과제 제출 횟수
total_count_assessments = ass_result[['id_student', 'code_module', 'code_presentation', 'id_assessment']].groupby(['id_student', 'code_module', 'code_presentation']).size().reset_index(name = 'total_assessments')
total_count = total_late_count.merge(total_count_assessments, on = ['id_student', 'code_module', 'code_presentation'], how = 'inner')
#학생 당 지각제출의 비율 계산
ass_result = ass_result.merge(total_count, on = ['id_student', 'code_module', 'code_presentation'], how = 'inner')
ass_result['late_submission_rate'] = ass_result['total_late_submission'] / ass_result['total_assessments']
ass_result.drop(columns = ['total_late_submission', 'total_assessments'], inplace = True)
ass_result
groupby로 feature를 만드는 방법에 어느정도 패턴이 있다는 걸 알 수 있다.
1) 두개 이상의 feature를 결합하여 하나의 feature를 만든다.
2) 새롭게 만든 feature는 groupby로 셀 수 있는 class인 True / False로 만든다.
3) 관심 대상(이 경우엔 id_student)를 중심으로 새롭게 만든 feature를 groupby().sum()한다.
4) 앞에서 만든 '총계'를 기존의 table에 붙인다(merge(on = 'id_student').
#낙제 비율 계산
ass_result['fail'] = ass_result['score'] < 40
total_fails_per_student = ass_result.groupby(['id_student', 'code_module', 'code_presentation']).agg(total_fails = ('fail', sum))
total_fails_late = total_count_assessments.merge(total_fails_per_student, on = ['id_student', 'code_module', 'code_presentation'], how = 'inner')
total_fails_late['fail_rate'] = total_fails_late['total_fails'] / total_fails_late['total_assessments']
total_fails_late.drop(columns = ['total_assessments', 'total_fails'], inplace = True)
total_fails_late
ass_result = ass_result.merge(total_fails_late, on = ['id_student', 'code_module', 'code_presentation'], how = 'inner')
ass_result
#학생 당 총 클릭횟수 계산
total_click_per_student = vle_material.groupby(['code_module', 'code_presentation', 'id_student']).agg(total_click = ("sum_click", sum)).reset_index()
total_click_per_student.head()
모두 1 ~ 4의 반복이다.
빠른 wrangling을 위해 자주 사용하는 feature engineering의 패턴을 익혀두는 것이 좋을 것 같다.