소셜 웹 마이닝 ch1 twitter

통계학을 배우기 전에 우선 데이터 스크래핑을 해봐야겠다는 생각에
소셜 웹 마이닝이라는 책을 사서 공부 중이다.
아래 코드는 한국 트위터에 맞게 수정해서 쓴 코드이다.

# coding: utf-8

# API 인증 

# In[1]:

import twitter


# In[2]:

CONSUMER_KEY = ''
CONSUMER_SECRET = ''
OAUTH_TOKEN = ''
OAUTH_TOKEN_SECRET = ''

키와 토큰은 트위터 사이트에서 받아야한다. 자세한 내용은 책에 있지만 생략한다.

auth = twitter.oauth.OAuth(OAUTH_TOKEN,OAUTH_TOKEN_SECRET,CONSUMER_KEY,CONSUMER_SECRET)
twitter_api = twitter.Twitter(auth=auth)

위처럼 api 인증을 받아야 트위터의 데이터를 스크래핑할 수 있다.

# In[3]:

WORLD_WOE_ID = 1
KOR_WOE_ID = 23424868

world_trends = twitter_api.trends.place(_id = WORLD_WOE_ID)
kor_trends = twitter_api.trends.place(_id = KOR_WOE_ID)

트위터 api에 트렌드 클래스도 있다니 신기하다.

# JSON을 이용해 보기 쉽게 하기 


# In[4]:

import json

json 은 자바 스크립트 변환하는 걸로 알고 있었는데 여기서는 어떻게 쓰일지 궁금했다.

# In[5]:

print(json.dumps(world_trends,indent = 1,ensure_ascii=False))
print
print(json.dumps(kor_trends,indent =1,ensure_ascii=False))

ensure_ascii=False 를 써야 한글이 깨지지 않고 잘 나왔다..
자바 스크립트 파일 덤프해서 더 보기 쉽게 출력되었다.
indent = 1 이라는 옵션 때문인지 구분을 잘 할 수 있도록 출력되었다.

# 두 개의 트렌드 집합에 대한 교집합 연산

이 함수를 좀 더 일찍 알았더라면 첫 자아성찰 프로젝트를 더 잘 할 수도 있었을 것 같다.
교집합과 합집합 등 이산수학에 나오는 개념들을 잘 사용할 수 있다.

# In[6]:

world_trends_set = set([trend['name'] for trend in world_trends[0]['trends']])


# In[7]:

kor_trends_set = set([trend['name'] for trend in world_trends[0]['trends']])


# In[8]:

common_trends = world_trends_set.intersection(kor_trends_set)


# In[9]:

print(common_trends)


# In[10]:

q = '#알파고'

count = 100

twitter api에 찾는 함수도 있었다.
참 편한 라이브러리인 거 같다.

search_results = twitter_api.search.tweets(q=q, count=count)
#print(search_results.keys()) ->dict_keys(['statuses', 'search_metadata'])

statuses = search_results['statuses']

print(json.dumps(search_results,indent=1 ,ensure_ascii=False))


# In[11]:

for _ in range(5):
    print("Length of statuses",len(statuses))
    try:
        next_result = search_results['search_metadata']['next_results']
    except KeyError:
        break
   
    kwargs = dict([kv.split('=') for kv in next_result[1:].split("&")])
   
    search_results = twitter_api.search.tweets(**kwargs)
    statuses += search_results['statuses']

print(json.dumps(statuses[0],indent=1, ensure_ascii=False))

statuses를 더 자세히 나누어 메타 데이터를 뽑아내는 과정이다.

# tweet 으로부터 텍스트, 스크린 네임, 해시 태그 추출


# In[20]:

status_texts = [status['text'] for status in statuses]
screen_names = [user_mention['screen_name'] for status in statuses for user_mention in status['entities']['user_mentions']]
hashtags = [hashtag['text'] for status in statuses for hashtag in status['entities']['hashtags']]

words = [w for t in status_texts for w in t.split()]

print(json.dumps(status_texts[:5],indent = 1 ,ensure_ascii=False ))
print(json.dumps(screen_names[:5],indent = 1 ,ensure_ascii=False ))
print(json.dumps(hashtags[:5],indent = 1 ,ensure_ascii=False ))
print(json.dumps(words[:5],indent = 1 ,ensure_ascii=False ))


# 트윗에 잇는 단어로부터 기본 빈도 분포 생성


# In[21]:

from collections import Counter

새롭고 좋은 라이브러리들을 알아가는 거 같다. 
Counter 라이브러리도 프로젝트 할 때 쓰면 참 좋았을 것 같다.

# In[22]:

for item in [words,screen_names,hashtags]:
    c = Counter(item)
    print(c.most_common()[:10])
    print


# In[23]:

from prettytable import PrettyTable

prettytable은 엄청 좋은 것은 아니지만 간단한 시각화하기엔 좋다.

# In[24]:

for label,data in (('word',words),('Screen Name',screen_names),('Hashtag',hashtags)):
    pt = PrettyTable(field_names = [label,'Count'])
    c = Counter(data)
    [ pt.add_row(kv) for kv in c.most_common()[:10]]
    pt.align[label], pt.align['Count'] = 'l','r'
    print(pt)


# 트윗에 대한 Lexical Diversity 계산


# In[25]:

def lexical_diversity(tokens):
    return 1.0*len(set(tokens))/len(tokens)

def average_words(statuses):
    total_words = sum([len(s.split()) for s in statuses])
    return 1.0*total_words/len(statuses)

print(lexical_diversity(words))
print(lexical_diversity(screen_names))
print(lexical_diversity(hashtags))
print(average_words(status_texts))


# 가장 유명한 리트윗 찾기


# In[26]:

retweets = [(status['retweet_count'],
             status['retweeted_status']['user']['screen_name'],
             status['text']) for status in statuses if 'retweeted_status' in status]


# In[27]:

pt= PrettyTable(field_names=['Count','Screen Name','Text'])
[pt.add_row(row) for row in sorted(retweets, reverse=True)[:5]]
pt.max_width['Text'] = 50
pt.align = 'l'
print(pt)


# 상태를 리트윗한 사용자 찾기


# In[28]:

_retweets =twitter_api.statuses.retweets(id=317127304981667841)
print ([r['user']['screen_name'] for r in _retweets])


# 워드 빈도 플로팅


# In[33]:

import matplotlib.pyplot as plt
import collections

word_counts =sorted(Counter(words).values(),reverse=True)

plt.loglog(word_counts)
plt.ylabel("Freq")
plt.xlabel("Word Rank")


# In[34]:

plt.show()


사실 트위터를 안해서 잘 모르겠지만 끌어오는 결과 값들이 어떤 때에 쓰여야 잘 쓰일까라는 생각을 많이 했다.
페이스북은 옛날에 해봐서 스크래핑해보면 더 잘 분석할 수 있을 것 같다.
하지만 이 책의 2부에는 트위터 쿡북이라는 부분으로써 많은 쪽을 트위터에 할애하고 있다는 점이 아쉽다..

댓글

이 블로그의 인기 게시물

윈도우 설치에서 파티션 설정 오류(NTFS)

[exploit writing] 1_스택 기반 오버플로우 (1) First

하둡 설치 오류 정리