Python을 이용한 실전 머신러닝 (1)
In [640]:
In [641]:
1. 데이터 선정 배경 및 분석 목표
1-1. 데이터 선정 배경
먼저, 이 데이터는 2018년에 진행되었던 제5회 L-Point Big-Data Competition의 자료입니다. 때문에 개인적인 분석 이외의 목적으로는 활용할 수 없습니다.
당시 이 공모전에 참가하였는데 머신러닝에 대해 무지할 때라 만족스러운 결과를 얻지 못했던 것이 아쉬움으로 남아 이번 과제를 계기로 다시 한 번 다루어보려고 합니다.
1-2. 분석 목표
데이터 셋이 다양하기 때문에 많은 인사이트를 도출할 수 있겠지만, 이번 분석에서는 Session 데이터를 바탕으로 잠재고객을 예측하는 모델을 세워보려고 합니다.
여기서 잠재고객이란, 온라인 페이지에 접속하여 실제 구매를 진행한 고객입니다.
분석에서는 CLNT_ID를 하나의 고객으로 정의하며 Target variable는 구매여부입니다. Feature는 주로 Session Data의 변수를 사용할 예정입니다.
2. 데이터 소개
01.Product
구매가 발생했을 때의 고객 ID 정보와 해당 제품의 정보를 담고 있는 구매내역 데이터. 아쉬운 점은 구매날짜에 대한 데이터가 없다는 것.
CLNT_ID
기기, 디바이스, 브라우저 체제에 따라 다른 방문자로 인식되기 때문에 동일 고객이 여러 개의 CLNT_ID를 가지고 있다고 볼 수 있으나 분석에서는 그냥 이것을 고객 개개인으로 정의함.
SESS_ID
Wep/App에 접속 후 세션이 시작될 때 부여된 고유 ID로 하나의 클라이언트 ID에 여러 개가 발급될 수 있다. Session ID는 다음과 같은 세 가지 경우에 변경될 수 있다.
사이트 간 이동이 있는 경우(닷컴, 마트, 슈퍼...) 세션 재할당
활동이 30분동안 없는 경우 만료.
자정 이후 만료
In [642]:
Out[642]:
CLNT_ID
SESS_ID
HITS_SEQ
PD_C
PD_ADD_NM
PD_BRA_NM
PD_BUY_AM
PD_BUY_CT
0
4139680
7605037
12
642112
색상:워터멜론
[바비브라운]
39,000
1
1
4140076
10189797
13
570603
색상:BLK0_(BLK0)BLACK|사이즈:120 / 2개
데상트
39,000
2
2
4142395
6158159
85
179538
(not set)
[아베다]
39,000
1
3
4144914
7935714
12
554336
색상:블랙|사이즈:160cm(12~13세) / 1개
아디다스 키즈
39,000
1
4
4144917
6406509
78
190306
5개
데코르테
39,000
5
...
...
...
...
...
...
...
...
...
1048570
949671
5917161
150
164378
색상:navy|사이즈:FREE / 1개
체리코코
51,000
1
1048571
1037959
4407588
44
161284
기본:기본
[빌리프]
51,000
1
1048572
1054284
2134407
30
92272
기본:기본 / 1개
빌리프
51,000
1
1048573
1054309
4134018
127
156417
1개
랩시리즈
51,000
1
1048574
1069766
9721756
61
599546
색상:블랙|사이즈:55 / 1개
라인
51,000
1
1048575 rows × 8 columns
02.Search_1
검색어와 그 빈도를 CLNT_ID별로 보여줌.In [643]:
Out[643]:
CLNT_ID
SESS_ID
KWD_NM
SEARCH_CNT
0
5607714
7112876
빌리프 아이크림
6
1
5607714
4090791
프리메라 마스크팩
3
2
5607714
4090791
여성청결제
1
3
5612428
1876482
명품가방
1
4
5612428
658123
콩순이 아이스크림
1
...
...
...
...
...
1048570
6333334
671748
원피스
1
1048571
6328679
3185795
고공캣
1
1048572
6328679
3185795
고양이간식
1
1048573
6328679
3185795
고양이
1
1048574
6329240
847845
트러플소금
1
1048575 rows × 4 columns
03.Search_2
검색어와 그 빈도를 날짜별로 보여줌.In [644]:
Out[644]:
SESS_DT
KWD_NM
SEARCH_CNT
0
20180407
닥스원피스
8
1
20180407
닥터지 브라이트닝
1
2
20180407
달팡 인트랄
2
3
20180407
대상트
1
4
20180407
더블유닷
6
...
...
...
...
1048570
20180822
보타닉가든 벨머그
1
1048571
20180822
보호필름
2
1048572
20180822
복주머니백
4
1048573
20180822
부라더미싱
1
1048574
20180822
부부리
1
1048575 rows × 3 columns
04.Customer
고객 정보를 담고 있는 데이터In [645]:
Out[645]:
CLNT_ID
CLNT_GENDER
CLNT_AGE
0
4830726
F
30
1
4830874
F
40
2
4830975
F
30
3
4831275
F
30
4
4825325
F
30
...
...
...
...
671674
3725302
F
40
671675
3725462
M
40
671676
3725818
F
30
671677
3661812
F
30
671678
3661917
M
40
671679 rows × 3 columns
05.Session
세션에 대한 데이터로 세션이 발생한 일자와, 페이지 조회건수, 머무른 시간 등에 대한 정보를 담고 있다.In [646]:
Out[646]:
CLNT_ID
SESS_ID
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
ZON_NM
CITY_NM
0
5873599
8641867
9
20180509
82.0
1,890
mobile
Daejeon
Daejeon
1
5873599
6616320
21
20180611
105.0
1,604
mobile
Busan
Busan
2
5873599
5886172
40
20180624
41.0
632
mobile
Daejeon
Daejeon
3
5873884
1050889
15
20180913
160.0
1,035
mobile
Gyeonggi-do
Anyang
4
5874461
10298270
5
20180412
13.0
298
mobile
Seoul
Seoul
...
...
...
...
...
...
...
...
...
...
1048570
2641792
1646940
70
20180903
168.0
6,510
mobile
Seoul
Seoul
1048571
2641792
678245
83
20180919
105.0
2,274
mobile
Seoul
Seoul
1048572
2641792
5087857
29
20180707
24.0
286
mobile
Incheon
Incheon
1048573
2641792
4631909
33
20180714
57.0
385
mobile
Seoul
Seoul
1048574
2641871
4005047
26
20180724
100.0
1,242
mobile
Seoul
Seoul
1048575 rows × 9 columns
06.Master
상품코드와 해당 상품에 대한 정보를 담고 있는 상품 데이터In [647]:
Out[647]:
PD_C
PD_NM
CLAC1_NM
CLAC2_NM
CLAC3_NM
0
64382
언더아머 남성 UA HG 아머 모크 LS 1289559-001 - 블랙 / MD[95]
스포츠패션
남성일반스포츠의류
남성스포츠티셔츠
1
62282
여자 플라워덧신 2족선물세트 17403-2set
속옷/양말/홈웨어
여성양말류
여성일반양말
2
61729
88A2933253배트맨스웨트티 - 블랙 / 130
유아동의류
유아의류상의
영유아티셔츠/탑
3
61537
닥터마틴 아드리안 블랙, 체리레드 - 02_체리레드 / 250mm(6)
패션잡화
남성화
남성부츠
4
58820
여성 그레이 스트라이프 퍼프 소매 블라우스 (128865YQ33) - 회색(앤틱실버...
남성의류
남성의류상의
남성남방셔츠
...
...
...
...
...
...
847647
400721
[피핀] 클레르 박스 롱티셔츠 103764 - ivory / FREE ◈85564075◈
여성의류
여성의류상의
여성티셔츠/탑
847648
400382
[바니플랫]여성플랫/BNF63011EN - 브라운 / 245 ◈83660832◈
패션잡화
여성화
여성플랫
847649
400197
섀르반 올인원 수영복 (K14D5DM231) - BL/110
시즌스포츠
수영/물놀이
아동수영복
847650
399225
링클플리츠주름밴딩스커트(CFHM1SK8821) - 블랙 / FREE
여성의류
여성의류하의
여성스커트
847651
306289
클라이마쿨 쇼츠 [CX3564] - CX3564(그레이) / M
스포츠패션
남성일반스포츠의류
남성일반스포츠바지
847652 rows × 5 columns
3. Analysis Process
➀ Create Target Variable
➁ Feature Engineering
➂ Missing value and outlier treatment
➃ Visualization
➄ Sampling
➅ Modeling
그럼 분석 시작합니다 ~ ~ ~ Start ~ ~ ~ ~ ~ ! ! !
Step 1. Create Target valriable
가장 중요한 부분으로 이 데이터는 TARGET 값이 존재하지 않기 때문에 직접 만들어주어야 합니다!
1. PRODUCT와 SESSION 데이터 셋을 이용하여 만들 수 있습니다.
SESSION은 LOTTE 계열 홈페이지(롯데마트, 롯데몰, 롯데닷컴...)에 접속한 기록을 담은 데이터 셋이고 PRODUCT는 그 중 구매로 이어진 경우 누가 샀고, 그 상품은 무엇인지에 대한 정보를 담은 데이터 셋입니다.
2. 두 Data Set을 Full join 합니다. (key = CLNT_ID, SESS_ID)
그러면 다음과 같은 세 가지 경우가 생깁니다.
➀ PRODUCT변수와 SESSION 변수 모두 가지고 있는 경우
: 세션 검색 결과가 구매로 이어진 케이스로, 이 경우 class 값을 1(구매O)으로 줌.
➁ SESSION변수는 가지고 있으나 PRODUCT 변수는 가지고 있지 않은 경우
: 세션 검색 결과는 존재하나 구매로 이어지지 않은 케이스로, 이 경우 class 값을 0(구매X)으로 줌.
➂ PRODUCT변수는 가지고 있으나 SESSION 변수는 가지고 있지 않은 경우
: SESSION 데이터를 만들면서 삭제된 케이스로, 이 경우는 어떠한 경우에도 해당되지 않으므로 해당 row를 모두 삭제함.
3. CLNT_ID, SESS_ID는 다음과 같이 정의합니다.
➀ CLNT_ID는 한 고객의 다른 디바이스마다 각각 다르게 부여되나 분석의 편의성을 위해 한 명의 고객으로 가정합니다.
➁ SESS_ID는 다양한 상황에서 바뀔 수 있으나 대부분의 경우에서 SESS_ID가 다른 경우는 다른 날짜에 접속했을 때 였습니다. 따라서 SESS_ID는 같은 고객이지만 상이한 날짜에 접속한 경우로 가정합니다.
➂ 대부분의 경우 다른 CLNT_ID 끼리는 같은 SESS_ID를 가질 수 없으나 가지는 경우도 보임. 따라서 CLNT_ID + SESS_ID의 조합을 기본키로 이용해야 합니다.
4. 최종 Target Variable 목표
각 row는 최종적으로 해당 SESS_ID에서 구매가 이루어졌는지에 대한 정보가 class 0 or class 1로 이루어져 있음.
PRODUCT & SESSION FULL JOIN - SAS SQL 사용
In [648]:
In [649]:
Out[649]:
CLNT_ID
SESS_ID
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
ZON_NM
CITY_NM
HITS_SEQ
PD_C
PD_ADD_NM
PD_BRA_NM
PD_BUY_AM
PD_BUY_CT
0
8.0
6964877.0
7.0
2018-06-06
38.0
366.0
mobile
Gyeonggi-do
Gwangmyeong-si
NaN
NaN
NaN
NaN
NaN
NaN
1
25.0
5317297.0
213.0
2018-07-03
33.0
865.0
desktop
Gyeonggi-do
Hwaseong-si
8.0
598634.0
피테로마 때박살:피테로마 때박살 120종
[유씨지]
39800.0
1.0
2
25.0
6059256.0
204.0
2018-06-21
7.0
99.0
desktop
Gyeonggi-do
Osan-si
8.0
715072.0
(not set)
[이롬]
47000.0
1.0
3
25.0
8113243.0
160.0
2018-05-18
28.0
1540.0
desktop
Gyeonggi-do
Osan-si
NaN
NaN
NaN
NaN
NaN
NaN
4
25.0
9506206.0
111.0
2018-04-25
12.0
242.0
desktop
Gyeonggi-do
Hwaseong-si
NaN
NaN
NaN
NaN
NaN
NaN
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1828919
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
11.0
636488.0
1개
이니스프리
550.0
1.0
1828920
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
31.0
5977.0
1개
본타몰
1600.0
1.0
1828921
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
9.0
344451.0
색상:641 오렌지
[디올]
43000.0
1.0
1828922
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
9.0
742670.0
색상:토프
[바비브라운]
42000.0
1.0
1828923
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
9.0
255120.0
색상:브라운(Brown)/사이즈:235mm
[사뿐(Sappun)]
40900.0
1.0
1828924 rows × 15 columnsIn [650]:
In [651]:
Out[651]:
In [652]:
In [653]:
Out[653]:
In [654]:
Out[654]:
In [655]:
Out[655]:
In [656]:
Out[656]:
CLNT_ID
SESS_ID
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
ZON_NM
CITY_NM
HITS_SEQ
PD_C
PD_ADD_NM
PD_BRA_NM
PD_BUY_AM
PD_BUY_CT
0
8.0
6964877.0
7.0
2018-06-06
38.0
366.0
mobile
Gyeonggi-do
Gwangmyeong-si
NaN
NaN
NaN
NaN
NaN
NaN
1
25.0
5317297.0
213.0
2018-07-03
33.0
865.0
desktop
Gyeonggi-do
Hwaseong-si
8.0
598634.0
피테로마 때박살:피테로마 때박살 120종
[유씨지]
39800.0
1.0
2
25.0
6059256.0
204.0
2018-06-21
7.0
99.0
desktop
Gyeonggi-do
Osan-si
8.0
715072.0
(not set)
[이롬]
47000.0
1.0
3
25.0
8113243.0
160.0
2018-05-18
28.0
1540.0
desktop
Gyeonggi-do
Osan-si
NaN
NaN
NaN
NaN
NaN
NaN
4
25.0
9506206.0
111.0
2018-04-25
12.0
242.0
desktop
Gyeonggi-do
Hwaseong-si
NaN
NaN
NaN
NaN
NaN
NaN
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1828908
6592524.0
8220549.0
10.0
2018-05-16
75.0
851.0
mobile
Seoul
Seoul
19.0
813954.0
색상:돌체 비타 / 1개
나스
40000.0
1.0
1828909
6592536.0
61570.0
67.0
2018-09-30
57.0
567.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
1828910
6592536.0
1078369.0
62.0
2018-09-12
50.0
525.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
1828911
6592536.0
1347403.0
57.0
2018-09-08
239.0
1214.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
1828912
6592544.0
8270794.0
1.0
2018-05-15
13.0
105.0
desktop
Gyeonggi-do
Siheung-si
14.0
706193.0
타입:세트
[설화수]
52000.0
1.0
1184063 rows × 15 columns
In [657]:
In [658]:
In [659]:
Out[659]:
CLNT_ID
SESS_ID
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
ZON_NM
CITY_NM
HITS_SEQ
PD_C
PD_ADD_NM
PD_BRA_NM
PD_BUY_AM
PD_BUY_CT
class
1
25.0
5317297.0
213.0
2018-07-03
33.0
865.0
desktop
Gyeonggi-do
Hwaseong-si
8.0
598634.0
피테로마 때박살:피테로마 때박살 120종
[유씨지]
39800.0
1.0
1
2
25.0
6059256.0
204.0
2018-06-21
7.0
99.0
desktop
Gyeonggi-do
Osan-si
8.0
715072.0
(not set)
[이롬]
47000.0
1.0
1
9
33.0
10548225.0
2.0
2018-04-07
48.0
1776.0
desktop
Seoul
Seoul
13.0
605825.0
(not set)
[슈에무라]
49000.0
1.0
1
10
56.0
2108568.0
92.0
2018-08-26
44.0
1343.0
mobile
Busan
Busan
57.0
425529.0
선택:딥모이 / 1개
비욘드
4500.0
1.0
1
11
56.0
2108568.0
92.0
2018-08-26
44.0
1343.0
mobile
Busan
Busan
57.0
425529.0
선택:데일리 디펜스 / 1개
비욘드
4500.0
1.0
1
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1828904
6592524.0
7212211.0
33.0
2018-06-02
110.0
581.0
mobile
Seoul
Seoul
NaN
NaN
NaN
NaN
NaN
NaN
0
1828905
6592524.0
7235959.0
32.0
2018-06-01
307.0
3493.0
mobile
Seoul
Seoul
NaN
NaN
NaN
NaN
NaN
NaN
0
1828909
6592536.0
61570.0
67.0
2018-09-30
57.0
567.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
0
1828910
6592536.0
1078369.0
62.0
2018-09-12
50.0
525.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
0
1828911
6592536.0
1347403.0
57.0
2018-09-08
239.0
1214.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
0
1184063 rows × 16 columns
Step 2. Feature Engineering
1. 불필요한 변수를 삭제합시다
➀ PRODUCT
CLNT_ID, SESS_ID ROW를 구별하기 위한 변수로 ID이기 때문에 변수에서는 제외한다. ***(삭제)***
HITS_SEQ 히트일련번호. 구매가 일어나기까지 몇 번의 행위가 있었는지에 대한 지표로 분석에 적극응용하려고 했으나 구매를 하지 않은 경우에 대해서는 모두 결측이기 때문에 사용할 수 없다. ***(삭제)*** 추가로 덧붙이자면 HITS_SEQ의 경우 PRODUCT 데이터셋에만 존재하기 때문에 구매하지 않은 경우(class 0)에 대해서는 모두 결측이며 구매한 경우(class 0)에 대해서만 양수의 값을 가짐. 그러므로 분석에 의미가 없다고 판단하여 삭제합니다.
PD_C, PD_ADD_NM, PD_BRA_NM, PD_BUY_NM, PD_BUY_CT 구매한 상품 정보에 대한 데이터. SESSION에는 없기 때문에 삭제하여야 함. ***(삭제)***
➁ SESSION
SESS_SEQ 해당 세션 아이디가 같은 CLNT_ID에 몇 번째로 할당되었는지에 대한 지표로 이 값이 클수록 LOTTE 관련 페이지에 많이 접속했다는 뜻으로 해석할 수 있음.
SESS_DT 날짜는 이 자체로 변수로 이용할 수는 없고 분기 변수로 바꾼 후에 더미화 하여 분석에 사용한다.
TOT_PAG_VIEW_CT, TOT_SESS_HR_V 세션 내 총 페이지 뷰 수와 시간 수로 아주 중요한 변수로 작용
DVC_CTG_NM 기기 유형으로 더미변수로 바꾸어 사용
ZON_NM, CITY_NM 지역에 대한 대분류, 중분류로 더미변수로 변환한들 너무 많아지고 지역이 크게 구매여부에 영향을 미치지 않을거라 판단하여 삭제함 ***(삭제)***
2. 나머지 데이터 셋도 그냥 두긴 아쉽지! 피처 엔지니어링 할 게 있나 보자
➀ SEARCH_1
- KWD_NM : 검색창에 입력한 검색 키워드. 하나의 SESS_ID에도 여러 개가 있을 수 있음. - SEARCH_CNT : 해당 검색어 검색량으로 그 검색 키워드에 대해 롯데 페이지에서 얼마나 깊게 찾아보았는가 정도로 해석할 수 있다. ➜ SESS_ID에 대한 SEARCH_CNT의 합을 구한 SUM_SEARCH를 생성하여 Feature로 이용할 수 있다.
➁ SEARCH_2
날짜별로 해당 검색키워드가 몇 번 검색되었는지에 대한 데이터 셋으로, 나에겐 필요 없으니 여기선 아무것도 하지 않는다.
➂ CUSTOM
고객 정보에 대한 데이터로 GENDER와 연령대는 매우 중요한 변수로 작용할 수 있다. 때문에 이 부분은 JOIN을 통해 feature 데이터 셋에 투입하며 결측치는 적절히 대치할 방안을 찾아보자.
➃ MASTER
PRODUCT 데이터 셋에 있는 PD_C에 대한 자세한 정보를 담고 있는 데이터 셋으로 카테고리를 이용한 분석을 진행할 시 굉장히 유용하겠지만 시간적 한계가 있는 나의 현재 분석에서는 이용하지 않는다.
3. Summary! 그래서 지금 뭘 해야한다고~?
➀ 다음의 불필요한 변수를 삭제하자.
: CLNT_ID, SESS_ID, PD_C, HITS_SEQ, PD_ADD_NM, PD_BRA_NM, PD_BUY_AM, PD_BUY_CT, ZON_NM, CITY_NM 그런데 이때! CLNT_ID, SESS_ID는 추후에 데이터 셋 끼리 join할 때의 중요한 key이므로 모델링 직전에 삭제합니다!
➁ Feature Engineering을 통해 새 변수를 투입하자
SESS_DT : session 날짜로 분기로 바꾼 후에 더미화하자.
DVC_CTG_NM : 세 가지 기기유형에 대한 변수(mobile, desktop, tablet)로 더미화하자.
SEARCH_CNT : SESS_ID를 기준으로 SUM하여 새로운 변수 SEARCH_CNT를 생성하자.
➂ 결측치와 이상치를 확인하자!
: CLNT_GENDER & CLNT_AGE (고객정보) : join 하는 과정에서 결측치가 생길 수 있으니 주의!
1. 필요없는 변수를 삭제하자.
In [660]:
Out[660]:
CLNT_ID
SESS_ID
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
ZON_NM
CITY_NM
HITS_SEQ
PD_C
PD_ADD_NM
PD_BRA_NM
PD_BUY_AM
PD_BUY_CT
class
1
25.0
5317297.0
213.0
2018-07-03
33.0
865.0
desktop
Gyeonggi-do
Hwaseong-si
8.0
598634.0
피테로마 때박살:피테로마 때박살 120종
[유씨지]
39800.0
1.0
1
2
25.0
6059256.0
204.0
2018-06-21
7.0
99.0
desktop
Gyeonggi-do
Osan-si
8.0
715072.0
(not set)
[이롬]
47000.0
1.0
1
9
33.0
10548225.0
2.0
2018-04-07
48.0
1776.0
desktop
Seoul
Seoul
13.0
605825.0
(not set)
[슈에무라]
49000.0
1.0
1
10
56.0
2108568.0
92.0
2018-08-26
44.0
1343.0
mobile
Busan
Busan
57.0
425529.0
선택:딥모이 / 1개
비욘드
4500.0
1.0
1
11
56.0
2108568.0
92.0
2018-08-26
44.0
1343.0
mobile
Busan
Busan
57.0
425529.0
선택:데일리 디펜스 / 1개
비욘드
4500.0
1.0
1
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1828904
6592524.0
7212211.0
33.0
2018-06-02
110.0
581.0
mobile
Seoul
Seoul
NaN
NaN
NaN
NaN
NaN
NaN
0
1828905
6592524.0
7235959.0
32.0
2018-06-01
307.0
3493.0
mobile
Seoul
Seoul
NaN
NaN
NaN
NaN
NaN
NaN
0
1828909
6592536.0
61570.0
67.0
2018-09-30
57.0
567.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
0
1828910
6592536.0
1078369.0
62.0
2018-09-12
50.0
525.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
0
1828911
6592536.0
1347403.0
57.0
2018-09-08
239.0
1214.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
0
1184063 rows × 16 columnsIn [661]:
Out[661]:
CLNT_ID
SESS_ID
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
class
1
25.0
5317297.0
213.0
2018-07-03
33.0
865.0
desktop
1
2
25.0
6059256.0
204.0
2018-06-21
7.0
99.0
desktop
1
9
33.0
10548225.0
2.0
2018-04-07
48.0
1776.0
desktop
1
10
56.0
2108568.0
92.0
2018-08-26
44.0
1343.0
mobile
1
11
56.0
2108568.0
92.0
2018-08-26
44.0
1343.0
mobile
1
...
...
...
...
...
...
...
...
...
1828904
6592524.0
7212211.0
33.0
2018-06-02
110.0
581.0
mobile
0
1828905
6592524.0
7235959.0
32.0
2018-06-01
307.0
3493.0
mobile
0
1828909
6592536.0
61570.0
67.0
2018-09-30
57.0
567.0
mobile
0
1828910
6592536.0
1078369.0
62.0
2018-09-12
50.0
525.0
mobile
0
1828911
6592536.0
1347403.0
57.0
2018-09-08
239.0
1214.0
mobile
0
1184063 rows × 8 columns
2. Feature Engineering
원래 SESS_DT를 이용하여 분기 변수 만들기 였으나 Problem이 발생했음. 왜냐 SESS_DT의 범위는 2018.04~2018.09 사이였기 때문! 이는 분기의 의미가 없으므로 "계절"의 의미를 담는 것이 더 좋을 것이라 판단.
4월, 5월 : 봄
6월, 7월, 8월 : 여름
9월 : 가을
이렇게 더미화 시켜봅시다!In [662]:
Out[662]:
In [663]:
In [664]:
Out[664]:
In [665]:
Out[665]:
In [666]:
In [667]:
Out[667]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
class
SESS_DT_M
1
25.0
5317297.0
213.0
33.0
865.0
desktop
1
7
2
25.0
6059256.0
204.0
7.0
99.0
desktop
1
6
9
33.0
10548225.0
2.0
48.0
1776.0
desktop
1
4
10
56.0
2108568.0
92.0
44.0
1343.0
mobile
1
8
11
56.0
2108568.0
92.0
44.0
1343.0
mobile
1
8
...
...
...
...
...
...
...
...
...
1828904
6592524.0
7212211.0
33.0
110.0
581.0
mobile
0
6
1828905
6592524.0
7235959.0
32.0
307.0
3493.0
mobile
0
6
1828909
6592536.0
61570.0
67.0
57.0
567.0
mobile
0
9
1828910
6592536.0
1078369.0
62.0
50.0
525.0
mobile
0
9
1828911
6592536.0
1347403.0
57.0
239.0
1214.0
mobile
0
9
1184063 rows × 8 columnsIn [668]:
Out[668]:
In [669]:
In [670]:
In [671]:
Out[671]:
In [672]:
In [673]:
Out[673]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
1
25.0
5317297.0
213.0
33.0
865.0
1
1
0
0
0
0
1
2
25.0
6059256.0
204.0
7.0
99.0
1
1
0
0
0
0
1
9
33.0
10548225.0
2.0
48.0
1776.0
1
1
0
0
0
1
0
10
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
11
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
...
...
...
...
...
...
...
...
...
...
...
...
...
1828904
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
1828905
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
1828909
6592536.0
61570.0
67.0
57.0
567.0
0
0
1
0
1
0
0
1828910
6592536.0
1078369.0
62.0
50.0
525.0
0
0
1
0
1
0
0
1828911
6592536.0
1347403.0
57.0
239.0
1214.0
0
0
1
0
1
0
0
1184063 rows × 12 columns
그렇다면 이제 SUM_SEARCH 변수를 새로 생성해봅시다
검색량 변수를 만들기 위해 SEARCH_CNT를 CLNT_ID & SESS_ID를 기준으로 SUM한 SUM_SEARCH 변수 생성 [SUM_SEARCH] 각 SESS_ID에 대한 총 검색량으로 이 값이 높을수록 구매가능성이 높을 것이라 추측.
SAS에서 데이터 핸들링했습니다.
In [674]:
In [675]:
Out[675]:
CLNT_ID
SESS_ID
SUM_SEARCH
0
14
1156991
5
1
33
8694850
4
2
33
10300429
6
3
33
10548225
12
4
56
2108568
3
...
...
...
...
444097
6592519
2619413
2
444098
6592519
6188865
1
444099
6592519
7284207
2
444100
6592536
1078369
1
444101
6592536
1347403
3
444102 rows × 3 columnsIn [676]:
Out[676]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
0
25.0
5317297.0
213.0
33.0
865.0
1
1
0
0
0
0
1
NaN
1
25.0
6059256.0
204.0
7.0
99.0
1
1
0
0
0
0
1
NaN
2
33.0
10548225.0
2.0
48.0
1776.0
1
1
0
0
0
1
0
12.0
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
NaN
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
NaN
1184060
6592536.0
61570.0
67.0
57.0
567.0
0
0
1
0
1
0
0
NaN
1184061
6592536.0
1078369.0
62.0
50.0
525.0
0
0
1
0
1
0
0
1.0
1184062
6592536.0
1347403.0
57.0
239.0
1214.0
0
0
1
0
1
0
0
3.0
1184063 rows × 13 columnsIn [677]:
SUM_SEARCH는 ....
sum_search 값은 전체의 18%만 존재함. 즉, SUM_SEARCH는 전체의 82%가 전부 다 결측치...TT
class가 1인 경우 sum_search 값은 20% 존재함.
class가 0인 경우 sum_search 값은 17% 존재함. ==> 불행 중 다행! 그래도 class별 비율은 어느정도 맞다!
But...
외부 사이트(네이버쇼핑 등과 같은 기타 검색 엔진)를 통해 유입된 경우엔 따로 검색이 필요하지 않기 때문에 sum_search 값이 0일 것. 따라서 sum_search 값이 없는 경우는 외부 사이트로부터의 유입이라고 간주하고 검색 기록이 없다는 의미로 사용될 수 있도록 0으로 대치한다!
Step3. Missing value and outlier treatment
In [678]:
In [679]:
Out[679]:
In [680]:
Out[680]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
0
25.0
5317297.0
213.0
33.0
865.0
1
1
0
0
0
0
1
0.0
1
25.0
6059256.0
204.0
7.0
99.0
1
1
0
0
0
0
1
0.0
2
33.0
10548225.0
2.0
48.0
1776.0
1
1
0
0
0
1
0
12.0
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
1184060
6592536.0
61570.0
67.0
57.0
567.0
0
0
1
0
1
0
0
0.0
1184061
6592536.0
1078369.0
62.0
50.0
525.0
0
0
1
0
1
0
0
1.0
1184062
6592536.0
1347403.0
57.0
239.0
1214.0
0
0
1
0
1
0
0
3.0
1184063 rows × 13 columns
이제 고객 정보 변수 (CLNT_GNEDER, CLNT_AGE) 를 넣어 봅시다.In [681]:
Out[681]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
0
25.0
5317297.0
213.0
33.0
865.0
1
1
0
0
0
0
1
0.0
NaN
NaN
1
25.0
6059256.0
204.0
7.0
99.0
1
1
0
0
0
0
1
0.0
NaN
NaN
2
33.0
10548225.0
2.0
48.0
1776.0
1
1
0
0
0
1
0
12.0
NaN
NaN
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
F
30.0
1184060
6592536.0
61570.0
67.0
57.0
567.0
0
0
1
0
1
0
0
0.0
NaN
NaN
1184061
6592536.0
1078369.0
62.0
50.0
525.0
0
0
1
0
1
0
0
1.0
NaN
NaN
1184062
6592536.0
1347403.0
57.0
239.0
1214.0
0
0
1
0
1
0
0
3.0
NaN
NaN
1184063 rows × 15 columnsIn [682]:
Out[682]:
In [683]:
위에서 확인한 네 가지 변수 결측값 대치하기
지금까지 중 가장 어려운 대목이다, 결측값을 무엇으로 바꿔주어야할까?In [684]:
Out[684]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
0
25.0
5317297.0
213.0
33.0
865.0
1
1
0
0
0
0
1
0.0
NaN
NaN
1
25.0
6059256.0
204.0
7.0
99.0
1
1
0
0
0
0
1
0.0
NaN
NaN
2
33.0
10548225.0
2.0
48.0
1776.0
1
1
0
0
0
1
0
12.0
NaN
NaN
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
F
30.0
1184060
6592536.0
61570.0
67.0
57.0
567.0
0
0
1
0
1
0
0
0.0
NaN
NaN
1184061
6592536.0
1078369.0
62.0
50.0
525.0
0
0
1
0
1
0
0
1.0
NaN
NaN
1184062
6592536.0
1347403.0
57.0
239.0
1214.0
0
0
1
0
1
0
0
3.0
NaN
NaN
1184063 rows × 15 columns
TOT_PAG_VIEW_CT :: 세션 내의 총 페이지 뷰 수
평균 값으로 대치하되, 클래스 별로 다른 값을 사용하자!In [685]:
Out[685]:
In [686]:
Out[686]:
In [687]:
Out[687]:
In [688]:
In [689]:
In [690]:
Out[690]:
In [691]:
Out[691]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
0
25.0
5317297.0
213.0
33.0
865.0
1
1
0
0
0
0
1
0.0
NaN
NaN
1
25.0
6059256.0
204.0
7.0
99.0
1
1
0
0
0
0
1
0.0
NaN
NaN
2
33.0
10548225.0
2.0
48.0
1776.0
1
1
0
0
0
1
0
12.0
NaN
NaN
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
F
30.0
1184060
6592536.0
61570.0
67.0
57.0
567.0
0
0
1
0
1
0
0
0.0
NaN
NaN
1184061
6592536.0
1078369.0
62.0
50.0
525.0
0
0
1
0
1
0
0
1.0
NaN
NaN
1184062
6592536.0
1347403.0
57.0
239.0
1214.0
0
0
1
0
1
0
0
3.0
NaN
NaN
1184063 rows × 15 columns
TOT_SESS_HR_V :: 세션 내 총 시간(단위: 초)
평균 값으로 대치하되, 클래스 별로 다른 값을 사용하자!In [692]:
Out[692]:
In [693]:
Out[693]:
In [694]:
Out[694]:
In [695]:
In [696]:
In [697]:
Out[697]:
CLNT_GENDER :: 고객의 성별
In [698]:
Out[698]:
CLNT_AGE :: 고객의 연령대
In [699]:
Out[699]:
20만개의 결측치를 어떻게 처리할까?
아예 없애버릴까, 아니면 가장 빈번한 값으로 대치할까? 두 방법 다 성에차진 않는다.
성별이 F인 고객과 M인 고객은 각각 어떤 특징을 보이고 있을까? 내 생각에 가장 성별을 잘 구별할 수 있는 특징은 '검색어'인 것 같다. Search 테이블과 Customer 데이터를 join해서 성별 검색어에 어떤 차이가 있는지 알아보자.In [700]:
In [701]:
Out[701]:
CLNT_ID
SESS_ID
KWD_NM
SEARCH_CNT
CLNT_GENDER
CLNT_AGE
0
5607714
7112876
빌리프 아이크림
6
F
40
1
5607714
4090791
프리메라 마스크팩
3
F
40
2
5607714
4090791
여성청결제
1
F
40
3
5612428
1876482
명품가방
1
F
30
4
5612428
658123
콩순이 아이스크림
1
F
30
...
...
...
...
...
...
...
836747
6333334
671748
원피스
1
F
40
836748
6328679
3185795
고공캣
1
F
30
836749
6328679
3185795
고양이간식
1
F
30
836750
6328679
3185795
고양이
1
F
30
836751
6329240
847845
트러플소금
1
F
40
836752 rows × 6 columnsIn [702]:
Out[702]:
In [703]:
Out[703]:
워드클라우드를 이용해 성별 자주 나오는 검색어는 뭐가 있는지 알아보자!
In [704]:
Out[704]:
KWD_NM
CLNT_GENDER
CLNT_AGE
0
빌리프 아이크림
F
40
1
프리메라 마스크팩
F
40
2
여성청결제
F
40
3
명품가방
F
30
4
콩순이 아이스크림
F
30
...
...
...
...
836747
원피스
F
40
836748
고공캣
F
30
836749
고양이간식
F
30
836750
고양이
F
30
836751
트러플소금
F
40
836752 rows × 3 columnsIn [705]:
In [706]:
In [707]:
In [708]:
In [709]:
준비는 끝났으니 워드클라우드를 만들어봅시다!
In [710]:
In [711]:
남성 검색어 키워드
In [712]:
In [713]:
남성, 아디다스, 셔츠, 지오다노, 반바지, 라코스테 ..... 와 더불어 여성, 원피스 등의 키워드도 보입니다!
Top20에는 어떤 키워드들이 들어갈까요?
In [714]:
In [715]:
Out[715]:
여성 검색어 키워드
In [716]:
In [717]:
여성, 원피스, 티셔츠, 나이키, 아디다스 기타 등등이 보입니다.
Top20에는 어떤 키워드들이 들어갈까요?
In [718]:
In [719]:
Out[719]:
잠깐! 그래서 이걸로 뭘 할 수 있다고~?
우리는 CLNT_GENDER와 CLNT_AGE의 결측값을 대치할 방법을 찾고 있었습니다.
저는 성별로 검색어 특징의 차이가 있지 않을까?라는 가설을 세우고 이를 확인하기 위해 워드 클라우드를 사용했습니다.
만약 특징에 큰 차이가 있다면, CLNT_GENDER가 결측인 ROW에 대해서, 만약 그 ROW의 검색어 기록이 존재한다면, 그것을 바탕으로 성별을 추측할 수 있지 않을까요?
In [720]:
In [721]:
Out[721]:
M
F
0
남성
여성
1
나이키
원피스
2
티셔츠
티셔츠
3
여성
남성
4
아디다스
나이키
5
셔츠
블라우스
6
원피스
아디다스
7
바지
샌들
8
반바지
반바지
9
남자
여아
10
지오다노
남아
11
라코스테
팬츠
12
빈폴
지오다노
13
운동화
바지
14
반팔티
크록스
15
반팔
스커트
16
샌들
블루독
17
노스페이스
아동
18
슬리퍼
키즈
19
데상트
래쉬가드
하지만 결과는 ....... Fail.....
특징이 명확하게 분리되지 않았습니다. 남성 검색어 4위에는 여성이, 여성 검색어 4위에는 남성이 들어가 있는 것 부터 등골이 쎄했지만 그래도 혹시나 하는 마음에 일단 진행해 본 것이었는데 이제는 놓아줄 때가 되었나 봅니다. 검색어를 통한 GENDER 결측값 대치는 사실 상 불가능한 것이라고 판단, 스폰지밥을 보내주겠습니다.
CLNT_GEDNER, CLNT_AGE 결측값이 존재하는 ROW를 삭제합시다
가장 빈번하게 나온 값으로 대치하는 방법도 생각해보았지만, 일단 데이터가 118만개이기 때문에 대치보다는 그냥 해당 row를 삭제하는 것이 더 좋다고 판단했습니다.In [722]:
In [723]:
Out[723]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
5
68.0
4237632.0
44.0
33.0
418.0
1
0
1
0
0
0
1
0.0
F
30.0
6
135.0
253618.0
29.0
40.0
697.0
1
0
1
0
1
0
0
0.0
M
40.0
9
156.0
7112398.0
181.0
236.0
1937.0
1
0
1
0
0
0
1
0.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184055
6592482.0
5743284.0
33.0
12.0
112.0
0
0
1
0
0
0
1
0.0
M
40.0
1184056
6592502.0
63166.0
27.0
19.0
434.0
0
0
1
0
1
0
0
0.0
F
30.0
1184057
6592519.0
6188865.0
159.0
52.0
343.0
0
0
1
0
0
0
1
1.0
F
20.0
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
F
30.0
967232 rows × 15 columns
CLNT_GENDER와 CLNT_AGE를 더미화하자!
In [724]:
In [725]:
Out[725]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
...
CLNT_GENDER_F
CLNT_GENDER_M
CLNT_AGE_10.0
CLNT_AGE_20.0
CLNT_AGE_30.0
CLNT_AGE_40.0
CLNT_AGE_50.0
CLNT_AGE_60.0
CLNT_AGE_70.0
CLNT_AGE_80.0
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
...
1
0
0
0
0
1
0
0
0
0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
...
1
0
0
0
0
1
0
0
0
0
5
68.0
4237632.0
44.0
33.0
418.0
1
0
1
0
0
...
1
0
0
0
1
0
0
0
0
0
6
135.0
253618.0
29.0
40.0
697.0
1
0
1
0
1
...
0
1
0
0
0
1
0
0
0
0
9
156.0
7112398.0
181.0
236.0
1937.0
1
0
1
0
0
...
1
0
0
0
0
1
0
0
0
0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184055
6592482.0
5743284.0
33.0
12.0
112.0
0
0
1
0
0
...
0
1
0
0
0
1
0
0
0
0
1184056
6592502.0
63166.0
27.0
19.0
434.0
0
0
1
0
1
...
1
0
0
0
1
0
0
0
0
0
1184057
6592519.0
6188865.0
159.0
52.0
343.0
0
0
1
0
0
...
1
0
0
1
0
0
0
0
0
0
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
...
1
0
0
0
1
0
0
0
0
0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
...
1
0
0
0
1
0
0
0
0
0
967232 rows × 23 columns
연속형 변수의 이상치를 확인하자!
In [726]:
In [936]:
In [728]:
이상치는 없다고 판단하고 다음으로 넘어갑니다.
산점도가 선형으로 나타나는데 그 이유는 SESS_SEQ(할당된 세션 번호)는 CLNT_ID별로 첫 세션이 발급되었을 때 1, 그리고 이후 방문마다 증가합니다. 따라서 SESS_SEQ가 높을수록 더 페이지에 자주 들리는 것이라고 생각할 수 있으며, 이는 일종의 충성도라고 할 수 있습니다. 이것이 커지면서 검색 횟수는 줄어드는 것을 볼 수 있는데, 자주 페이지에 들리는 사람들은 어떠한 물건을 검색하기 위해 들어오는 것이 아니라 습관적으로 페이지에 들어오기 때문에 SESS_SEQ가 증가할수록 SUM_SEARCH(검색횟수)는 감소하는 것으로 해석할 수 있습니다.
Step4. Visualization
feature도 완성이 되었습니다! 그래도 분석 전에 데이터가 어떻게 생겼는지는 봐야겠죠?
1. DVC_CTG_NM(사용 디바이스), SESS_DT_M(계절)
이 두가지 변수는 더미화하기 전인 데이터셋을 이용해서 확인해보겠습니다. (CLNT_GENDER, CLNT_AGE의 결측값을 삭제하기 전 데이터셋이라 118만개입니다.)In [729]:
Out[729]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
class
SESS_DT_M
1
25.0
5317297.0
213.0
33.0
865.0
desktop
1
여름
2
25.0
6059256.0
204.0
7.0
99.0
desktop
1
여름
9
33.0
10548225.0
2.0
48.0
1776.0
desktop
1
봄
10
56.0
2108568.0
92.0
44.0
1343.0
mobile
1
여름
11
56.0
2108568.0
92.0
44.0
1343.0
mobile
1
여름
...
...
...
...
...
...
...
...
...
1828904
6592524.0
7212211.0
33.0
110.0
581.0
mobile
0
여름
1828905
6592524.0
7235959.0
32.0
307.0
3493.0
mobile
0
여름
1828909
6592536.0
61570.0
67.0
57.0
567.0
mobile
0
가을
1828910
6592536.0
1078369.0
62.0
50.0
525.0
mobile
0
가을
1828911
6592536.0
1347403.0
57.0
239.0
1214.0
mobile
0
가을
1184063 rows × 8 columnsIn [730]:
클래스는 2대 1 비율로 이루어져 있으며 구매를 하지 않은 경우가 더 많다.
사용 디바이스는 핸드폰(mobile)이 약 83%로 전체의 대부분을 차지했으며 tablet은 거의 없었다. (0.4%)
계절로 보았을 때에는 6, 7, 8월의 데이터가 절반을 차지했으며 그 다음으로는 봄(4, 5월), 가을(9월) 순으로 많았다.
2. CLNT_AGE, CLNT_GENDER
In [731]:
Out[731]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
0
25.0
5317297.0
213.0
33.0
865.0
1
1
0
0
0
0
1
0.0
NaN
NaN
1
25.0
6059256.0
204.0
7.0
99.0
1
1
0
0
0
0
1
0.0
NaN
NaN
2
33.0
10548225.0
2.0
48.0
1776.0
1
1
0
0
0
1
0
12.0
NaN
NaN
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
F
30.0
1184060
6592536.0
61570.0
67.0
57.0
567.0
0
0
1
0
1
0
0
0.0
NaN
NaN
1184061
6592536.0
1078369.0
62.0
50.0
525.0
0
0
1
0
1
0
0
1.0
NaN
NaN
1184062
6592536.0
1347403.0
57.0
239.0
1214.0
0
0
1
0
1
0
0
3.0
NaN
NaN
1184063 rows × 15 columnsIn [732]:
Out[732]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
5
68.0
4237632.0
44.0
33.0
418.0
1
0
1
0
0
0
1
0.0
F
30.0
6
135.0
253618.0
29.0
40.0
697.0
1
0
1
0
1
0
0
0.0
M
40.0
9
156.0
7112398.0
181.0
236.0
1937.0
1
0
1
0
0
0
1
0.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184055
6592482.0
5743284.0
33.0
12.0
112.0
0
0
1
0
0
0
1
0.0
M
40.0
1184056
6592502.0
63166.0
27.0
19.0
434.0
0
0
1
0
1
0
0
0.0
F
30.0
1184057
6592519.0
6188865.0
159.0
52.0
343.0
0
0
1
0
0
0
1
1.0
F
20.0
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
F
30.0
967232 rows × 15 columns
In [733]:
In [734]:
3. 연속형 변수는 클래스 별로 어떻게 분포할까?
In [735]:
조금 징그러운 그래프이다. 회귀선이 희미하게 보인다. 비슷한데 아주 살짝 class 1이 위에 있는 것으로 보아 세션 내 시간과 세션 내 페이지 뷰 수가 클수록 구매가 조금 더 잘 일어난다고 볼 수 있다.In [736]:
Step5. Sampling
샘플링은 두 가지로 진행합니다.
Train 0.8 / Test 0.2로 나눈 데이터 셋 : 복잡하지 않은 Single model을 돌릴 때 사용합니다.
Train 0.05 / Test 0.95로 나눈 데이터 셋 : Ensemble, Gridsearchcv 등을 돌릴 때 사용합니다.
1. Feature & Target 분리
In [737]:
In [738]:
Out[738]:
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
...
CLNT_GENDER_F
CLNT_GENDER_M
CLNT_AGE_10.0
CLNT_AGE_20.0
CLNT_AGE_30.0
CLNT_AGE_40.0
CLNT_AGE_50.0
CLNT_AGE_60.0
CLNT_AGE_70.0
CLNT_AGE_80.0
3
92.0
44.0
1343.0
1
0
1
0
0
0
1
...
1
0
0
0
0
1
0
0
0
0
4
92.0
44.0
1343.0
1
0
1
0
0
0
1
...
1
0
0
0
0
1
0
0
0
0
5
44.0
33.0
418.0
1
0
1
0
0
0
1
...
1
0
0
0
1
0
0
0
0
0
6
29.0
40.0
697.0
1
0
1
0
1
0
0
...
0
1
0
0
0
1
0
0
0
0
9
181.0
236.0
1937.0
1
0
1
0
0
0
1
...
1
0
0
0
0
1
0
0
0
0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184055
33.0
12.0
112.0
0
0
1
0
0
0
1
...
0
1
0
0
0
1
0
0
0
0
1184056
27.0
19.0
434.0
0
0
1
0
1
0
0
...
1
0
0
0
1
0
0
0
0
0
1184057
159.0
52.0
343.0
0
0
1
0
0
0
1
...
1
0
0
1
0
0
0
0
0
0
1184058
33.0
110.0
581.0
0
0
1
0
0
0
1
...
1
0
0
0
1
0
0
0
0
0
1184059
32.0
307.0
3493.0
0
0
1
0
0
0
1
...
1
0
0
0
1
0
0
0
0
0
967232 rows × 21 columns
In [739]:
In [637]:
In [743]:
Out[743]:
2. Train-Test Split
In [747]:
In [748]:
Out[748]:
In [749]:
Out[749]:
In [750]:
In [751]:
Out[751]:
In [753]:
Out[753]:
y의 비율을 살펴봅시다.
In [754]:
Out[754]:
In [755]:
Out[755]:
3. Scaling
In [757]:
In [758]:
Out[758]:
In [759]:
Out[759]:
In [760]:
In [761]:
Out[761]:
In [762]:
Out[762]:
Step6. Modeling
1. 먼저 간단하게 단일 모델에 대한 성능을 살펴봅시다!
Decision Tree
In [763]:
In [764]:
Out[764]:
In [765]:
Out[765]:
max_depth 를 살짝 조정해봅시다.
In [766]:
Out[766]:
In [767]:
Out[767]:
In [768]:
Out[768]:
In [769]:
Out[769]:
In [781]:
Out[781]:
In [786]:
Out[786]:
Logistic Regression
In [788]:
Out[788]:
In [790]:
Out[790]:
K-Means Clustering
In [891]:
Out[891]:
In [892]:
In [893]:
Out[893]:
In [894]:
Out[894]:
2. Ensemble 해봅시다 ~ !
In [795]:
2-1. Default Model
디폴트 모델로 돌려보면서 전반적인 점수를 확인하고 추가로 진행할 모델을 선정합시다.
Gradient Boost
In [796]:
Out[796]:
Random Forest
In [798]:
Out[798]:
XGBoost
In [801]:
Out[801]:
LightGBM
In [803]:
Out[803]:
2-2. GridSearchCV
네 개의 모델 다 score의 차이가 크지 않아서 전부 다 튜닝해 볼 가치가 있지만, 시간 관계상 Gradient Boost, XGBoost 두 개에 대해서만 하이퍼 파라미터 튜닝을 해보겠습니다
➀ Gradient Boost
Graident Boost의 하이퍼파라미터 튜닝은 이곳을 참조하였습니다.
Baseline model Score : 0.6713706276506713
Tune1 Score : 0.6715329060099838 (Learning_rate, n_estimators)
In [ ]:
In [806]:
Out[806]:
Tune2 Score : 0.6715329060099838 (max_depth)
In [807]:
Out[807]:
Tune3 Score : 0.6715949279230677 (min_samples_split, min_samples_leaf, max_features)
In [811]:
Out[811]:
위의 결과를 종합해서 최종 스코어를 내보자!
Tune4 Score : 0.6713009769597691 (오히려 디폴트였을 때 보다 아주 살짝 더 낮아졌다 ㅋㅋㅋ)
In [821]:
Out[821]:
[결론]
하이퍼 파라미터 튜닝은 굉장히 어렵다. 그냥 한꺼번에 모든 파라미터에 대한 조합을 돌려놓고 자고 일어났으면 결과가 달라져있었을까? 다음부턴 자기 전에 꼭 모든 파라미터 조합에 대한 그리드 서치를 돌려놓을 것이다.
➁ XGBoost
XGBoost의 하이퍼파라미터 튜닝은 이곳을 참조하였습니다.
이번에는 tree와 관련된 하이퍼 파라미터를 먼저 튜닝해보겠습니다. learning_rate와 n_estimators에 대한 최적의 파라미터를 먼저 찾는 것도 좋지만, 초반에 learning_rate를 너무 낮게 잡았더니 학습이 느려 비효율적이라는 생각이 들었습니다.
따라서 이번에는
Tune Tree-specific parameters (max_depth, min_child_weight)
Tune Regularization parameters (gamma, alpha)
Reducing Leraning rate
순서로 진행합니다.
Baseline model Score : 0.6711616755779647
Tune1 Score : 0.6676454277367861 (max_depth, min_child_weight)
In [813]:
Out[813]:
Tune2 Score : 0.6696098461887339 (gamma, reg_alpha)
In [815]:
Out[815]:
디폴트로 주었을 때 보다 낮다니 믿을 수가 없다. 하지만 그래도 마지막까지 해보자.
Tune3 Score : 0.6698373004868805 (점점 더 산으로 가는 것 같다. 망한걸까?)
In [819]:
Out[819]:
이렇게 된 이상 직접 하이퍼 파라미터를 튜닝해봅시다.........ㅋ
Tune4 Score : 0.6710474049132032
In [828]:
Out[828]:
2-3. Stacking
In [837]:
스태킹에 사용할 모델은 가장 score가 높게 나왔던 세 가지로 합니다
DT Sigle model : dt // 0.6864929412190419
Gradient Boost Default model : gbrt // 0.6713706276506713
XGBBoost Default model : xgb_c // 0.6711616755779647
In [843]:
In [860]:
In [898]:
In [899]:
Out[899]:
0.5 이상(즉, 두 개 이상의 모델에서 1이라고 투표한 경우)를 기준으로 잘라봅시다.In [900]:
In [901]:
In [902]:
Out[902]:
In [903]:
Out[903]:
[결론] 그냥 dt default model로 예측했을 때가 가장 높다. 이것은 하이퍼 파라미터 튜닝의 문제보다는 데이터 자체의 문제라는 생각이 든다.
Step 7. What's the problem?
열심히 하이퍼 파라미터 튜닝을 해 보았지만 성능은 전혀 나아지지 않고 있다. 어떻게 하면 더 좋은 성능을 낼 수 있을지에 대한 고민 끝에 다음과 같은 네 가지 가설을 세울 수 있었다.
1. Feature가 부족하다.
: 피쳐가 부족한 건 처음부터 우려했던 부분이었다. 더 만들 수 있는 변수는 어떤 것이 있을까 생각해본 결과 PRODUCT 데이터 셋을 이용하여 '구매이력' 변수를 만들 수 있겠다 생각했음. [구매이력] SESS_ID를 기준으로, 데이터 기간 내 다른 날짜에 구매한 이력을 COUNT하여 생성
2. 나의 Hyper Parameter Tuning의 능력이 부족하다.
: 하이퍼 파라미터 문제에 앞서 모델 선정 능력 또한 부족한 것은 아닐까 생각해보았고 대안으로 AutoML과 Scikit-optimize를 생각해보았으나 현재 이 구린 성능의 원인은 모델과 하이퍼 파라미터의 문제보다는 데이터 셋 자체의 문제가 더 크다고 생각해서 일단 Pass
3. 애초에 Accuracy만이 좋은 지표로 작용하는가?
: 이 부분에 대해서도 많이 생각해보았다. Confusion matrix에서 예측이 잘못된 부분은 False Nagative, False Positive로 나눌 수 있는데 자꾸 헷갈려서 적어놓겠다.
False Nagative (confusion matrix의 2행 1열) : 예측은 0이라고 했는데 실제 1인 것들의 숫자 ---> Recall Score와 관련
False Positive (confusion matrix의 1행 2열) : 예측은 1이라고 했는데 실제 0인 것들의 숫자 ---> Precision Score와 관련 이 중에서도 나의 데이터에서 더 중요한 지표는 False Nagative와 연관된 Recall Score라고 생각했다. 구매를 한 사람들을 안 했다고 예측한다면 추후에도 잠재고객을 놓쳐버릴 수 있기 때문에 Accuracy와 더불어 Recall 값 또한 성능에 중요한 영향을 미친다. 반대로 Precision Score의 경우 잠재고객이라고 예측했으나 실제 구매하지 않은 케이스에 대한 지표로 상대적으로 중요도가 떨어진다. 따라서 추후 분석에서는 Accuracy와 Recall, Precision의 적절한 조화를 찾아보도록 하겠다.
4. 모든 데이터에 대해 고려하다보니 생긴 일?
: 나의 모델 성능에 가장 많이 영향을 미친 부분이라고 생각한다. 애초에 시각화 파트에서 보면 알겠지만, 30, 40대 여성의 내역이 데이터의 80%이상을 차지하고 이는 다시 말해 롯데 계열사의 주고객이 30, 40대 여성이라는 뜻이기 때문에 모든 데이터를 고려했을 때 성능이 좋다면 문제가 되지 않으나, 지금과 같은 상황이 발생한 경우 주고객층의 class라도 잘 예측하자는 의미에서 데이터 셋을 분리할 필요가 있다고 본다.
Step 8. 30, 40대 여성의 경우만 고려하자!
In [909]:
Out[909]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
5
68.0
4237632.0
44.0
33.0
418.0
1
0
1
0
0
0
1
0.0
F
30.0
6
135.0
253618.0
29.0
40.0
697.0
1
0
1
0
1
0
0
0.0
M
40.0
9
156.0
7112398.0
181.0
236.0
1937.0
1
0
1
0
0
0
1
0.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184055
6592482.0
5743284.0
33.0
12.0
112.0
0
0
1
0
0
0
1
0.0
M
40.0
1184056
6592502.0
63166.0
27.0
19.0
434.0
0
0
1
0
1
0
0
0.0
F
30.0
1184057
6592519.0
6188865.0
159.0
52.0
343.0
0
0
1
0
0
0
1
1.0
F
20.0
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
F
30.0
967232 rows × 15 columnsIn [916]:
In [927]:
Out[927]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
3
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
F
40.0
5
68.0
4237632.0
44.0
33.0
418.0
1
0
1
0
0
0
1
0.0
F
30.0
9
156.0
7112398.0
181.0
236.0
1937.0
1
0
1
0
0
0
1
0.0
F
40.0
10
159.0
1206445.0
177.0
252.0
3733.0
1
0
1
0
1
0
0
4.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184053
6592481.0
949356.0
15.0
150.0
2351.0
0
0
1
0
1
0
0
0.0
F
30.0
1184054
6592481.0
962852.0
7.0
145.0
3632.0
0
0
1
0
1
0
0
0.0
F
30.0
1184056
6592502.0
63166.0
27.0
19.0
434.0
0
0
1
0
1
0
0
0.0
F
30.0
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
F
30.0
699883 rows × 15 columnsIn [929]:
Out[929]:
In [930]:
Out[930]:
In [932]:
Out[932]:
In [935]:
Out[935]:
In [942]:
In [943]:
Out[943]:
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_AGE
3
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
40.0
4
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
40.0
5
44.0
33.0
418.0
1
0
1
0
0
0
1
0.0
30.0
9
181.0
236.0
1937.0
1
0
1
0
0
0
1
0.0
40.0
10
177.0
252.0
3733.0
1
0
1
0
1
0
0
4.0
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
1184053
15.0
150.0
2351.0
0
0
1
0
1
0
0
0.0
30.0
1184054
7.0
145.0
3632.0
0
0
1
0
1
0
0
0.0
30.0
1184056
27.0
19.0
434.0
0
0
1
0
1
0
0
0.0
30.0
1184058
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
30.0
1184059
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
30.0
699883 rows × 12 columns
이제 아까 위에서 했던 것과 똑같이 전처리를 진행합니다. 쭉쭉 ~ ~ ~! 🚗 ~ 🚗 ~ 🚗
In [944]:
Out[944]:
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_AGE_30.0
CLNT_AGE_40.0
3
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
0
1
4
92.0
44.0
1343.0
1
0
1
0
0
0
1
3.0
0
1
5
44.0
33.0
418.0
1
0
1
0
0
0
1
0.0
1
0
9
181.0
236.0
1937.0
1
0
1
0
0
0
1
0.0
0
1
10
177.0
252.0
3733.0
1
0
1
0
1
0
0
4.0
0
1
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184053
15.0
150.0
2351.0
0
0
1
0
1
0
0
0.0
1
0
1184054
7.0
145.0
3632.0
0
0
1
0
1
0
0
0.0
1
0
1184056
27.0
19.0
434.0
0
0
1
0
1
0
0
0.0
1
0
1184058
33.0
110.0
581.0
0
0
1
0
0
0
1
0.0
1
0
1184059
32.0
307.0
3493.0
0
0
1
0
0
0
1
0.0
1
0
699883 rows × 13 columns
In [946]:
In [953]:
In [950]:
In [954]:
In [951]:
In [955]:
Modeling
1. Decision Tree :: 0.6854768997763918
In [969]:
Out[969]:
In [964]:
2. Random Forest :: 0.6559791711316966
In [963]:
Out[963]:
In [ ]:
In [966]:
3. XGBoost :: 0.6615356527675248
In [959]:
In [961]:
Out[961]:
In [967]:
[결론]
30, 40대 여성의 데이터로만 분석한 결과도 위와 차이가 없었다.
recall 값을 보면 오히려 앙상블 기법을 적용한 게 훨씬 점수가 떨어져 나온다! 샘플링 크기의 차이 때문일까?
차라리 이런 큰 데이터들은 앙상블 하려고 train set 크기를 줄이는 것보다 많은 train 가지고 간단한 모델에 적합시키는 게 나을 수도 있겠다고 생각했다.
Step 9. 구매이력 변수를 새로 만들자
너무 멀리까지 와버려서 솔직히 변수를 새로 만드는 게 겁이 난다. 또 얼만큼 더 해야하는걸까?
하지만 첫 단추를 잘못끼웠다면 다시 처음부터 끼우는 게 맞다....
또, 추가적으로 처음에 제거하였던 HITS_SEQ도 분석에 포함시켜보고자 한다. [HITS_SEQ] Web/App에서 페이지 또는 화면 클릭, 이벤트 참여, 검색 등 방문자의 행위에 대해 순서대로 배열된 일련번호. 세션 내에서 발생되며, 첫번째 행위에 대해서는 1로 설정됨 (즉 몇 번째 행위에서 구매가 일어났는지에 대한 지표로, 이는 product에만 있으므로 구매가 일어나지 않은 경우에 대해서는 0으로 결측값 처리하자.)
How! 구매이력 변수는 어떻게 만들까?
PRODUCT 데이터 셋에는 구매가 발생했을 때 해당 CLNT_ID, SESS_ID와 어떤 상품을 구매하였는지에 대한 정보가 있다.
이를 COUNT하여 구매이력(BUY_CNT)변수로 이용하자는 것이 기본 아이디어
주의할 점
그런데 이때, 구매 시 두 개의 다른 상품을 구매하였다면 구매 한 건에 대해 ROW가 두 개 생긴다. ==> SESS_ID가 같다면 동일한 구매로 간주, SESS_ID가 다른 경우에만 다른 날짜에 구매한 것으로 간주하여 이 경우 BUY_CNT를 1증가시킴.
session 정보는 있으나 구매로 이어진 적 없는 경우에는 0, 첫 번째 구매 시 buy_cnt는 1, 두 번째 구매 시 buy_cnt는 2로 둔다.
구매이력 변수를 만들자!
In [1004]:
In [1007]:
Out[1007]:
CLNT_ID
SESS_ID
HITS_SEQ
PD_C
PD_ADD_NM
PD_BRA_NM
PD_BUY_AM
PD_BUY_CT
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
ZON_NM
CITY_NM
307620
25
6059256
8
715072
(not set)
[이롬]
47,000
1
204
20180621
7.0
99
desktop
Gyeonggi-do
Osan-si
32606
25
5317297
8
598634
피테로마 때박살:피테로마 때박살 120종
[유씨지]
39,800
1
213
20180703
33.0
865
desktop
Gyeonggi-do
Hwaseong-si
284679
33
10548225
13
605825
(not set)
[슈에무라]
49,000
1
2
20180407
48.0
1,776
desktop
Seoul
Seoul
237322
56
2108568
57
425529
선택:데일리 디펜스 / 1개
비욘드
4,500
1
92
20180826
44.0
1,343
mobile
Busan
Busan
237323
56
2108568
57
425529
선택:딥모이 / 1개
비욘드
4,500
1
92
20180826
44.0
1,343
mobile
Busan
Busan
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
212471
6592519
2373889
127
737746
색상:403 / 1개
입생로랑
43,000
1
221
20180821
128.0
2,762
mobile
Gyeongsangbuk-do
Pohang-si
44012
6592524
8220549
19
813954
색상:돌체 비타 / 1개
나스
40,000
1
10
20180516
75.0
851
mobile
Seoul
Seoul
44013
6592524
8220549
19
817564
1개
맥
47,000
1
10
20180516
75.0
851
mobile
Seoul
Seoul
44014
6592524
8220549
19
748742
1개
맥
48,000
1
10
20180516
75.0
851
mobile
Seoul
Seoul
392067
6592544
8270794
14
706193
타입:세트
[설화수]
52,000
1
1
20180515
13.0
105
desktop
Gyeonggi-do
Siheung-si
403714 rows × 15 columnsIn [1020]:
In [ ]:
In [1058]:
Out[1058]:
In [1044]:
Out[1044]:
CLNT_ID
BUY_CNT
SESS_ID
307620
25
1
6059256
32606
25
2
5317297
284679
33
1
10548225
237322
56
1
2108568
237323
56
1
2108568
...
...
...
...
212471
6592519
3
2373889
44012
6592524
1
8220549
44013
6592524
1
8220549
44014
6592524
1
8220549
392067
6592544
1
8270794
403714 rows × 3 columns
필요없는 나머지 변수는 전부 드랍합니다. 이제 이 데이터셋을 CLNT_ID와 SESS_ID를 기준으로 합쳐봅시다!
여기서부터 전처리 다시 하는 과정이오니 넘겨주세요
그저 다른 점 하나는 HITS_SEQ가 있다는 것.....In [972]:
Out[972]:
CLNT_ID
SESS_ID
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
ZON_NM
CITY_NM
HITS_SEQ
PD_C
PD_ADD_NM
PD_BRA_NM
PD_BUY_AM
PD_BUY_CT
0
8.0
6964877.0
7.0
2018-06-06
38.0
366.0
mobile
Gyeonggi-do
Gwangmyeong-si
NaN
NaN
NaN
NaN
NaN
NaN
1
25.0
5317297.0
213.0
2018-07-03
33.0
865.0
desktop
Gyeonggi-do
Hwaseong-si
8.0
598634.0
피테로마 때박살:피테로마 때박살 120종
[유씨지]
39800.0
1.0
2
25.0
6059256.0
204.0
2018-06-21
7.0
99.0
desktop
Gyeonggi-do
Osan-si
8.0
715072.0
(not set)
[이롬]
47000.0
1.0
3
25.0
8113243.0
160.0
2018-05-18
28.0
1540.0
desktop
Gyeonggi-do
Osan-si
NaN
NaN
NaN
NaN
NaN
NaN
4
25.0
9506206.0
111.0
2018-04-25
12.0
242.0
desktop
Gyeonggi-do
Hwaseong-si
NaN
NaN
NaN
NaN
NaN
NaN
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1828908
6592524.0
8220549.0
10.0
2018-05-16
75.0
851.0
mobile
Seoul
Seoul
19.0
813954.0
색상:돌체 비타 / 1개
나스
40000.0
1.0
1828909
6592536.0
61570.0
67.0
2018-09-30
57.0
567.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
1828910
6592536.0
1078369.0
62.0
2018-09-12
50.0
525.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
1828911
6592536.0
1347403.0
57.0
2018-09-08
239.0
1214.0
mobile
Busan
Busan
NaN
NaN
NaN
NaN
NaN
NaN
1828912
6592544.0
8270794.0
1.0
2018-05-15
13.0
105.0
desktop
Gyeonggi-do
Siheung-si
14.0
706193.0
타입:세트
[설화수]
52000.0
1.0
1184063 rows × 15 columnsIn [974]:
In [976]:
Out[976]:
In [977]:
Out[977]:
CLNT_ID
SESS_ID
SESS_SEQ
SESS_DT
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
DVC_CTG_NM
HITS_SEQ
class
1
25.0
5317297.0
213.0
2018-07-03
33.0
865.0
desktop
8.0
1
2
25.0
6059256.0
204.0
2018-06-21
7.0
99.0
desktop
8.0
1
9
33.0
10548225.0
2.0
2018-04-07
48.0
1776.0
desktop
13.0
1
10
56.0
2108568.0
92.0
2018-08-26
44.0
1343.0
mobile
57.0
1
11
56.0
2108568.0
92.0
2018-08-26
44.0
1343.0
mobile
57.0
1
...
...
...
...
...
...
...
...
...
...
1828904
6592524.0
7212211.0
33.0
2018-06-02
110.0
581.0
mobile
NaN
0
1828905
6592524.0
7235959.0
32.0
2018-06-01
307.0
3493.0
mobile
NaN
0
1828909
6592536.0
61570.0
67.0
2018-09-30
57.0
567.0
mobile
NaN
0
1828910
6592536.0
1078369.0
62.0
2018-09-12
50.0
525.0
mobile
NaN
0
1828911
6592536.0
1347403.0
57.0
2018-09-08
239.0
1214.0
mobile
NaN
0
1184063 rows × 9 columnsIn [978]:
In [979]:
Out[979]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
HITS_SEQ
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
1
25.0
5317297.0
213.0
33.0
865.0
8.0
1
1
0
0
0
0
1
2
25.0
6059256.0
204.0
7.0
99.0
8.0
1
1
0
0
0
0
1
9
33.0
10548225.0
2.0
48.0
1776.0
13.0
1
1
0
0
0
1
0
10
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
0
0
1
11
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
0
0
1
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1828904
6592524.0
7212211.0
33.0
110.0
581.0
NaN
0
0
1
0
0
0
1
1828905
6592524.0
7235959.0
32.0
307.0
3493.0
NaN
0
0
1
0
0
0
1
1828909
6592536.0
61570.0
67.0
57.0
567.0
NaN
0
0
1
0
1
0
0
1828910
6592536.0
1078369.0
62.0
50.0
525.0
NaN
0
0
1
0
1
0
0
1828911
6592536.0
1347403.0
57.0
239.0
1214.0
NaN
0
0
1
0
1
0
0
1184063 rows × 13 columnsIn [982]:
Out[982]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
HITS_SEQ
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
0
25.0
5317297.0
213.0
33.0
865.0
8.0
1
1
0
0
0
0
1
NaN
1
25.0
6059256.0
204.0
7.0
99.0
8.0
1
1
0
0
0
0
1
NaN
2
33.0
10548225.0
2.0
48.0
1776.0
13.0
1
1
0
0
0
1
0
12.0
3
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
0
0
1
3.0
4
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
0
0
1
3.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184058
6592524.0
7212211.0
33.0
110.0
581.0
NaN
0
0
1
0
0
0
1
NaN
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
NaN
0
0
1
0
0
0
1
NaN
1184060
6592536.0
61570.0
67.0
57.0
567.0
NaN
0
0
1
0
1
0
0
NaN
1184061
6592536.0
1078369.0
62.0
50.0
525.0
NaN
0
0
1
0
1
0
0
1.0
1184062
6592536.0
1347403.0
57.0
239.0
1214.0
NaN
0
0
1
0
1
0
0
3.0
1184063 rows × 14 columns
In [983]:
Out[983]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
HITS_SEQ
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
SUM_SEARCH
CLNT_GENDER
CLNT_AGE
0
25.0
5317297.0
213.0
33.0
865.0
8.0
1
1
0
0
0
0
1
NaN
NaN
NaN
1
25.0
6059256.0
204.0
7.0
99.0
8.0
1
1
0
0
0
0
1
NaN
NaN
NaN
2
33.0
10548225.0
2.0
48.0
1776.0
13.0
1
1
0
0
0
1
0
12.0
NaN
NaN
3
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
0
0
1
3.0
F
40.0
4
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
0
0
1
3.0
F
40.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184058
6592524.0
7212211.0
33.0
110.0
581.0
NaN
0
0
1
0
0
0
1
NaN
F
30.0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
NaN
0
0
1
0
0
0
1
NaN
F
30.0
1184060
6592536.0
61570.0
67.0
57.0
567.0
NaN
0
0
1
0
1
0
0
NaN
NaN
NaN
1184061
6592536.0
1078369.0
62.0
50.0
525.0
NaN
0
0
1
0
1
0
0
1.0
NaN
NaN
1184062
6592536.0
1347403.0
57.0
239.0
1214.0
NaN
0
0
1
0
1
0
0
3.0
NaN
NaN
1184063 rows × 16 columnsIn [995]:
In [996]:
In [997]:
In [998]:
In [999]:
Out[999]:
In [1001]:
Out[1001]:
In [1247]:
In [1248]:
Out[1248]:
여기까지 HITS_SEQ 변수를 포함하여 만든 데이터셋 생성 완료
In [1249]:
Out[1249]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
HITS_SEQ
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
...
CLNT_GENDER_F
CLNT_GENDER_M
CLNT_AGE_10.0
CLNT_AGE_20.0
CLNT_AGE_30.0
CLNT_AGE_40.0
CLNT_AGE_50.0
CLNT_AGE_60.0
CLNT_AGE_70.0
CLNT_AGE_80.0
3
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
...
1
0
0
0
0
1
0
0
0
0
4
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
...
1
0
0
0
0
1
0
0
0
0
5
68.0
4237632.0
44.0
33.0
418.0
31.0
1
0
1
0
...
1
0
0
0
1
0
0
0
0
0
6
135.0
253618.0
29.0
40.0
697.0
21.0
1
0
1
0
...
0
1
0
0
0
1
0
0
0
0
9
156.0
7112398.0
181.0
236.0
1937.0
231.0
1
0
1
0
...
1
0
0
0
0
1
0
0
0
0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1184055
6592482.0
5743284.0
33.0
12.0
112.0
0.0
0
0
1
0
...
0
1
0
0
0
1
0
0
0
0
1184056
6592502.0
63166.0
27.0
19.0
434.0
0.0
0
0
1
0
...
1
0
0
0
1
0
0
0
0
0
1184057
6592519.0
6188865.0
159.0
52.0
343.0
0.0
0
0
1
0
...
1
0
0
1
0
0
0
0
0
0
1184058
6592524.0
7212211.0
33.0
110.0
581.0
0.0
0
0
1
0
...
1
0
0
0
1
0
0
0
0
0
1184059
6592524.0
7235959.0
32.0
307.0
3493.0
0.0
0
0
1
0
...
1
0
0
0
1
0
0
0
0
0
967232 rows × 24 columnsIn [1250]:
Out[1250]:
CLNT_ID
BUY_CNT
SESS_ID
307620
25
1
6059256
32606
25
2
5317297
284679
33
1
10548225
237322
56
1
2108568
237323
56
1
2108568
...
...
...
...
212471
6592519
3
2373889
44012
6592524
1
8220549
44013
6592524
1
8220549
44014
6592524
1
8220549
392067
6592544
1
8270794
403714 rows × 3 columnsIn [1251]:
Out[1251]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
HITS_SEQ
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
...
CLNT_GENDER_M
CLNT_AGE_10.0
CLNT_AGE_20.0
CLNT_AGE_30.0
CLNT_AGE_40.0
CLNT_AGE_50.0
CLNT_AGE_60.0
CLNT_AGE_70.0
CLNT_AGE_80.0
BUY_CNT
0
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
1
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
2
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
3
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
4
68.0
4237632.0
44.0
33.0
418.0
31.0
1
0
1
0
...
0
0
0
1
0
0
0
0
0
1.0
5
135.0
253618.0
29.0
40.0
697.0
21.0
1
0
1
0
...
1
0
0
0
1
0
0
0
0
1.0
6
156.0
7112398.0
181.0
236.0
1937.0
231.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
7
159.0
1206445.0
177.0
252.0
3733.0
268.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
8
222.0
3257833.0
29.0
47.0
2309.0
35.0
1
0
1
0
...
0
0
0
1
0
0
0
0
0
1.0
9
258.0
6639976.0
36.0
105.0
1774.0
97.0
1
0
1
0
...
0
0
0
1
0
0
0
0
0
1.0
10
266.0
3904945.0
9.0
37.0
367.0
38.0
1
0
1
0
...
0
0
0
1
0
0
0
0
0
1.0
11
305.0
6534328.0
21.0
193.0
2453.0
106.0
1
0
1
0
...
1
0
0
0
1
0
0
0
0
1.0
12
305.0
6534328.0
21.0
193.0
2453.0
106.0
1
0
1
0
...
1
0
0
0
1
0
0
0
0
1.0
13
305.0
6534328.0
21.0
193.0
2453.0
178.0
1
0
1
0
...
1
0
0
0
1
0
0
0
0
1.0
14
305.0
6534328.0
21.0
193.0
2453.0
178.0
1
0
1
0
...
1
0
0
0
1
0
0
0
0
1.0
15
421.0
10813914.0
21.0
92.0
422.0
78.0
1
0
1
0
...
0
0
1
0
0
0
0
0
0
1.0
16
421.0
10813914.0
21.0
92.0
422.0
78.0
1
0
1
0
...
0
0
1
0
0
0
0
0
0
1.0
17
421.0
10813914.0
21.0
92.0
422.0
78.0
1
0
1
0
...
0
0
1
0
0
0
0
0
0
1.0
18
421.0
10813914.0
21.0
92.0
422.0
78.0
1
0
1
0
...
0
0
1
0
0
0
0
0
0
1.0
19
434.0
6430259.0
278.0
15.0
89.0
16.0
1
0
1
0
...
0
0
1
0
0
0
0
0
0
2.0
20 rows × 25 columns
문제가 생겼다 ......
데이터가 약 5만개 늘어났습니다.
left join을 하면 left쪽, 즉 prod_sess_buy의 row 수인 967232개로 생성이 되어야 하는데 왜이럴까요?
바로.. key가 고유하지 않아서 입니다. (같은 sess_id를 가진 row가 a셋에 2개, b셋에 2개있다면, 그 두 개의 모든 조합인 4개가 결과 셋에 생성된 것입니다.)
이는 product 데이터 셋이 구매 건수로 생성되지 않고 구매물품을 기준으로 생성되어서 그렇습니다. 예를 들어 하나의 SESS_ID 77이라는 사람이 양말과 신발을 구매하였다면 Product에는 77 양말 77 신발 로 들어가기 때문에 결국 이 조합은 key로서의 역할을 하지 못하는 것이지요. 애초에 Product 셋을 보고 중복된 값에 대해 먼저 처리를 해주었으면 좋았겠지만, 미처 생각하지 못한 제 잘못입니다. 분석 처음부터 잘못되었다고 생각할 수 있겠네요. 모든 join에서 저는 CLNT_ID, SESS_ID의 조합이 KEY의 역할을 하도록 중복을 없애는 전처리를 먼저 수행해주었어야 했습니다. 그걸 잊은 채 열심히 join 해버렸더니 결국 이 사단이 났네요 ㅠㅜ
다시 처음으로 돌아가기엔 저는 6주차 과제를 해야해서요 ㅎㅎ,, 일단 아쉬운 마음은 뒤로 하고 이 상황을 어떻게 극복할 수 있을까 하다가, 중복 행에 대해서 삭제해주는 함수 duplicate를 이용해보기로 하였습니다.In [1252]:
Out[1252]:
In [1253]:
Out[1253]:
In [1254]:
In [1255]:
Out[1255]:
CLNT_ID
SESS_ID
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
HITS_SEQ
class
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
...
CLNT_GENDER_M
CLNT_AGE_10.0
CLNT_AGE_20.0
CLNT_AGE_30.0
CLNT_AGE_40.0
CLNT_AGE_50.0
CLNT_AGE_60.0
CLNT_AGE_70.0
CLNT_AGE_80.0
BUY_CNT
0
56.0
2108568.0
92.0
44.0
1343.0
57.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
4
68.0
4237632.0
44.0
33.0
418.0
31.0
1
0
1
0
...
0
0
0
1
0
0
0
0
0
1.0
5
135.0
253618.0
29.0
40.0
697.0
21.0
1
0
1
0
...
1
0
0
0
1
0
0
0
0
1.0
6
156.0
7112398.0
181.0
236.0
1937.0
231.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
7
159.0
1206445.0
177.0
252.0
3733.0
268.0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
1.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1391151
6592482.0
5743284.0
33.0
12.0
112.0
0.0
0
0
1
0
...
1
0
0
0
1
0
0
0
0
0.0
1391152
6592502.0
63166.0
27.0
19.0
434.0
0.0
0
0
1
0
...
0
0
0
1
0
0
0
0
0
0.0
1391153
6592519.0
6188865.0
159.0
52.0
343.0
0.0
0
0
1
0
...
0
0
1
0
0
0
0
0
0
0.0
1391154
6592524.0
7212211.0
33.0
110.0
581.0
0.0
0
0
1
0
...
0
0
0
1
0
0
0
0
0
0.0
1391155
6592524.0
7235959.0
32.0
307.0
3493.0
0.0
0
0
1
0
...
0
0
0
1
0
0
0
0
0
0.0
877238 rows × 25 columns
다시 모델링 해봅시다
In [1256]:
In [1257]:
Out[1257]:
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
HITS_SEQ
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
...
CLNT_GENDER_M
CLNT_AGE_10.0
CLNT_AGE_20.0
CLNT_AGE_30.0
CLNT_AGE_40.0
CLNT_AGE_50.0
CLNT_AGE_60.0
CLNT_AGE_70.0
CLNT_AGE_80.0
BUY_CNT
1044031
12.0
30.0
239.000000
0.0
0
1
0
0
0
1
...
0
0
1
0
0
0
0
0
0
0.0
860565
178.0
1.0
1405.188022
0.0
0
1
0
0
0
1
...
0
0
0
0
1
0
0
0
0
0.0
888770
175.0
32.0
2546.000000
0.0
0
1
0
0
1
0
...
0
0
0
1
0
0
0
0
0
0.0
1323381
79.0
36.0
735.000000
0.0
0
1
0
1
0
0
...
0
0
0
0
1
0
0
0
0
0.0
1389236
3.0
150.0
1230.000000
0.0
0
1
0
1
0
0
...
0
0
0
0
1
0
0
0
0
0.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
335240
8.0
42.0
424.000000
49.0
0
1
0
1
0
0
...
0
0
0
0
1
0
0
0
0
1.0
345653
355.0
116.0
7955.000000
111.0
0
1
0
0
0
1
...
0
0
0
1
0
0
0
0
0
3.0
594412
1385.0
70.0
1427.000000
42.0
0
1
0
0
1
0
...
0
0
0
0
0
1
0
0
0
1.0
988601
1218.0
52.0
757.000000
0.0
0
1
0
0
0
1
...
0
0
0
1
0
0
0
0
0
0.0
839653
590.0
102.0
609.000000
0.0
0
0
1
0
1
0
...
0
0
0
0
1
0
0
0
0
0.0
701790 rows × 22 columnsIn [1258]:
Out[1258]:
SESS_SEQ
TOT_PAG_VIEW_CT
TOT_SESS_HR_V
HITS_SEQ
DVC_CTG_NM_desktop
DVC_CTG_NM_mobile
DVC_CTG_NM_tablet
SESS_DT_M_가을
SESS_DT_M_봄
SESS_DT_M_여름
...
CLNT_GENDER_M
CLNT_AGE_10.0
CLNT_AGE_20.0
CLNT_AGE_30.0
CLNT_AGE_40.0
CLNT_AGE_50.0
CLNT_AGE_60.0
CLNT_AGE_70.0
CLNT_AGE_80.0
BUY_CNT
1216528
11.0
29.0
254.0
0.0
0
1
0
0
1
0
...
0
0
1
0
0
0
0
0
0
0.0
1291017
902.0
62.0
341.0
0.0
0
1
0
0
1
0
...
0
0
1
0
0
0
0
0
0
0.0
832395
461.0
262.0
3754.0
0.0
0
1
0
1
0
0
...
0
0
0
1
0
0
0
0
0
0.0
1189923
3.0
57.0
1285.0
0.0
0
1
0
0
1
0
...
0
0
0
1
0
0
0
0
0
0.0
1154212
10.0
18.0
126.0
0.0
0
1
0
0
1
0
...
0
0
0
1
0
0
0
0
0
0.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
803944
7.0
59.0
550.0
0.0
0
1
0
0
0
1
...
1
0
0
0
1
0
0
0
0
0.0
941744
269.0
51.0
940.0
0.0
0
1
0
0
0
1
...
0
0
0
0
1
0
0
0
0
0.0
1246892
8.0
223.0
1954.0
0.0
0
1
0
0
1
0
...
0
0
1
0
0
0
0
0
0
0.0
908786
253.0
464.0
4453.0
0.0
0
1
0
0
0
1
...
0
0
0
0
1
0
0
0
0
0.0
335328
68.0
95.0
816.0
90.0
0
1
0
0
1
0
...
0
0
0
1
0
0
0
0
0
1.0
175448 rows × 22 columnsIn [1259]:
Out[1259]:
In [1260]:
Out[1260]:
In [1261]:
Out[1261]:
In [1262]:
Out[1262]:
In [1263]:
Out[1263]:
In [1264]:
In [1265]:
Out[1265]:
In [1266]:
Out[1266]:
말도 안 되는 값이 나왔습니다. 아무래도 새로 넣은 변수 HITS_SEQ, BUY_CNT가 구매 한 고객으로부터만 얻을 수 있는 값이기 때문인 것 같습니다. HITS_SEQ는 구매까지의 페이지 창 클릭수라고 볼 수 있고 BUY_CNT는 구매한 고객의 구매이력 변수이나, 이 또한 PRODUCT 데이터 셋에서만 만들 수 있었기 때문에 SESSION 값만 있는 고객에 대해서는 0이 들어갑니다. 각각 BUY_CNT만 없앴을 때, HITS_SEQ만 없앴을 때를 비교해 보았는데 둘 중 어느 하나만 있더라도 설명력은 1.0 혹은 0.99가 나왔으며 두 변수 모두 없었을 때만 지금까지의 분석 결과와 비슷한 SCORE가 나왔습니다. 결과적으로 모델 자체의 성능은 올랐지만.... 좋은 결과는 아니라고 볼 수 있었습니다. 하지만 좋은 경험이라고 생각하겠습니다.
In [1268]:
In [1269]:
Out[1269]:
In [1270]:
Out[1270]:
그래도 마지막 분석에서 ACCURACY 0.7을 넘었습니다!!!! 위에서 열심히 했던 분석과 다른 게 하나 있다면 중복행을 제거한 것 뿐입니다. 아무래도 JOIN 과정에서 잘못되어 중복된 행이 여러 개 생긴 것도 큰 영향을 미친 것 같습니다.
느낀점
리얼한 데이터를 다루는 것은 너무나도 어렵다. 그러니 각오하고 시작하자..
데이터셋이 이처럼 분할되어 있는 경우 JOIN 할 때에도 주기적으로 상황을 체크하여 이번(KEY값으로 인한 중복행 발생)같은 사태가 발생하지 않도록 해야한다.
큼직한 성능 자체는 모델선정과 하이퍼파라미터 튜닝보다는 데이터 셋 자체 (피쳐 개수 등)의 문제로 이어진다.
피쳐 엔지니어링 시에 구현 능력이 중요하게 다가왔다. 알고리즘 문제 열심히 풀어야겠다.
다시 한 번 느끼지만 인생은 내 생각처럼 흘러가는 법이 없는 것 같다....
지금까지 배웠던 내용을 적용해볼 수 있었던 좋은 시간이었습니다. 목표 SCORE는 0.7이었는데 어쩌다보니 결국 넘기긴 했네요 .... 마지막 중복 행에 대해 제거만 했더니 이렇게 나온 걸 보니 허무하기도 합니다만... 그래도 전처리에서 어떻게 결측값을 처리할지, 모델은 어떻게 선정할 지, 하이퍼 파라미터 튜닝은 어떤 식으로 진행할 지, 모델 성능이 잘 안나온다면 원인은 무엇일지에 대해 고민해본 과정과 시간들은 헛되지 않았다고 생각합니다 밑 부분엔 멘탈이 나가서 주석이 별로 없는 점 양해부탁드리고요,, 읽으시느라 고생 많으셨습니다!
쁘이 V^--------------------^V
Last updated