분석을 하다 보면 원본 데이터의 구조가 분석 기법에 맞지 않아서 행과 열의 위치를 바꾼다거나, 특정 요인에 따라 집계를 해서 구조를 바꿔주어야 하는 경우가 있습니다.

 

재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들에 대해서 아래의 순서대로 나누어서 소개해보겠습니다.

 

 - (1) pivot(), pd.pivot_table()

 - (2) stack(), unstack()

 - (3) melt()

 - (4) wide_to_long()

 - (5) pd.crosstab() 

 

 

이번 포스팅에서는 pd.wide_to_long() 에 대해서 알아보겠습니다.

 

필요한 모듈을 불러오고, 실습에 필요한 간단한 예제 데이터셋을 만들어보겠습니다.

 

 

# importing libraries

In [1]: import numpy as np


In [2]: import pandas as pd


In [3]: from pandas import DataFrame


# setting random seed number

In [4]: np.random.seed(10)


# making an example 'wide' DataFrame

In [5]: data_wide = pd.DataFrame({"C1prd1" : {0 : "a", 1 : "b", 2 : "c"},

   ...: "C1prd2" : {0 : "d", 1 : "e", 2 : "f"},

   ...: "C2prd1" : {0 : 2.5, 1 : 1.2, 2 : .7},

   ...: "C2prd2" : {0 : 3.2, 1 : 1.3, 2 : .1},

   ...: "value" : dict(zip(range(3), np.random.randn(3)))

   ...: })

   ...:


In [6]: data_wide["seq_no"] = data_wide.index


In [7]: data_wide

Out[7]:

     C1prd1 C1prd2  C2prd1  C2prd2     value      seq_no
0       a         d         2.5       3.2      1.331587       0
1       b         e         1.2       1.3      0.715279       1
2       c          f         0.7       0.1     -1.545400       2

 

 

 

 

이제 pd.wide_to_long() 함수를 써서 데이터를 재구조화 해보겠습니다.

 

wide_to_long()은 pivot() 이나 stack() 과는 다르게 "칼럼 이름의 앞부분"과 나머지 "칼럼 이름의 뒷부분"을 구분해서, 칼럼 이름의 앞부분을 칼럼 이름으로, 칼럼 이름의 나머지 뒷부분을 행(row)의 원소로 해서 세로로 길게(long~) 쌓아 줍니다.  말로 설명해주기가 참 힘든데요, 아래의 wide_to_long() 적용 전, 후의 변화 이미지를 참고하시기 바랍니다.

 

제가 R, SAS, SPSS 다 써봤는데요, Python의 pd.wide_to_long() 함수 같은거는 본 적이 없습니다. 좀 생소하고, 처음 봤을 때 한눈에 잘 안들어왔던 유형의 데이터 재구조화 함수예요. 

 

 

 

pd.widt_to_long() 함수를 한번 사용해서 가로로 넓은 데이터(wide~)를 세로로 길게(long~) 재구조화 해보겠습니다.

 

 

  (1) pd.wide_to_long(data, ["col_prefix_1", "col_prefix_2"], i="idx_1", j="idx_2")

 

 

# reshaping a 'wide' DataFrame to a 'long' DataFrame

In [8]: data_long = pd.wide_to_long(data_wide, ["C1", "C2"], i="seq_no", j="prd")


In [9]: data_long

Out[9]:

                     value    C1    C2
seq_no prd                 
0        prd1  1.331587      2.5
1        prd1  0.715279   b     1.2
2        prd1 -1.545400   c     0.7
0        prd2  1.331587      3.2
1        prd2  0.715279   e     1.3
2        prd2 -1.545400   f     0.1

 

 

 

 

  (2) pd.wide_to_long()에 의한 index, columns 변화 비교

 

 

# data_wide (original data set) : index, columns

In [10]: data_wide.index

Out[10]: Int64Index([0, 1, 2], dtype='int64')


In [11]: data_wide.columns

