Python for data analysis

Chapter 2 사례 소개

표독's 2016. 3. 4. 17:13

이 책은 데이터를 생산적으로 다루는 여러 가지 파이썬 도구를 사용하는 방법을 설명한다.


저마다 데이터를 처리하는 목적은 다르겠지만 대개는 다음과 같은 작업을 위해 사용할 것이다.


외부 자료 활용 : 여러 가지 파일 형식과 데이터베이스를 읽고 쓰는 작업

데이터 준비 : 데이터 정비, 수집, 집계, 정규화, 개조, 분리, 분석을 위한 이터 변형

데이터 변형 : 모아놓은 데이터에 수학적, 통계학적 연산을 적용해 새로운 데이터를 도출. 

모델링과 계산 : 통계 모델, 기계 학습 알고리즘 또는 다른 계산 도구와 데이터 연결하기

데이터 표현 : 정적 혹은 인터랙티브한 도식화 또는 원문 요약


2.1 bit.ly의 1.usa.gov 데이터


http://1usagov.measuredvoice.com/2012/


에 가서 usagov_bitly_data2012-03-16-1331923249를 받고 압축을 푼뒤 txt파일로 변환하여 주었다.


json모듈의 loads 함수는 내려받은 샘플 파일을 한 줄 씩 읽는다.


path = 'E:\\Pfd\\usagov_bitly_data2012-03-16-1331923249.txt'
open(path).readline()
import json
path = 'usagov_bitly_data2012-03-16-1331923249.txt'
records = [json.loads(line) for line in open(path)] # json 모듈의 loads 함수는 내려받은 샘플 파일을 한 줄 씩 읽는다.
records[0]
records[0]['tz'] # record의 개별 아이템에서 접근하려는 값의 키를 문자열로 넘겨서 쉽게 읽어올 수 있다.
print records[0]['tz'] # 'America/New_York을 출력 형식으로

2.1.1 순수 파이썬으로 표준시간대 세어보기


가장 빈도가 높은 표준시간대 (tz 필드)를 구한다고 가정하자. 


# 2.1.1
time_zones = [rec['tz'] for rec in records] #수행하면 오류 - records의 아이템이 모두 표준시간대 필드를 포함하지 않음.
time_zones = [rec['tz'] for rec in records if 'tz' in rec] # 위의 문제를 해결, tz 필드가 있는지 검사
time_zones[:10] # 처음 10개의 표준시간대 보기, 몇 개는 비어있다. 그냥 두고 표준시간대를 셀 때 pandas를 사용.

# 재사용이 쉽도록 이 로직을 함수로 만들고 time_zones 리스트를 함수에 넘겨서 사용
def get_counts(sequence):
counts = {}
for x in sequence:
if x in counts:
counts[x] += 1
else:
counts[x] = 1
return counts # time_zones를 순회하면서 표준시간대를 센 후 자료 구조에 저장

from collections import defaultdict
def get_counts2(sequence):
counts = defaultdict(int) # 값은 0부터 시작할 것임
for x in sequence:
counts[x] += 1
return counts

counts = get_counts(time_zones)
counts['America/New_York'] # 표준시간대 중 America/New_York의 표준 시간대 개수
len(time_zones) #time_zones의 문자 길이

#가장 많이 등장하는 상위 10개의 표준시간대를 알고 싶을때, 세련된 방법으로 사전 이용
def top_counts(count_dict, n=10):
value_key_pairs = [(count, tz) for tz, count in count_dict.items()]
value_key_pairs.sort() # 오름차순 정렬
return value_key_pairs[-n:]

top_counts(counts) # 가장 많이 등장하는 상위 10개 표준시간대 알 수 있다.

#collections.Counter 클래스를 이용하면 지금까지 수행했던 작업을 훨씬 쉽게 할 수 있다.

from collections import Counter

counts = Counter(time_zones)
counts.most_common(10)

2.1.2 pandas로 표준시간대 세어보기


pandas의 주요 자료 구조는 DataFrame인데 표나 스프레드시트 같은 형태라고 생각하면 된다. 다음은 records를 가지고 DataFrame을 만드는 방법으로, 매우 간단하다.


In[27]: from pandas import DataFrame, Series
import pandas as pd; import numpy as np

In[28]: from pandas import DataFrame, Series

In[29]: import pandas as pd; import numpy as np

In[30]: frame = DataFrame(records)

In[31]: frame

Out[31]:
_heartbeat_ a \
0 NaN Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKi...
1 NaN GoogleMaps/RochesterNY
2 NaN Mozilla/4.0 (compatible; MSIE 8.0; Windows NT ...
3 NaN Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8)...
4 NaN Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKi...
5 NaN Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKi...
In[33]: frame['tz'][:10]

