L'API de streaming ne prend pas en charge le filtrage japonais, elle ne peut capter qu'environ 1% des tweets, et je pense que beaucoup de gens pensent que ce n'est pas facile à utiliser. Je me suis demandé s'il y avait une utilité pour une telle API de streaming, alors j'y ai pensé, alors je l'ai fait.
Tout ce dont vous avez besoin, ce sont les données de nombre de mots (stockées dans sqlite) toutes les 10 minutes obtenues à partir de l'API de streaming de Twitter. Les champs DB sont ymd, hour, minute, word_dict, tweet_cnt. Année, mois, jour ('2014-06-01'), heure ('22'), minute ('10' (par incréments de 10 minutes de 00 à 50)), ensemble de mots de type dictionnaire mariné, toutes les 10 minutes, respectivement. Le nombre de tweets. J'ai pensé après l'avoir fait, mais j'ai fait une erreur en concevant la DB. Il ne servait à rien de séparer la date, l'heure et les minutes. .. Je pense que je l'ai fait stupide, oui. Pour plus d'informations sur l'utilisation de l'API Twitter, reportez-vous à la page décrite dans Diviser les données Twitter en SPAM et HAM.
python
# coding: utf-8
import sqlite3 as sqlite
from collections import defaultdict
import cPickle as pickle
import copy
import matplotlib.pyplot as plt
import re, unicodedata
from normalizewords import Replace # !!!!!À!!!Ou capitalisation, pleine largeur
from math import floor, sqrt
stopword = ('Veuillez décrire en fonction de l'objectif tel que des pictogrammes',)
class DataCreater:
date = []
tweet_cnt = []
ex_words_store = []
now_words_store = []
new_break_words = set()
bin_cnt = 0
p = re.compile("[!-/:-@[-`{-~]")
def __init__(self, dbname, word_limit, ofname, oftcntname,ofnewword,ofcos):
self.con = sqlite.connect(dbname)
self.word_limit = word_limit
self.ofword = open(ofname, 'w',1000)
self.oftcnt = open(oftcntname, 'w',1000)
self.ofnewwords = open(ofnewword,'w',1000)
self.ofcos = open(ofcos,'w',1000)
def __def__(self):
self.ofword.close()
self.oftcnt.close()
self.ofnewwords.close()
self.ofcos.close()
def re_aggregate(self,span,con_bin=10):
response = self.get_data_yeald()
itr, tweet_cnt, word_cnt = self.initiarize_cnt()
s_date = None
while 1:
res = response.fetchone()
if res is None: break
#print res[0]+', '+res[1]+', '+res[2]+', '+str(res[4])
tweet_cnt += int(res[4])
word_cnt = self.aggregate_word_cnt(pickle.loads(str(res[3])), word_cnt)
if itr==0:
s_date = res[0]+' '+res[1].zfill(2)+':'+res[2]
if itr == span-1:
date = res[0]+' '+res[1].zfill(2)+':'+res[2]
sorted_word_list = self.sort_word_dict(word_cnt)
self.output_topN_word(s_date, sorted_word_list)
self.output_tweet_cnt(s_date, tweet_cnt)
self.date.append(s_date)
self.tweet_cnt.append(tweet_cnt)
s_date = date
self.bin_cnt += 1
self.store_now_dict(sorted_word_list[:self.word_limit])
print len(self.now_words_store)
if self.bin_cnt >= con_bin:
if len(self.ex_words_store)!=0:
self.store_new_words(sorted_word_list[:self.word_limit])
cos_sim = self.calculate_cos_similarity(sorted_word_list[:self.word_limit])
self.output_new_words(s_date)
self.output_cos_sim(s_date,cos_sim)
self.ex_words_store = copy.deepcopy( self.now_words_store )
self.now_words_store.pop(0)
self.new_break_words = set()
else:
self.ex_words_store = copy.deepcopy( self.now_words_store )
self.now_words_store.pop(0)
itr, tweet_cnt, word_cnt = self.initiarize_cnt()
else:
itr += 1
def get_data_yeald(self, start_date=None, end_date=None):
return self.con.execute("select ymd, hour, minute, word_dict,tweet_cnt from word_count")
def initiarize_cnt(self):
return 0, 0, defaultdict(int)
def aggregate_word_cnt(self, new_word_dic, orig_word_dic):
for k,v in new_word_dic.items():
if k not in stopword:
m = self.p.search(unicodedata.normalize('NFKC', unicode(k)))
if m is None:
orig_word_dic[k] += v
return orig_word_dic
def sort_word_dict(self, word_dict):
lst = word_dict.items()
lst.sort(lambda p0,p1: cmp(p1[1],p0[1])) # get Top N data
return lst
def calculate_cos_similarity(self, sorted_wordlist):
ex_words =[]
now_word_list = []
for w_list in self.ex_words_store:
ex_words +=w_list
for k,_ in sorted_wordlist:
now_word_list.append(k)
numerator = sum([1 for c in now_word_list if c in ex_words])
denominator = sqrt(len(ex_words) * len(now_word_list))
return 1-float(numerator) / denominator if denominator != 0 else 1
def output_topN_word(self, date, sorted_word_list):
if len(sorted_word_list) >=self.word_limit:
s_list = [ st[0]+':'+str(st[1]) for st in sorted_word_list[:self.word_limit]]
s = '\t'.join(s_list)
self.ofword.write(date+'\t'+s+'\n')
else:
s_list = [ st[0]+':'+str(st[1]) for st in sorted_word_list[:self.word_limit]]
s = '\t'.join(s_list)
self.ofword.write(date+'\t'+s+'\n')
def output_tweet_cnt(self, date, cnt):
s = date+'\t'+str(cnt)
self.oftcnt.write(s+'\n')
def output_new_words(self,date):
s = '\t'.join(list(self.new_break_words))
print date, s
self.ofnewwords.write(date+'\t'+s+'\n')
def output_cos_sim(self, date, cos_sim):
self.ofcos.write(date+'\t'+str(cos_sim)+'\n')
def store_now_dict(self, sorted_wordlist):
words = [k for k,_ in sorted_wordlist]
self.now_words_store.append(words)
def store_new_words(self, sorted_wordlist):
ex_words =[]
for w_list in self.ex_words_store:
ex_words +=w_list
for k,_ in sorted_wordlist:
if k not in ex_words:
self.new_break_words.add(k)
if __name__=='__main__':
dbname = 'stream_word_cnt.db'
ofname = 'topN_words'
oftcnt = 'tweet_count'
ofnewword = 'new_word'
ofcos = 'cos_simularity'
word_top = 100 #haut Combien de mots obtenir
span = 6 #Combien de comptes en unités de 10 minutes devraient être combinés et recomptés
dc = DataCreater(dbname, word_top, ofname, oftcnt,ofnewword,ofcos)
dc.re_aggregate(span,con_bin=24) #con_bin est le nombre de portées pour comparer la similarité
tick = int(floor(len(dc.tweet_cnt)/7))
plt.plot(range(len(dc.tweet_cnt)), dc.tweet_cnt)
plt.xticks(range(0, len(dc.tweet_cnt), tick), dc.date[::tick], rotation=40)
plt.show()
J'avais des données que j'avais sauvegardées du 10 au 25 juin, alors j'ai essayé. En conséquence, les mots liés à la Coupe du monde ont été pris vers 5 heures du matin, les mots liés au tremblement de terre du 16 ont été repris, et les mots tels que fortes pluies et tonnerre ont été extraits les jours de forte pluie. C'est très simple à faire, mais j'ai de bonnes données. La dissemblance calculée par la similitude cosinus a également beaucoup réagi à l'heure de la Coupe du monde (notamment l'heure de diffusion du match contre le Japon) et à l'heure du tremblement de terre.
Je pensais regarder les 10 premiers mots, mais la plupart des mots de spam tweet montent en haut. Il semble qu'il puisse également être utilisé comme moyen de supprimer des mots contenus dans ce spam (un simple filtre anti-spam qui ne nécessite pas de maintenance). J'ai le sentiment que les données de l'API de streaming peuvent être utilisées de cette manière.
Désolé de vous déranger, mais si vous avez des points étranges, veuillez commenter.
Recommended Posts