Out[11]: Index(['C1prd1', 'C1prd2', 'C2prd1', 'C2prd2', 'value', 'seq_no'], dtype='object')

 


# data_long (reshaped data set) : index, columns

In [12]: data_long.index

Out[12]:

MultiIndex(levels=[[0, 1, 2], ['prd1', 'prd2']],

labels=[[0, 1, 2, 0, 1, 2], [0, 0, 0, 1, 1, 1]],

names=['seq_no', 'type'])


In [13]: data_long.columns

Out[13]: Index(['value', 'C1', 'C2'], dtype='object')

 

 

 

이상으로 pd.wide_to_long() 을 이용한 데이터 재구조화 소개를 마치겠습니다.

 

다음번 포스팅에서는 pd.crosstab() 에 대해서 알아보겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by R Friend R_Friend

데이터 재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들에 대해서 아래의 순서대로 나누어서 소개해보겠습니다.
 
 - (1) pivot(), pd.pivot_table()
 - (2) stack(), unstack()
 - (3) melt()

 - (4) wide_to_long()
 - (5) pd.crosstab() 
 
 
이번 포스팅에서는 세번째로 pd.melt() 사용법에 대해서 알아보겠습니다.

 

R 사용자라면 reshape package의 melt(), cast() 함수를 생각하면 쉽게 이해할 수 있을 것입니다. melt()는 pivot_table()과 함께 데이터 전처리 단계에서 자주 사용되곤 합니다.

 

melt() 는 ID 변수를 기준으로 원래 데이터셋에 있던 여러개의 칼럼 이름을 'variable' 칼럼에 위에서 아래로 길게 쌓아놓고, 'value' 칼럼에 ID와 variable에 해당하는 값을 넣어주는 식으로 데이터를 재구조화합니다.  말로 설명하자니 좀 어려운데요, 아래의 melt() 적용 전, 후의 이미지를 참고하시기 바랍니다.

 

 

 

 

필요한 라이브러리를 불러오고, 예제로 사용할 간단한 DataFrame을 만들어보겠습니다.

 

 

# importing libraries

In [1]: import numpy as np


In [2]: import pandas as pd


In [3]: from pandas import DataFrame

 

# making an example DataFrame

In [4]: data = DataFrame({'cust_ID' : ['C_001', 'C_001', 'C_002', 'C_002'],

   ...: 'prd_CD' : ['P_001', 'P_002', 'P_001', 'P_002'],

   ...: 'pch_cnt' : [1, 2, 3, 4],

   ...: 'pch_amt' : [100, 200, 300, 400]})

   ...:


In [5]: data

Out[5]:

  cust_ID  pch_amt  pch_cnt prd_CD
0   C_001      100        1  P_001
1   C_001      200        2  P_002
2   C_002      300        3  P_001
3   C_002      400        4  P_002

 

 

 

 

  (1) pd.melt(data, id_vars=['id1', 'id2', ...]) 를 사용한 데이터 재구조화

 

 

# melt()

In [6]: pd.melt(data, id_vars=['cust_ID', 'prd_CD'])

Out[6]:

   cust_ID prd_CD variable     value
0   C_001  P_001  pch_amt    100
1   C_001  P_002  pch_amt    200
2   C_002  P_001  pch_amt    300
3   C_002  P_002  pch_amt    400
4   C_001  P_001  pch_cnt      1
5   C_001  P_002  pch_cnt      2
6   C_002  P_001  pch_cnt      3
7   C_002  P_002  pch_cnt      4

 

 

 

 (2) pd.melt() 의 variable 이름, value 이름 부여하기 : var_name, value_name

 

 

# # melt : assigning name of variable and value

In [7]: pd.melt(data, id_vars=['cust_ID', 'prd_CD'],

   ...: var_name='pch_CD', value_name='pch_value')

Out[7]:

  cust_ID  prd_CD  pch_CD      pch_value