Out[33]:
0 America/New_York
1 America/Denver
2 America/New_York
3 America/Sao_Paulo
4 America/New_York
5 America/New_York
6 Europe/Warsaw
7
8
9
Name: tz, dtype: object
In[34]: tz_counts = frame['tz'].value_counts() # 각 시간대 별 갯수를 센다
tz_counts[:10] # 상위 10개 정렬

Out[34]:
America/New_York 1251
521
America/Chicago 400
America/Los_Angeles 382
America/Denver 191
Europe/London 74
Asia/Tokyo 37
Pacific/Honolulu 36
Europe/Madrid 35
America/Sao_Paulo 33
Name: tz, dtype: int64

matplotlib 라이브러리로 이 데이터의 그래프 그려보기.


In[38]: clean_tz = frame['tz'].fillna('Missing') # fillna로 없는 값을 대체
In[39]: clean_tz[clean_tz ==''] = 'Unknown' # 비어있는 값은 불리언 배열 색인을 통해 대체
In[40]: tz_counts = clean_tz.value_counts() # tz_count에서 비어있는 표준시간대를 다른 이름으로 바꿔줌
In[41]: tz_counts[:10]
Out[41]:
America/New_York 1251
Unknown 521
America/Chicago 400
America/Los_Angeles 382
America/Denver 191
Missing 120
Europe/London 74
Asia/Tokyo 37
Pacific/Honolulu 36
Europe/Madrid 35
Name: tz, dtype: int64
tz_counts[:10].plot(kind= 'barh', rot=0) # plot 메서드 이용, counts 객체에 대한 수평 막대 그래프를 만든다.



#다음처럼 URL을 축약하는 데 사용한 브라우저, 단말기, 애플리케이션에 대한 정보를 담은 필드가 있다.
In[45]: frame['a'][1]
Out[45]: u'GoogleMaps/RochesterNY'
In[46]: frame['a'][50]
Out[46]: u'Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2'
In[47]: frame['a'][51]
Out[47]: u'Mozilla/5.0 (Linux; U; Android 2.2.2; en-us; LG-P925/V10e Build/FRG83G) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'

'agent'라고 하는 이 흥미로운 문자열 정보를 분석하는 일이 어려워보일 수도 있다. 하지만 다행히도 파이썬의 내장 문자열 함수와 정규표현식을 익히고 나면 식은 죽 먹기다.


이 둘을 이용하면 대략적인 브라우저 종류를 알 수 있는 첫번째 문자열 토큰을 잘라내고 사용자 행동에 대한 또 다른 개요를 만들 수 있다.


In[50]: results = Series([x.split()[0] for x in frame.a.dropna()]) # a에서 공백으로 분리, split()
In[51]: results[:5] # 5개 보여주기
Out[51]:
0 Mozilla/5.0
1 GoogleMaps/RochesterNY
2 Mozilla/4.0
3 Mozilla/5.0
4 Mozilla/5.0
dtype: object
In[52]: results.value_counts()[:8] # 8개 종류를 쓰는 순서대로 보여주기
Out[52]:
Mozilla/5.0 2594
Mozilla/4.0 601
GoogleMaps/RochesterNY 121
Opera/9.80 34
TEST_INTERNET_AGENT 24ㅗ
GoogleProducer 21
Mozilla/6.0 5
BlackBerry8520/5.0.0.681 4
dtype: int64

표준시간대 순위표를 윈도우 사용자와 비윈도우 사용자 그룹으로 나눠보기


agent 문자열이 'Windows'를 포함하면 윈도우 사용자라고 가정, agent값이 없는 경우 제외 시킨다.


cframe = frame[frame.a.notnull()] #agent값이 없는 경우 제외


각 행이 윈도우인지 아닌지 검사한다.




2.2 MovieLens의 영화평점 데이터


GroupLens 연구소는 1990년대부터 2000년대 초까지 방대한 영화 평점 데이터를 제공하고 있다.

이 데이터에는 영화평점과 영화에 대한 정보(장르, 개봉연도) 그리고 사용자에 대한 정보( 나이, 우편번호, 성별, 직업)가 포함되어있다. 기계 학습 기법을 여기서 소개하기는 어렵고 이런 종류의 데이터를 요구사항에 맞게 잘 쪼개는 방법만 소개하겠다.


MovieLens 1M( 백만 개) 데이터 셋은 약 6천여 명의 사용자들로부터 수집한 4000여 편의 영화에 대한 백만 개의 영화 평점을 담고 있다.


이 데이터 셋은 평점, 사용자 정보, 영화 정보, 이 세 가지 테이블로 나뉘어 있는데, zip 파일을 풀어서 각 테이블을 pandas.read_table 함수를 사용해 DataFrame 객체로 불러오자.


'Python for data analysis' 카테고리의 다른 글

Chapter 5 pandas 시작하기  (0) 2016.03.25
Chapter 4. Numpy 기본 : 배열과 벡터 계산  (0) 2016.03.11
Chapter 3. IPython 소개  (0) 2016.03.11
Chaper 1 시작하기 전에  (0) 2016.03.04