0   C_001  P_001   pch_amt        100
1   C_001  P_002   pch_amt        200
2   C_002  P_001   pch_amt        300
3   C_002  P_002   pch_amt        400
4   C_001  P_001   pch_cnt          1
5   C_001  P_002   pch_cnt          2
6   C_002  P_001   pch_cnt          3
7   C_002  P_002   pch_cnt          4

 

 

 

 

  (3) data vs. pd.melt() vs. pd.pivot_table() 비교해보기

 

melt()와 pivot_table() 이 비슷한거 같은데.... 뭔가 다른거 같기도 하고... 왜 비슷한것들을 여러개 만들어놔서 사람을 헷갈리게 하는 것일까 의아할 것 같습니다.

 

아래에 똑같은 data에 대해서 melt()와 pivot_table() 을 적용해보았습니다.  melt()와 pivot_table()을 적용하고 난 이후의 index와 columns 을 유심히 살펴보시기 바랍니다.  melt()는 ID가 칼럼으로 존재하는 반면에, pivot_table()은 ID가 index로 들어갔습니다.

 

 

# comparison among (a) data vs. (b) pd.melt() vs. pd.pivot_table()

 

# (a) data

In [8]: data

Out[8]:

  cust_ID  pch_amt  pch_cnt prd_CD
0   C_001      100        1  P_001
1   C_001      200        2  P_002
2   C_002      300        3  P_001
3   C_002      400        4  P_002

 


# (b) melt()

In [9]: data_melt = pd.melt(data, id_vars=['cust_ID', 'prd_CD'],

   ...: var_name='pch_CD', value_name='pch_value')


In [10]: data_melt

Out[10]:

  cust_ID prd_CD   pch_CD  pch_value
0   C_001  P_001  pch_amt        100
1   C_001  P_002  pch_amt        200
2   C_002  P_001  pch_amt        300
3   C_002  P_002  pch_amt        400
4   C_001  P_001  pch_cnt          1
5   C_001  P_002  pch_cnt          2
6   C_002  P_001  pch_cnt          3
7   C_002  P_002  pch_cnt          4


In [11]: data_melt.index

Out[11]: RangeIndex(start=0, stop=8, step=1)


In [12]: data_melt.columns

Out[12]: Index(['cust_ID', 'prd_CD', 'pch_CD', 'pch_value'], dtype='object')

 


# (c) pd.pivot_table()

In [13]: data_melt_pivot = pd.pivot_table(data_melt, index=['cust_ID', 'prd_CD'],

    ...: columns='pch_CD', values='pch_value',

    ...: aggfunc=np.mean)


In [14]: data_melt_pivot

Out[14]:

pch_CD             pch_amt   pch_cnt
cust_ID prd_CD                 
C_001   P_001       100        1
           P_002       200        2
C_002   P_001       300        3
           P_002       400        4


In [15]: data_melt_pivot.index

Out[15]:

MultiIndex(levels=[['C_001', 'C_002'], ['P_001', 'P_002']],

labels=[[0, 0, 1, 1], [0, 1, 0, 1]],

names=['cust_ID', 'prd_CD'])


In [16]: data_melt_pivot.columns

Out[16]: Index(['pch_amt', 'pch_cnt'], dtype='object', name='pch_CD')

 

 

 

이상으로 Pytho pandas의 melt() 함수를 가지고 데이터 재구조화하는 방법에 대한 소개를 마치겠습니다.

 

다음번 포스팅에서는 wide_to_long() 함수에 대해서 알아보겠습니다.

 

 

 

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by R Friend R_Friend

박근혜 정부의 '최순실 국정농단' 사태로 온 나라가 난리도 아닙니다.  박근혜 댓통령이 부끄러움이 무엇인지를 알고 있다면, 대한민국 이 나라를 조금이라도 위하는 마음이 있다면 조속한 국정 정상화를 위해 즉각 퇴진하는 것이 마땅한 도리라고 보는데요, "평화로이 청와대에서 크리스마스를 보냈다"는 박근혜 댓통령을 보고 있노라니 역사에 어찌 기록이 되려고 저러나 참 말도 안나옵니다.

 

비선실세로 국정을 농락한 박근혜 대통령과 최순실 일당, 그리고 청문회 기간 중에 위증 공모하는 새누리당이 우리나라의 수치라면, 국민은 위대했습니다. 이 추운 날씨에도 주말이면 수십, 수백만의 국민들이 박근혜의 즉각 퇴진, 구속을 요구하면 촛불집회를 이어가고 있으니 말입니다. 저도 가족들과 같이 몇 번 촛불집회에 나가기는 했습니다만, 매번 가지는 못했습니다.  이에 거리에서 귀한 시간 내서 꾸준히 초불집회 나가주신 분들에 대한 빚진 마음과 고마움을 담아, 블로그 글로라도 뭔가 보답(?)을 하고자 몇자 적어봅니다.    

 

글의 요지는 제목처럼 '박근혜, 최순실 게이트'의 박영수 팀검팀에게 이제 데이터 과학자가 필요하다는 내용입니다. 

 

지난주 청문회 보시면서 '모르쇠'로 일관하는 능구렁이 김기춘, 미꾸라지 우병우씨를 보면서 속으로 화 많이 나셨지요?

 

박근혜 정부 권력의 실세 중의 실세, 핵심 중의 핵심이었던 김기춘 전 비서실장, 우병우 전 민정수석이 아 글쎄, 최순실을 "모른다"고 합니다. (풉~ ....  순도 99.99% 거짓말?)

 

 

 

 

위의 이미지는 한겨레 신문에서 우병우, 김기춘 검색해서 사진이랑 기사 머리글 스크랩해 본건데요, 두 증인의 "모른다" 답변에 대해 위원들의 질의가 날카롭지 못했고 "죄를 인정"하게 하는데 한계가 있었다는 지적입니다.

 

그나마 주갤(디씨인사이드 주식갤러리) 네티즌의 제보가 결정적인 역할을 해서 모르쇠 김기춘을 당황시키고 "(최순실) 이름을 못들었다 할 수 없겠다"는 증원을 이끌어낸 성과가 있었습니다.

 

우리는 주갤러가 보여준 '증거'의 힘, 'fact'의 위력을 경험했습니다.  만약 데이터 과학자가 특검팀에 합류한다면 추가적인 '증거', 'fact'를 찾아낼 수 있지 않을까 하는 기대로 이 블로그를 써봅니다. (이미 합류해서 열심히 분석을 하고 있을지도 모르지요. 요즘 과학수사대 얘기도 종종 나오곤 하니깐요)

 

손예진이 주연한 "비밀은 없다"라는 영화 보셨는지요?  역사 이래 요즘 처럼 우리의 일거수 일투족이 디지털화 되어서 네트워크 저 너머의 DB에 우리도 의식하지 못하는 사이에 차곡차곡 쌓이는 시절이 없었습니다. 이제 정말 "비밀(privacy)이 없는 시대"에 우리는 살고 있습니다. 데이터 과학자가 범죄자를 옴짝달짝 못하게 하는 증거를 찾는데 데이터가 유용하게 사용될 수 있을 것입니다.

 

제가 주목하는 데이터는 민주당의 안민석 의원이 국회에서 제기한 "박근혜 대통령 대포폰 사용 의혹"입니다.  최순실 조카 장시호씨가 대포폰 6대를 개설했고, 박근혜 대통령도 그중에 한대를 사용했을 거라는 의혹입니다.

 

* 화면캡처 출처 : https://www.youtube.com/watch?v=2io2pROsRQo

 

 

의혹으로 제기된 6대의 대포폰이 만약 사실이라면요... 6대 대포폰 사용자의 후보를 추측해볼 수 있을 것같습니다.

 

핸드폰을 사용할 때 발생되는 데이터(Call Detail Record, Packet Data 등)의 특징을 들자면,

 - (1) 누가 (who)

 - (2) 언제, 얼마의 시간동안 (when, how long)

 - (3) 어디서 (where), 이동경로 (moving route)

 - (4) 누구랑 (with whom)

 - (5) 무엇을 (what) : 통화, 문자메시지, 메신저 채팅, 인터넷 검색, 스마트폰 앱 실행 등...

 - (6) 무슨 컨텐츠로 (which contents, message) : 문자메시지 내용, 채팅 내용, 검색 키워드, 접속 사이트 주소, 로그....

 

등 민감한 정보들이 자동으로, 실시간으로, 꼬박꼬박 생성이 된다는 것입니다.  요 몇년 사이에 모든 이동통신사가 Big Data 도입한다고 난리였기 때문에, 아마도 하둡 파일 시스템에 원천 데이터의 몇 년치 데이터를 잘 저장해두었을 것으로 추측해봅니다.

 

이들은 극히 민감한 개인정보들 이므로 '개인정보 비식별화', '암호화' 되어서 이동통신사 DB에 저장이 될거고, 조회도 아무나 못하고, 요금정산(billing) 등의 용도나 NW 효율화, 최적화 등의 주로 사용이 될것 같고요, 마케팅에도 비식화 조건하에 제한적으로 사용이 될것 같습니다.

 

근데, 이번 '박근혜, 최순실 게이트'는 워낙 국가의 명운이 걸린 위중한 사안이므로 특검팀에서 법원으로 부터 수사 영장을 받으면 이동통신사 DB도 분석에 사용할 수 있지 않을까 짐작해봅니다.

(덧글 : 2015년 새누리당이 주도해서 통과시켰던 '테러방지법'을 들여다 보면 법원 영장과 서면 요청을 거치면 개인정보, 통신기록, 위치정보 수집, 추적 권한을 국가정보원에 허용하는 것이 주된 내용입니다. 국정원은 마음만 먹으면 '거의 모든 사적인 비밀'을 알 수 있는 신적인 조직, 무시무시한 조직이 된거지요)

 

대포폰의 경우는 '(1) 누가(who)' 를 알 수 없다 (개통 등록자의 profile이 거짓 정보일 것이므로...)는 점인데요, 데이터 과학자(data scientist)가 도움을 줄 수 있는 가상의 시나리오를 써보겠습니다. (잘못한 사람은 벌을 받으면 좋겠다는 희망사항이 섞인, 소설같은 분석 시나리오인데요, 분석한다는 사람은 청문회를 보고나서 이렇게 생각하기도 하는구나...하고 봐주시면 좋겠습니다.)

 

 

[ 통신, 위치 정보 분석 시나리오 ]

  • (1). 2012년 박근혜 정부 출범 이후 올해 2016년 11월까지 '청와대 위치'에서 수신, 발신 이력이 있는 모든 핸드폰의 번호를 조회한다 (=> 이동통신사 기지국 삼각측량으로 위치 추정 가능)
  • (2). (1)번에서 추출한 핸드폰 번호의 등록자, 사용자 정보를 추출한다
  • (3). (2)번에서 작성한 '핸드폰 등록자, 사용자' 정보와 '청와대 근무자 정보'를 비교한다.
  • (4). (3)의 작업 결과 '청와대 근무자 정보'와 매핑이 안되는 핸드폰 번호를 선별한다.
  • (5). (4)번에서 선별된 핸드폰 번호 중에서 대포폰이 걸려들면 (희망사항....) 
  • (6). 이 대포폰을 중심으로 '통화, 문자 송/수신 Network'를 생성 (아래 Network 이미지들 참고)

 

 [ 사담 후세인의 네트워크 ]

 

* 출처 : 'Network Science', barabasi, (http://barabasilab.neu.edu/networksciencebook/download/network_science_November_Ch1_2012.pdf)

 

 

[ 조직 내부에서 실제 일어나고 있는 상호작용 네트워크의 이해 ]

 

 

* 출처 : 'Network Science', barabasi, (http://barabasilab.neu.edu/networksciencebook/download/network_science_November_Ch1_2012.pdf)

 

참고로, 복잡계 네트워크 과학은 최근 연구가 굉장히 활발합니다. 가령, 예로 몇가지 용어들, 개념들을 나열하자면요... 노드(node), 링크(link), 방향성 있는 양방향 네트워크(directed two-sided network), 연결선 수(indegree), 출선 수(outdegree), 네트워크의 중심성(centrality), 네트워크 밀도(density), 네트워크 연결 강도(strength)나 빈도(frequency), 도달가능성(reachability), 추이성(transitivity), 상호성(reciprocity) 등... 많지요? 너무 깊이 들어가면 포스팅이 끝이 없을 것이므로 이쯤에서 pass.

 

  • (7) '대포폰 네트워크'의 주 사용 위치와 시간, 문자 메시지 내용, 상호작용 관계 등을 종합적으로 고려해 대포폰의 주인을 추정한다. 
  • (8) '대포폰 네트워크'에 걸린 '실명 핸드폰 사용자'들을 추가하여 '박근혜 & 최순실 게이트의 주연과 조연'으로 구성된 '대포폰 & 실명폰 네트워크'를 완성한다.
  • (9) 특검 검사분들께 증거로 전달한다.

 

 

 

최순실의 비자금이 10조원 정도 된다면서요?  독일 검찰에서 자금세탁 경로를 분석하고 있다는 기사도 보았는데요, 자금 세탁 탐지 분석 기법 중에 'Network analysis', 'Link Analysis' 가 있습니다. (분석 기법 상세 내용은 역시 pass... 나중에 '기계학습' 카테고리에 별도 포스팅할 기회가...그게 언제가 될지는 모르겠지만요... ^^;)

 

[ 자금세탁 탐지의 기술들]

 

* 이미지 출처 :  http://groups.csail.mit.edu/mac/classes/6.805/articles/money/ota-money-laundering/05ch4.pdf

 

 

시계열 Event log를 가지고 (1) 프로세스 자동 탐지/도출, (2) 병목구간 탐색, (3) 시간 흐름에 따른 프로세스 상에서의 Event flow animation 시각화 등에 사용하는 프로세스 마이닝(process mining) 이라는 분석 기법이 있습니다. (아래 Youtube의 프로세스 마이닝 애니메이션 참고)

 

[ 프로세스 마이닝 - 프로세스 자동 탐지 및 시계열 애니메이션 예시 ]

 

 

 

 

이 프로세스 마이닝(process mining) 기법을 사용해서 박정희 대통령 때부터 해서 박근혜-최순실 때까지의 수십년의 기간을 두고 자금의 돈세탁 흐름을 시계열 애니메이션으로 보여주면 재미있을 것 같습니다. 10조원의 돈이 하늘에서 불쑥 떨어지지는 않았을 테고요, 묵직한 종자돈이 아마도 박정희 대통령이 국민의 피같은 돈을 빼돌린 돈이였을거 같지요? (영남대 강탈, 육영재단... ) 특히, 최근에 최순실 게이트 터지고 나서 돈 세탁하느라고 돈 흐름이 아주 왕성하게 활성화되지 않았을까 추측해봅니다.

 

이 블로그에서 소개한 '네트워크 분석(network analysis, link analysis)' 내용이나 분석 기법은 일부의 예시일 뿐이구요, 데이터 과학자에게 데이터를 제공해 준다면(접근할 수 있는 권한을 준다면) 이 포스팅에서 소개한 내용 외에 훨씬 더 다양한 관점과 분석 기법을 적용해서 범죄 사실을 입증할 증거를 찾아내는데 기여를 할 수 있을 것이라고 예상합니다.  

 

 

[ 박영수 특검팀 홧팅~! ]

 

 

마지막으로, 박영수 특검팀, 응원하고 또 응원합니다. 

빛은 어둠을 이긴다는 것을, 정의는 살아있다는 것을 보여주십시요!

훗날 기록될 2016년 역사의 한 페이지를 멋지게 채워주십시요!!

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by R Friend R_Friend


티스토리 툴바