[PYTHON] Programme d'analyse des tendances Twitter (mémo personnel)

Bonjour. J'étudie actuellement les tendances Twitter ** comme le titre l'indique à l'Université de Komazawa ** GMS 2e année **. ** Cet article présente la recherche, le code et les références potentielles.

À l'origine, je m'intéressais aux tendances de Twitter, et depuis que j'étais en première année, j'utilise Python, Twitter API et MeCab, mais c'était une chose primitive qui ** analyse morphologiquement et agrège mot par mot **. Je jouais aussi avec les informations de langue et de localisation et apparaissais kanji ↓ Ensuite, de la même manière que N-gram, par exemple, nous avons enregistré tous les 2 à 12 vocabulaires et agrégé toutes les ** analyses de tendances simples **. En passant, j'ai fait beaucoup de règles manuelles pour le vocabulaire, comme par exemple là où les mots auxiliaires ne viennent pas et les verbes auxiliaires, comme dans la tendance de Twitter. C'est le début de la deuxième année ↓ Après cela, quand il s'agissait de quoi étudier, j'ai eu l'idée de définir et de modéliser une tendance constante qui fluctue tout au long de la journée, mais je me demandais ce que ce serait de faire cela. Ensuite, un enseignant d'une certaine université a souligné que les points et les règles étaient entre les mains d'autres. Il s'agit de l'été de la deuxième année ↓ J'errais un peu, mais https://pj.ninjal.ac.jp/corpus_center/goihyo.html ** Je suis arrivé à l'Institut national des langues Unidic, Dictionnaire de classification, classification sémantique **, et j'ai essayé de faire une normalisation sémantique et un regroupement de mots. C'était plutôt bien, mais la table de correspondance de plusieurs dictionnaires? C'était censé être synonyme du même son lors de l'inversion, mais le sens était mentionné par une personne extrême, donc certaines personnes se sont impliquées, mais le problème Je ne pense pas. De plus, il y a un mot inconnu dans Unidic, et il y a un problème que la tendance n'est pas prise en compte. S'agit-il d'octobre de la deuxième année? ↓ Une fois le sens normalisé, j'ai utilisé CaboCha parce que j'avais pensé à l'étape précédente que j'aimerais utiliser la dépendance pour créer une tendance avec la dépendance du sens. ** C'était un problème et je ne pouvais pas le faire sur mon serveur de séminaire ou AWS, j'ai donc eu du mal à l'installer sur mon Windows et à le lier avec un sous-processus (car Python n'a que 32 bits). Unidic et Cabocha (Cabocha peut-il également spécifier un dictionnaire?) La position du délimiteur était différente, je les ai donc mis en correspondance dans la partie commune de la même manière que le multiple commun minimum. ↓ En conséquence, nous avons pu créer une tendance sémantique basée sur la dépendance du sens. ** Cependant, comme il est dit "ça devrait être synonyme du même son, mais le sens est évoqué par une personne extrême", j'ai fait une correction, et c'est "Hit dans la campagne! Il existe une méthode appelée «suivre et tweeter», et dans «l'analyse de tendance simple», il y avait une méthode pour supprimer en utilisant des tendances d'expression en double, mais j'ai décidé de l'utiliser également. ↓ Jusqu'à présent, nous avons été en mesure d'analyser «les tendances du sens basées sur la dépendance au sens» et les «tendances d'expression simple», et ce que je pense maintenant, c'est que les tendances du sens sont difficiles à séparer des expressions. Je veux dire, c'est une psychologie profonde ou quelque chose de grand, et je pense qu'il est important de le rendre concret dans cette recherche. Indépendant? Agréger pour chaque tendance sémantique qui accompagne la tendance d'expression, ** estimer la tendance d'expression à partir de la tendance de signification, dans quelle mesure les deux peuvent être utilisées correctement et comment les combiner ** sont des problèmes futurs. Maintenant, en novembre de ma deuxième année, je fais de mon mieux pour mes recherches de fin d'études. Je l'ai écrit parce que j'avais un paragraphe. (J'aurais peut-être dû l'écrire plus tôt)

De nos jours, la tendance d'expression est une liste de lettres, et la tendance de signification est une liste de significations dans lesquelles les lettres sont remplacées par des significations.

** Si vous souhaitez l'utiliser, merci de me le faire savoir même sur Twitter. J'étais inquiet à ce sujet. Veuillez supposer que vous possédez les droits d'auteur. ** ** Je voulais aussi l'écrire dans un sens de sauvegarde. L'environnement est Windows 10-64bit Python 3 (Divers) https://twitter.com/kenkensz9

Tout d'abord, il s'agit d'un programme d'estimation de la tendance d'expression. custam_freq_sentece.txt est le texte intégral récupéré pour analyse custam_freq_tue.txt est un candidat de tendance. custam_freq.txt est une tendance. custam_freq_new.txt est le programme qui a la plus longue tendance, excluant les doublons de la tendance. De plus, les tendances changent toutes les heures. La partie de freshtime = int (time.time () * 1000) -200000. Cela devrait être changé en fonction de la vitesse d'acquisition du tweet. En outre, il existe une liste de mots badword qui ne sera pas traitée si ce mot est inclus dans le tweet en premier lieu, et ce n'est peut-être pas la version du programme, mais ce n'est pas facile à gérer, alors n'hésitez pas à l'utiliser.

hyousyutu_trend.py



# coding: utf-8
import tweepy
import datetime
import re
import itertools
import collections
from pytz import timezone
import time
import MeCab
#import threading
#from multiprocessing import Pool
import os
#import multiprocessing
import concurrent.futures
import urllib.parse
#importer
import pdb; pdb.set_trace()
import gc
import sys
import emoji

consumer_key = ""
consumer_secret = ""
access_token = ""
access_token_secret = ""
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
authapp = tweepy.AppAuthHandler(consumer_key,consumer_secret)
apiapp = tweepy.API(authapp)
#Authentification

m_owaka = MeCab.Tagger("-Owakati")
m_ocha = MeCab.Tagger("-Ochasen")
#définition de la décomposition morphologique mecab


lang_dict="{'en': 'Anglais', 'und': 'inconnue', 'is': 'islandais', 'ay': 'Aimara', 'ga': 'irlandais', 'az': 'Azerbaigen', 'as': 'Assam', 'aa': 'Au loin', 'ab': 'Aphazien', 'af': 'Africains', 'am': 'Amhara', 'ar': 'arabe', 'sq': 'albanais', 'hy': 'arménien', 'it': 'italien', 'yi': 'Idish', 'iu': 'Inuktitot', 'ik': 'Inupia', 'ia': 'Intéressant', 'ie': 'Interling', 'in': 'indonésien', 'ug': 'Ouïghour', 'cy': 'Pays de Galles', 'vo': 'Volapuk', 'wo': 'Wolof', 'uk': 'ukrainien', 'uz': 'Ouzbek', 'ur': 'Ourdou', 'et': 'estonien', 'eo': 'Espérant', 'or': 'Oria', 'oc': 'Okinawan', 'nl': 'néerlandais', 'om': 'Oromo', 'kk': 'Kazakh', 'ks': 'Cachemire', 'ca': 'catalan', 'gl': 'Galicien', 'ko': 'coréen', 'kn': 'Cannada', 'km': 'cambodgien', 'rw': 'Kyawanda', 'el': 'langue grecque', 'ky': 'Kirghize', 'rn': 'Kirundi', 'gn': 'Guarani', 'qu': 'Quetua', 'gu': 'Gujarat', 'kl': 'Groenland', 'ku': 'kurde', 'ckb': '中央kurde', 'hr': 'croate', 'gd': 'gaélique', 'gv': 'gaélique', 'xh': 'Kosa', 'co': 'la Corse', 'sm': 'Samoa', 'sg': 'Sangho', 'sa': 'sanskrit', 'ss': 'Siswati', 'jv': 'Javanais', 'ka': 'géorgien', 'sn': 'Shona', 'sd': 'Sind', 'si': 'Sinhara', 'sv': 'suédois', 'su': 'Soudan', 'zu': 'zoulou', 'es': 'Espagnol', 'sk': 'slovaque', 'sl': 'slovène', 'sw': 'Swahili', 'tn': 'Setuwana', 'st': 'Seto', 'sr': 'serbe', 'sh': 'セルボcroate', 'so': 'somali', 'th': 'thaïlandais', 'tl': 'Tagalog', 'tg': 'Tadjik', 'tt': 'tatar', 'ta': 'Tamil', 'cs': 'langue tchèque', 'ti': 'Tigrinya', 'bo': 'Tibétain', 'zh': 'chinois', 'ts': 'Zonga', 'te': 'Terugu', 'da': 'danois', 'de': 'allemand', 'tw': 'Twi', 'tk': 'Torquemen', 'tr': 'turc', 'to': 'Tonga', 'na': 'Nauru', 'ja': 'Japonais', 'ne': 'népalais', 'no': 'norvégien', 'ht': 'haïtien', 'ha': 'Haoussa', 'be': 'un Russe blanc', 'ba': 'Basikir', 'ps': 'Pasito', 'eu': 'basque', 'hu': 'hongrois', 'pa': 'Punjabi', 'bi': 'Bisrama', 'bh': 'Bihar', 'my': 'birman', 'hi': 'hindi', 'fj': 'Fidjien', 'fi': 'finlandais', 'dz': 'Bhoutan', 'fo': 'Compagnon', 'fr': 'français', 'fy': 'frison', 'bg': 'bulgare', 'br': 'Bretagne', 'vi': 'vietnamien', 'iw': 'hébreu', 'fa': 'persan', 'bn': 'bengali', 'pl': 'langue polonaise', 'pt': 'Portugais', 'mi': 'Maori', 'mk': 'Macadonie', 'mg': 'Madagascar', 'mr': 'Malata', 'ml': 'Malayalam', 'mt': 'maltais', 'ms': 'malais', 'mo': 'Moldave', 'mn': 'mongol', 'yo': 'Jorba', 'lo': 'Laota', 'la': 'Latin', 'lv': 'letton', 'lt': 'lituanien', 'ln': 'Ringara', 'li': 'Limbourg', 'ro': 'roumain', 'rm': 'Évaluer la romance', 'ru': 'russe'}"
lang_dict=eval(lang_dict)
lang_dict_inv = {v:k for k, v in lang_dict.items()}
#Dictionnaire de langue


all=[]
#Initialisation de la liste
if os.path.exists('custam_freq_tue.txt'):
  alll=open("custam_freq_tue.txt","r",encoding="utf-8-sig")
  alll=alll.read()
  all=eval(alll)
  del alll
#all=[]
#Prêt à exporter

#freq_write=open("custam_freq.txt","w",encoding="utf-8-sig")
sent_write=open("custam_freq_sentece.txt","a",encoding="utf-8-sig", errors='ignore')
#Prêt à exporter

use_lang=["Japonais"]
use_type=["tweet"]
#config

uselang=""
for k in use_lang:
 k_key=lang_dict_inv[k]
 uselang=uselang+" lang:"+k_key
#préparation de la configuration


def inita(f,k):
  suball=[]
  small=[]
  for s in k:
    if not int(f)==int(s[1]):
     #print("------",f)
     suball.append(small)
     small=[]
    #print(s[0],s[1])
    small.append(s)
    f=s[1]
  suball.append(small)
  #Si 2 est inclus
  return suball


def notwo(al):
 micro=[]
 final=[]
 kaburilist=[]
 for fg in al:
  kaburilist=[] 
  if len(fg)>1:
   for v in itertools.combinations(fg, 2):
    micro=[]
    for s in v:
     micro.append(s[0])
    micro=sorted(micro,key=len,reverse=False)
    kaburi=len(set(micro[0]) & set(micro[1]))
    per=kaburi*100//len(micro[1])
    #print(s[1],per,kaburi,len(micro[0]),len(micro[1]),"m",micro)
    if per>50:
     kaburilist.append(micro[0])
     kaburilist.append(micro[1])
    else:
     final.append([micro[0],s[1]])
     #print("fin1",micro[0],s[1])
    if micro[0] in micro[1]:
     pass
     #print(micro[0],micro[1])
     #print("inclus"*5)
     #if micro[0] in kaburilist:
     # kaburilist.remove(micro[0])
  else:
   pass
   #print(fg[0][1],fg[0][0])
   final.append([fg[0][0],fg[0][1]])
   #print("fin3",fg[0][0],fg[0][1])
  #if kaburilist:
   #longword=max(kaburilist,key=len)
   #final.append([longword,s[1]])
   ##print("fin2",longword,s[1])
   #kaburilist.remove(longword)
   #kaburilist=list(set(kaburilist))
   #for k in kaburilist:
   # if k in final:
   #  final.remove(k)
   #  #print("finremove1",k)
 return final

def siage(fin):
 fin=list(map(list, set(map(tuple, fin))))
 finallen = sorted(fin, key=lambda x: len(x[0]))
 finallendic=dict(finallen)
 finalword=[]
 for f in finallen:
  finalword.append(f[0])
 #print("f1",finalword)

 notwo=[]
 for v in itertools.combinations(finalword, 2):
  #print(v)
  if v[0] in v[1]:
   #print("in")
   if v[0] in finalword:
    finalword.remove(v[0])

 #print("f2",finalword)
 finall=[]
 for f in finalword:
  finall.append([f,finallendic[f]])
 finall = sorted(finall, key=lambda x: int(x[1]), reverse=True)
 #print("final",finall)
 kk=open("custam_freq_new.txt", 'w', errors='ignore')
 kk.write(str(finall))
 kk.close()


def eval_pattern(use_t):
 tw=0
 rp=0
 rt=0
 if "tweet" in use_t:
  tw=1
 if "retweet" in use_t:
  rt=1
 if "reply" in use_t:
  rp=1
 sword=""
 if tw==1:
  sword="filter:safe OR -filter:safe"
  if rp==0:
   sword=sword+" exclude:replies"
  if rt==0:
   sword=sword+" exclude:retweets"
 elif tw==0:
  if rp==1 and rt ==1:
   sword="filter:reply OR filter:retweets"
  elif rp==0 and rt ==0:
   print("NO")
   sys.exit()
  elif rt==1:
   sword="filter:retweets"
  elif rp==1:
   sword="filter:replies"
 return sword
pat=eval_pattern(use_type)+" "+uselang

#config read, fonction et exécution

def a(n):
 return n+1
def f(k):
 k = list(map(a, k))
 return k
def g(n,m):
 b=[]
 for _ in range(n):
  m=f(m)
  b.append(m)
 return b
#Génération de liste de numéros de série

def validate(text):
    if re.search(r'(.)\1{1,}', text):
     return False
    elif re.search(r'(..)\1{1,}', text):
     return False
    elif re.search(r'(...)\1{1,}', text):
     return False
    elif re.search(r'(...)\1{1,}', text):
     return False
    elif re.search(r'(....)\1{1,}', text):
     return False
    else:
     return True
#Fonction pour vérifier les doublons

def eval_what_nosp(c,i):
   no_term=[]
   no_start=[]
   no_in=[]
   koyu_meisi=[]
   if re.findall(r"[「」、。)(『』&@_;【/<>,!】\/@]", c[0]):
     no_term.append(i)
     no_start.append(i)
     no_in.append(i)
   if len(c) == 4:
    if "suffixe" in c[3]:
     no_start.append(i)
    if "Nomenclature propriétaire" in c[3]:
     koyu_meisi.append(i)
    if c[3]=="nom-Non indépendant-Général":
     no_term.append(i)
     no_start.append(i)
     no_in.append(i)
    if "Particule" in c[3]:
     no_term.append(i)
     no_start.append(i)
     #no_in.append(i)
    if c[3]=="Particule-syndicat":
     no_start.append(i)
    if c[3]=="Particule":
     no_start.append(i)
    if "Oh" in c[2]:
     if c[3]=="nom-Changer de connexion":
      no_term.append(i)
      no_start.append(i)
      no_in.append(i)
   if len(c) == 6:
    if c[4]=="Sahen Suru":
     no_start.append(i)
    if c[3]=="verbe-Non indépendant":
     no_start.append(i)
    if "suffixe" in c[3]:
     no_start.append(i)
    if c[3]=="Verbe auxiliaire":
     if c[2]=="Ta":
      no_start.append(i)
      no_in.append(i)
    if c[3]=="Verbe auxiliaire":
     if c[2]=="Absent":
      no_start.append(i)
    if c[3]=="Verbe auxiliaire":
     if "Utilisation continue" in c[5]:
      no_term.append(i)
      no_start.append(i)
    if c[2]=="Faire":
     if c[3]=="verbe-Indépendance":
       if c[5]=="Type continu":
        no_start.append(i)
        no_in.append(i)
    if c[2]=="Devenir":
     if c[3]=="verbe-Indépendance":
      no_start.append(i)
      no_in.append(i)
    if c[2]=="Teru":
     if c[3]=="verbe-Non indépendant":
      no_start.append(i)
      no_in.append(i)
    if c[2]=="est":
     if c[3]=="Verbe auxiliaire":
      no_start.append(i)
      no_in.append(i)
    if c[2]=="Chau":
     if c[3]=="verbe-Non indépendant":
      no_start.append(i)
      no_in.append(i)
    if c[2]=="y a-t-il":
     if c[3]=="verbe-Indépendance":
      no_term.append(i)
      no_start.append(i)
      no_in.append(i)
    if c[2]=="Verbe auxiliaire":
     if c[3]=="Spécial da":
      no_term.append(i)
      no_start.append(i)
      no_in.append(i)
    if c[2]=="Masu":
     if c[3]=="Verbe auxiliaire":
      no_term.append(i)
      no_start.append(i)
      no_in.append(i)
    if "Utilisation continue" in c[5]:
      no_term.append(i)
    if c[5]=="Connexion Word":
     no_start.append(i)
    if c[2]=="Donnez-moi":
     if c[3]=="verbe-Non indépendant":
      no_start.append(i)
      no_in.append(i)
   x=""
   y=""
   z=""
   koyu=""
   if no_term:
    x=no_term[0]
   if no_start:
    y=no_start[0]
   if no_in:
    z=no_in[0]
   if koyu_meisi:
    koyu=koyu_meisi[0]
    #print("koyu",koyu)
    koyu=int(koyu)
   return x,y,z,koyu


small=[]
nodouble=[]
seq=""
def process(ty,tw,un,tagg):
 global all
 global seq
 global small
 global nodouble
 tw=tw.replace("\n"," ")
 sent_write.write(str(tw))
 sent_write.write("\n")
 parselist=m_owaka.parse(tw)
 parsesplit=parselist.split()
 parseocha=m_ocha.parse(tw)
 l = [x.strip() for x in parseocha[0:len(parseocha)-5].split('\n')]
 nodouble=[]
 no_term=[]
 no_start=[]
 no_in=[]
 km_l=[]
 for i, block in enumerate(l):
  c=block.split('\t')
  #sent_write.write("\n")
  #sent_write.write(str(c))
  #sent_write.write("\n")
  #print(str(c))
  ha,hi,hu,km=eval_what_nosp(c,i)
  no_term.append(ha)
  no_start.append(hi)
  no_in.append(hu)
  km_l.append(km)
  #Écriture terminée
 if km_l[0]:
  for r in km_l:
   strin=parsesplit[r]
   if not strin in nodouble:
    all.append([strin,un])
    nodouble.append(strin)
 for s in range(2,8):
  #Une chaîne de 2 à 8.
  #Important car vous pouvez améliorer la précision au lieu de la rendre plus lourde
  num=g(len(parsesplit)-s+1,range(-1,s-1))
  for nr in num:
    #2 pour une phrase-Toutes les rues de 8 chaînes
    #print(no_term)
   if not len(set(nr) & set(no_in)):
    if not nr[-1] in no_term:
     if not nr[0] in no_start:
      small=[]
      #print(str(parsesplit))
      for nr2 in nr:
       #print(nr2,parsesplit[nr2])
      #Ajouter le mot en petit à la position indexée par la séquence à l'intérieur
       small.append(parsesplit[nr2])
      seq="".join(small)
      judge_whole=0
      bad_direct_word=["Comme","\'mat","I\'mat"]
      #if "" in seq:
      # judge_whole=1
      #if "" in seq:
      # judge_whole=1
      for bd  in bad_direct_word:
       if seq==bd:
        judge_whole=1
        break
      parselist=m_owaka.parse(seq)
      l = [x.strip() for x in parseocha[0:len(parseocha)-5].split('\n')]
      for n in range(len(l)):
       if len(l[n].split("\t"))==6:
        if l[n].split("\t")[3]=="verbe-Indépendance":
         if len(l[n+1].split("\t"))==6:
          if l[n+1].split("\t")[3]:
           judge_whole=1
           break
      if judge_whole==0:
       if validate(seq) and len(seq) > 3 and not re.findall(r'[「」、。『』/\\/@]', seq):
        if not  seq in nodouble:
         #Évitement continu
         all.append([seq,un])
         nodouble.append(seq)
         #print("Ajouté avec succès",seq)
         #Ne pas agréger le même mot deux fois
        else:
         #print("Déjà inclus",seq)
         pass
       else:
        #print("Exclusion",seq)
        pass
     else:
      #print("Le début est non_c'est commencer",seq)
      pass
    else:
      #print("La fin est non_terme",seq)
      pass
    #print("\n")
 #print(parsesplit)
 #print(l)
 if tagg:
       print("tagg",tagg)
       for sta in tagg:
        all.append(["#"+str(sta),un])
 #Inclure la balise

N=1
#Nombre de tweets acquis


def print_varsize():
    import types
    print("{}{: >15}{}{: >10}{}".format('|','Variable Name','|','  Size','|'))
    print(" -------------------------- ")
    for k, v in globals().items():
        if hasattr(v, 'size') and not k.startswith('_') and not isinstance(v,types.ModuleType):
            print("{}{: >15}{}{: >10}{}".format('|',k,'|',str(v.size),'|'))
        elif hasattr(v, '__len__') and not k.startswith('_') and not isinstance(v,types.ModuleType):
            print("{}{: >15}{}{: >10}{}".format('|',k,'|',str(len(v)),'|'))






def collect_count():
  global all
  global deadline
  hh=[]
  tueall=[]
  #print("alllll",all)
  freshtime=int(time.time()*1000)-200000
  deadline=-1
  #import pdb; pdb.set_trace()
  #print(N_time)
  print(len(N_time))
  for b in N_time:
   if int(b[1]) < freshtime:
     deadline=b[0]
  print("dead",deadline)
  dellist=[]
  if not deadline ==-1:
   for b in N_time:
    print("b",b)
    if int(b[0]) < int(deadline):
      dellist.append(b)
  for d in dellist:
   N_time.remove(d)
  #print(N_time)
  #import pdb; pdb.set_trace()
  #time.sleep(2)
  #import pdb; pdb.set_trace()
  for a in all:
   if int(a[1]) > freshtime:
    #Nombre de tweets que vous souhaitez recevoir/45*Soustrayez la valeur de 1000. Maintenant 5000/45*1000=112000
    tueall.append(a[0])
    #print("tuealllappend"*10)
    #print(tueall)
   else:
    all.remove(a)
    #print("allremove",a)
  #import pdb; pdb.set_trace()
  c = collections.Counter(tueall)
  c=c.most_common()
  #print("c",c)
  #print(c)
  for r in c:
   if r and r[1]>1:
    hh.append([str(r[0]),str(r[1])])
  k=str(hh).replace("[]","")
  freq_write=open("custam_freq.txt","w",encoding="utf-8-sig", errors='ignore')
  freq_write.write(str(k))
  #import pdb; pdb.set_trace()
  oldunix=N_time[0][1]
  newunix=N_time[-1][1]
  dato=str(datetime.datetime.fromtimestamp(oldunix/1000)).replace(":","-")
  datn=str(datetime.datetime.fromtimestamp(newunix/1000)).replace(":","-")
  dato=dato.replace(" ","_")
  datn=datn.replace(" ","_")
  #print(dato,datn)
  #import pdb; pdb.set_trace()
  freq_writea=open("trenddata/custam_freq-"+dato+"-"+datn+"--"+str(len(N_time))+".txt","w",encoding="utf-8-sig", errors='ignore')
  freq_writea.write(str(k))
  #import pdb; pdb.set_trace()
  freq_write_tue=open("custam_freq_tue.txt","w",encoding="utf-8-sig", errors='ignore')
  freq_write_tue.write(str(all))
  #print(c)

def remove_emoji(src_str):
    return ''.join(c for c in src_str if c not in emoji.UNICODE_EMOJI)

def deEmojify(inputString):
    return inputString.encode('ascii', 'ignore').decode('ascii')

def get_tag(tw,text_content):
 taglist=[]
 entities=eval(str(tw.entities))["hashtags"]
 for e in entities:
  text=e["text"]
  taglist.append(text)
 for _ in range(len(taglist)+2):
  for s in taglist:
   text_content=re.sub(s,"",text_content)
   #text_content=re.sub(r"#(.+?)+ ","",text_content)
 return taglist,text_content

def get_time(id):
 two_raw=format(int(id),'016b').zfill(64)
 unixtime = int(two_raw[:-22],2) + 1288834974657
 unixtime_th = datetime.datetime.fromtimestamp(unixtime/1000)
 tim = str(unixtime_th).replace(" ","_")[:-3]
 return tim,unixtime

non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), '')
N_time=[]
def gather(tweet,type,tweet_type,removed_text):
 global N
 global N_all
 global lagtime
 global all_time
 global all
 global auth
 global N_time
 if get_time(tweet.id):
  tim,unix=get_time(tweet.id)
 else:
  exit
 #Obtenez un bon temps de tweet
 #original_text=tweet.text
 nowtime=time.time()
 tweet_pertime=str(round(N/(nowtime-all_time),1))
 lag=str(round(nowtime-unix/1000,1))
 #Calculer le décalage
 lang=lang_dict[tweet.lang]
 print(N_all,N,tweet_pertime,"/s","+"+lag,tim,type,tweet_type,lang)
 #Affichage des informations.(Tous les tweets, tweets traités, vitesse de traitement, décalage, temps réel, itinéraire d'acquisition, type de tweet, langue)
 print(removed_text.replace("\n"," "))
 taglist,tag_removed_text=get_tag(tweet,removed_text)
 #import pdb; pdb.set_trace()
 #print(type(tweet))
 #import pdb; pdb.set_trace()
 #Exclure les balises
 noemoji=remove_emoji(tag_removed_text)
 try:
  process(tweet_type,tag_removed_text,unix,taglist)
  N_time.append([N,unix])
  print("trt",tag_removed_text)
 except Exception as pe:
   print("process error")
   print(pe)
   #import pdb; pdb.set_trace()
 #Envoyer au traitement réel
 surplus=N%1000
 if surplus==0:
   #sumprocess()
   try:
    collect_count()
   except Exception as eeee:
    print(eeee)
   #exit
   #Comptons
   cft_read=open("custam_freq.txt","r",encoding="utf-8-sig")
   cft_read=cft_read.read()
   cft_read=eval(cft_read)
   max_freq=cft_read[0][1]
   #Valeur maximum
   allen=inita(max_freq,cft_read)
   #Faites une liste des tendances avec la même fréquence.
   finf=notwo(allen)
   #Rechercher et supprimer les chaînes en double et les tendances en double
   siage(finf)
   #Nouveau_Ecrire en fréq
   print_varsize()
   #Afficher les informations de mémoire
 N=N+1
#corps en streaming


def judge_tweet_type(tweet):
 text = re.sub("https?://[\w/:%#\$&\?\(\)~\.=\+\-]+","",tweet.text)
 if tweet.in_reply_to_status_id_str :
  text=re.sub(r"@[a-zA-Z0-9_]* ","",text)
  text=re.sub(r"@[a-zA-Z0-9_]","",text)
  return "reply",text
 else:
  head= str(tweet.text).split(":")
  if len(head) >= 2 and "RT" in head[0]:
   text=re.sub(r"RT @[a-zA-Z0-9_]*: ","",text)
   return "retwe",text
  else:
   return "tweet",text



badword=["Boîte à questions","Jetons des guimauves","J'ai une question","Participation à la guerre","Livraison","@","Suivre","Appliquer","RPG pour smartphone","Gacha","S4live","campagne","Esprits à la dérive","Présent","Coopérative en direct","Nous acceptons les consultations entièrement gratuites","Omikuji","Chance de gagner","GET","avoir","shindanmaker","Frappé","loterie"]
N_all=0
def gather_pre(tweet,type):
    global N_all
    N_all=N_all+1
    #Comptez tous les tweets qui passent par ici
    go=0
    for b in badword:
     if  b in tweet.text:
      go=1
      break
    #Jugez s'il y a un mauvais mot dans le texte, jugement GO car il n'est pas inclus dans 0
    if go == 0:
      if tweet.lang=="ja":
        tweet_type,removed_text=judge_tweet_type(tweet)
        #Déterminer le type de tweet
        if tweet_type=="tweet":
         try:
          gather(tweet,type,tweet_type,removed_text)
          #print(type(tweet))
          #Envoyer pour recueillir le traitement.
         except Exception as eee:
          #gather("Ah","Ah","Ah","Ah")
          #import pdb; pdb.set_trace()
          pass
lagtime=0


def search(last_id):
 #print(pat)
 global pat
 time_search =time.time()
 for status in apiapp.search(q=pat,count="100",result_type="recent",since_id=last_id):
   #Obtenez des tweets plus récents que le dernier tweet que vous avez obtenu avec la recherche
   gather_pre(status,"search")
#corps de recherche

interval = 2.16
#recherche intervalle d'appel
#min2

trysearch=0
#recherche nombre d'appels

class StreamingListener(tweepy.StreamListener):
    def on_status(self, status):
        global time_search
        global trysearch
        gather_pre(status,"stream")
        time_stream=time.time()
        time_stream-time_search % interval
        if time_stream-time_search-interval>interval*trysearch:
           #Pour une certaine période de temps(interbal)Exécutez une recherche à chaque fois.
           last_id=status.id
           #executor = concurrent.futures.ThreadPoolExecutor(max_workers=8)
           #executor.submit(search(last_id))
           #Lors de l'essai de traitement parallèle
           search(last_id)
           trysearch=trysearch+1
#corps en streaming

def carry():
 listener = StreamingListener()
 streaming = tweepy.Stream(auth, listener)
 streaming.sample()
#fonction d'appel de flux

time_search =time.time()
#L'heure à laquelle la recherche a été exécutée pour la dernière fois mais définie avant le flux

executor = concurrent.futures.ThreadPoolExecutor(max_workers=8)
#Définition parallèle

all_time=time.time()
#Définition de l'heure de début de l'exécution

try:
 carry()
except Exception as e:
 import pdb; pdb.set_trace()
 print(e)
 #import pdb; pdb.set_trace()
 pass
 #except Exception as ee:
  #print(ee)
  #import pdb; pdb.set_trace()

#transporter le corps et la gestion des erreurs

Vous trouverez ci-dessous un programme de tendance sémantique, mais je peux le recommander en toute confiance car il est très apprécié (). Je n'ai pas écrit la partie que j'ai apportée du cissolus, mais je la laisserai.

imi_trend.py



from bs4 import BeautifulSoup
import collections
import concurrent.futures
import datetime
import emoji
import itertools
import MeCab
from nltk import Tree
import os
from pathlib import Path
from pytz import timezone
import re
import spacy
import subprocess
import sys
import time
import tweepy
import unidic2ud
import unidic2ud.cabocha as CaboCha
from urllib.error import HTTPError, URLError
from urllib.parse import quote_plus
from urllib.request import urlopen
m=MeCab.Tagger("-d ./unidic-cwj-2.3.0")

os.remove("bunrui01.csv")
os.remove("all_tweet_text.txt")
os.remove("all_kakari_imi.txt")

bunrui01open=open("bunrui01.csv","a",encoding="utf-8")
textopen=open("all_tweet_text.txt","a",encoding="utf-8")
akiopen=open("all_kakari_imi.txt","a",encoding="utf-8")

catedic={}
with open('categori.txt') as f:

 a=f.read()
 aa=a.split("\n")
 b=[]
 bunrui01open.write(",,,")
 for i, j in enumerate(aa):
  catedic[j]=i
  bunrui01open.write(str(j))
  bunrui01open.write(",")
 bunrui01open.write("\n")
 print(catedic)
with open('./BunruiNo_LemmaID_ansi_user.csv') as f:
 a=f.read()
 aa=a.split(",\n")
 b=[]
 for bb in aa:
  if len(bb.split(","))==2:
   b.append(bb.split(","))
 word_origin_num_to_cate=dict(b)
with open('./cate_rank2.csv') as f:
 a=f.read()
 aa=a.split("\n")
 b=[]
 for bb in aa:
  if len(bb.split(","))==2:
   b.append(bb.split(","))
 cate_rank=dict(b)

class Synonym:

    def getSy(self, word, target_url, css_selector):

        try:
            #Encodé car l'URL d'accès contient du japonais
            self.__url = target_url + quote_plus(word, encoding='utf-8')

            #Accès et analyse
            self.__html = urlopen(self.__url)
            self.__soup = BeautifulSoup(self.__html, "lxml")

            result = self.__soup.select_one(css_selector).text

            return result
        except HTTPError as e:
            print(e.reason)
        except URLError as e:
            print(e.reason)
sy = Synonym()
alist = ["Sélection"]

#Utilisez "Japanese Sisoras Associative Synonymes" pour rechercher
target = "https://renso-ruigo.com/word/"
selector = "#content > div.word_t_field > div"
#for item in alist:
#    print(sy.getSy(item, target, selector))

consumer_key = ""
consumer_secret = ""
access_token = ""
access_token_secret = ""
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth)
authapp = tweepy.AppAuthHandler(consumer_key,consumer_secret)
apiapp = tweepy.API(authapp)
#Authentification(Ici api)

def remove_emoji(src_str):
    return ''.join(c for c in src_str if c not in emoji.UNICODE_EMOJI)

def get_tag(tw,text_content):
 taglist=[]
 entities=eval(str(tw.entities))["hashtags"]
 for e in entities:
  text=e["text"]
  taglist.append(text)
 for _ in range(len(taglist)+2):
  for s in taglist:
   text_content=re.sub(s,"",text_content)
   #text_content=re.sub(r"#(.+?)+ ","",text_content)
 return taglist,text_content

def get_swap_dict(d):
    return {v: k for k, v in d.items()}

def xcut(asub,a):
 asub.append(a[0])
 a=a[1:len(a)]
 return asub,a

def ycut(asub,a):
 asub.append(a[0])
 a=a[1:len(a)]
 return asub,a

def bunruikugiri(lastx,lasty):
 hoge=[]
 #import pdb; pdb.set_trace()
 editx=[]
 edity=[]
 for _ in range(500):
  edity,lasty=ycut(edity,lasty)
  #target=sum(edity)
  for _ in range(500):
   target=sum(edity)
   #rint("sum",sum(editx),"target",target)
   if sum(editx)<target:
    editx,lastx=xcut(editx,lastx)
   elif sum(editx)>target:
    edity,lasty=ycut(edity,lasty)
   else:
    hoge.append(editx)
    editx=[]
    edity=[]
    if lastx==[] and lasty==[]:
     return hoge
    break

all_appear_cate=[]
all_unfound_word=[]
all_kumiawase=[]
nn=1
all_kakari_imi=[]
def process(tw,ty):
 global nn
 wordnum_toword={}
 catenum_wordnum={}
 word_origin_num=[]
 mozisu=[]
 try:
  tw=re.sub("https?://[\w/:%#\$&\?\(\)~\.=\+\-]+","",tw)
  tw=tw.replace("#","")
  tw=tw.replace(",","")
  tw=tw.replace("\u3000","") #Important pour faire correspondre le nombre de caractères
  tw=re.sub(re.compile("[!-/:-@[-`{-~]"), '', tw)
  parseocha=m.parse(tw)
  print(tw)
  l = [x.strip() for x in parseocha[0:len(parseocha)-5].split('\n')]
  bunrui_miti_sentence=[]
  for i, block in enumerate(l):
   if len(block.split('\t')) > 1:
    c=block.split('\t')
    d=c[1].split(",")
    #Processus de traitement de texte
    print(d,len(d))
    if len(d)>9:
        if d[10] in ["Faire"]:
          word_origin_num.append(d[10])
          bunrui_miti_sentence.append(d[8])
          mozisu.append(len(d[8]))
        elif d[-1] in word_origin_num_to_cate:
         word_origin_num.append(int(d[-1]))
         wordnum_toword[int(d[-1])]=d[8]
         bunrui_miti_sentence.append(word_origin_num_to_cate[str(d[-1])])
         mozisu.append(len(d[8]))
        else:
          #print("nai",d[8])
          #Affichage de mots inconnus
          all_unfound_word.append(d[10])
          bunrui_miti_sentence.append(d[8])
          mozisu.append(len(c[0]))
    else:
        mozisu.append(len(c[0]))
        all_unfound_word.append(c[0])
        bunrui_miti_sentence.append(c[0])
        #else:
        #  mozisu.append(l[])
  #print("kouho",word_origin_num,"\n")
  #Mots aux nombres originaux
  #print(tw)
  #Si vous regardez des phrases faites avec une classification sémantique et des mots inconnus
  for s in bunrui_miti_sentence:
    print(s," ",end="")
  print("\n")
  stn=0
  cmd = "echo "+str(tw)+" | cabocha -f1"
  cmdtree="echo "+str(tw)+" | cabocha "
  proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
  proctree = subprocess.Popen(cmdtree, stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
  proc=proc.communicate()[0].decode('cp932')
  proctree=proctree.communicate()[0].decode('cp932')
  print(proctree)
  proclist=proc.split("\n")
  #print(proc)
  #informations f1
  #print(proclist)
  #Informations sur la liste
  procnumlist=[]
  wordlis=[]
  eachword=""
  num=0
  for p in proclist:
   if p[0]=="*":
    f=p.split(" ")[1]
    t=p.split(" ")[2].replace("D","")
    procnumlist.append([f,t])
    if eachword:
     wordlis.append([num,eachword])
     num=num+1
     eachword=""
   elif p=="EOS\r":
     wordlis.append([num,eachword])
     num=num+1
     eachword=""
     break
   else:
    #print("aaaaa",p.split("\t")[0])
    eachword=eachword+p.split("\t")[0]
  tunagari_num_dict=dict(procnumlist)

  print(tunagari_num_dict)
  bunsetu_num_word=dict(wordlis)
  #print(bunsetu_num_word)
  bunsetu_mozisu=[] 
  for v in bunsetu_num_word.values():
   bunsetu_mozisu.append(len(v))
  if sum(bunsetu_mozisu) != sum(mozisu):
    return
  #print("mozisu",mozisu)
  #print("bunsetumozi",bunsetu_mozisu)
  res=bunruikugiri(mozisu,bunsetu_mozisu)
  #print("res",res)
  nnn=0
  small_cateandcharlist=[]
  big_cateandcharlist=[]
  for gc in res:
    for _ in range(len(gc)):
     print(bunrui_miti_sentence[nnn],end="  ")
     if bunrui_miti_sentence[nnn] in list(catedic.keys()):
       small_cateandcharlist.append(bunrui_miti_sentence[nnn])
     nnn=nnn+1
    #Les mots inconnus et les mots auxiliaires sont considérés comme identiques, le dictionnaire mecabne gold peut donc être utilisé.
    if small_cateandcharlist==[]:
     big_cateandcharlist.append(["null"])
    else:
     big_cateandcharlist.append(small_cateandcharlist)
    small_cateandcharlist=[]
    print("\n")
  #print("bcacl",big_cateandcharlist)
  twewtnai_kakari_imi=[]
  if len(big_cateandcharlist)>1 and len(big_cateandcharlist)==len(bunsetu_num_word):
  #Les délimiteurs de la dépendance et de l'analyse morphologique ne correspondent pas
   for kk, vv in tunagari_num_dict.items():
     if vv != "-1":
      for aaw in big_cateandcharlist[int(kk)]:
       for bbw in big_cateandcharlist[int(vv)]:
        twewtnai_kakari_imi.append([aaw,bbw])
        if not "Symbole de rang" in str([aaw,bbw]):
          if not "null" in str([aaw,bbw]):
           if not "Symbole numérique" in str([aaw,bbw]):
            if not "Des choses" in str([aaw,bbw]):
             all_kakari_imi.append(str([aaw,bbw]))
             akiopen.write(str([aaw,bbw]))
     else:
       break
  else:
    return
  akiopen.write("\n")
  akiopen.write(str(bunrui_miti_sentence))
  akiopen.write("\n")
  akiopen.write(str(tw))
  akiopen.write("\n")
  print("tki",twewtnai_kakari_imi)
  tweetnai_cate=[]
  word_cate_num=[]
  for k in word_origin_num:
    if str(k) in word_origin_num_to_cate:
     ram=word_origin_num_to_cate[str(k)]
     print(ram,cate_rank[ram],end="")
     tweetnai_cate.append(ram)
     all_appear_cate.append(ram)
     word_cate_num.append(catedic[ram])
     catenum_wordnum[catedic[ram]]=int(k)
     stn=stn+1
    else:
     if k in ["Faire"]:
      all_appear_cate.append(k)
      tweetnai_cate.append(k)
  print("\n")
  #print(tweetnai_cate)
  #import pdb; pdb.set_trace()
  for k in tweetnai_cate:
   if k in catedic:
    aac=catedic[k]
  #print("gyaku",word_cate_num)
  #print("wt",wordnum_toword)
  #print("cw",catenum_wordnum)
  bunrui01open.write(str(tw))
  bunrui01open.write(",")
  bunrui01open.write(str(tim))
  bunrui01open.write(",")
  bunrui01open.write(str(unix))
  bunrui01open.write(",")
  ps=0
  for tt in list(range(544)):
    if int(tt) in word_cate_num:
     a=catenum_wordnum[tt]
     #Numéro de mot de l'épée
     bunrui01open.write(str(wordnum_toword[a]))
     #Mots des nombres de mots
     bunrui01open.write(",")
     ps=ps+1
    else:
     bunrui01open.write("0,")
  bunrui01open.write("end")
  bunrui01open.write("\n")
  textopen.write(str(nn))
  textopen.write(" ")
  textopen.write(tw)
  textopen.write("\n")
  nn=nn+1
  #Mettez toutes les rues
  for k in list(itertools.combinations(tweetnai_cate,2)):
   all_kumiawase.append(k)

 except Exception as ee:
  print(ee)
  import pdb; pdb.set_trace()
  pass

def judge_tweet_type(tweet):
 if tweet.in_reply_to_status_id_str:
  return "reply"
 else:
  head= str(tweet.text).split(":")
 if len(head) >= 2 and "RT" in head[0]:
  return "retwe"
 else:
  return "tweet"
#Juger s'il s'agit d'une lèvre, d'un retweet, d'un tweet

def get_time(id):
 two_raw=format(int(id),'016b').zfill(64)
 unixtime = int(two_raw[:-22],2) + 1288834974657
 unixtime_th = datetime.datetime.fromtimestamp(unixtime/1000)
 tim = str(unixtime_th).replace(" ","_")[:-3]
 return tim,unixtime
#Heure du Tweet à partir de l'identifiant

N=1
def gather(tweet,type,tweet_typea):
 global all_appear_cate
 global N
 global all_time
 global tim
 global unix
 tim,unix=get_time(tweet.id)
 original_text=tweet.text.replace("\n","")
 taglist,original_text=get_tag(tweet,original_text)
 nowtime=time.time()
 tweet_pertime=str(round(N/(nowtime-all_time),1))
 lag=str(round(nowtime-unix/1000,1))
 #lang=lang_dict[tweet.lang]
 try:
  process(remove_emoji(original_text),tweet_typea,)
 except Exception as e:
  print(e)
  #import pdb; pdb.set_trace()
  pass
 print(N,tweet_pertime,"/s","+"+lag,tim,type,tweet_typea)
 N=N+1
 if N%500==0:
   ccdd=collections.Counter(all_appear_cate).most_common()
   for a in ccdd:
    print(a)
   #ccdd=collections.Counter(all_unfound_word).most_common()
   #for a in ccdd:
   # print("Absent",a)
   ccdd=collections.Counter(all_kumiawase).most_common(300)
   for a in ccdd:
    print(a)
   ccdd=collections.Counter(all_kakari_imi).most_common(300)
   for a in ccdd:
    print("all_kakari_imi",a)
   #import pdb; pdb.set_trace() 
#Collectez tous les tweets de flux et de recherche

def pre_gather(tw,ty):
 #print(ty)
# if  "http://utabami.com/TodaysTwitterLife" in tw.text:
  print(tw.text)
  if ty=="stream":
   tweet_type=judge_tweet_type(tw)
   if tw.lang=="ja" and tweet_type=="tweet":
    gather(tw,ty,tweet_type)
  elif ty=="search":
    gather(tw,ty,"tweet")

def search(last_id):
 time_search =time.time()
 for status in apiapp.search(q="filter:safe OR -filter:safe -filter:retweets -filter:replies lang:ja",count="100",result_type="recent",since_id=last_id):
   pre_gather(status,"search")
#corps de recherche

class StreamingListener(tweepy.StreamListener):
    def on_status(self, status):
        global time_search
        global trysearch
        pre_gather(status,"stream")
        time_stream=time.time()
        time_stream-time_search % interval
        if time_stream-time_search-interval>interval*trysearch:
           last_id=status.id
           #executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
           #executor.submit(search(last_id))
           search(last_id)
           trysearch=trysearch+1
#corps en streaming

def carry():
 listener = StreamingListener()
 streaming = tweepy.Stream(auth, listener)
 streaming.sample()


interval = 2.1
trysearch=0
time_search =time.time()
#executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
all_time=time.time()
try:
 #executor.submit(carry)
 carry()
except Exception as er:
 print(er)
 import pdb; pdb.set_trace()
 pass


bandicam 2020-11-16 17-53-41-545.jpg bandicam 2020-11-16 17-53-18-841.jpg

Pour chaque 500 tweets Nombre d'occurrences de sens simple Nombre d'occurrences de la signification de 2 grammes Le nombre d'occurrences d'un continu significatif? Aussi pour tous Texte du Tweet, informations d'analyse Unidic, dépendance CaboCha, remplacement par classification sémantique, etc.

bunrui01.csv-L'axe horizontal est le sens de la classification de 544, l'axe vertical est le tweet, 0 n'existe pas, 1 est le csv à écrire donc c'est le mot correspondant all_tweet_text-Tweet traité et de quel numéro il s'agit all_kakari_imi-Paire de significations dépendantes, signifiant remplacement de classification, texte categori.txt-Un txt qui décrit la classification sémantique de 544 et crée un dictionnaire avec index au moment de l'exécution. Pour plus d'informations sur BunruiNo_LemmaID_ansi_user.csv, voir https://pj.ninjal.ac.jp/corpus_center/goihyo.html Comme vous pouvez le voir, il s'agit d'une table de correspondance du numéro d'origine du mot et de la classification de la signification. cate_rank2.csv-Un dictionnaire de l'ordre d'apparition des classifications sémantiques créées à un moment donné.

J'expliquerai les autres variables plus tard,

C'est pour mon propre mémo, et les gens qui le comprennent feront de leur mieux pour le comprendre, alors je le ferai.

Recommended Posts

Programme d'analyse des tendances Twitter (mémo personnel)
Analyse des données Twitter | Analyse des tendances
Note tout à fait personnelle
Note personnelle de Flask # 2
Note personnelle de Flask # 1
[CovsirPhy] Package Python COVID-19 pour l'analyse des données: analyse des tendances S-R
Structure des dossiers pour l'analyse
Programme d'étude des statistiques
Analyse négative / positive 2 Analyse négative / positive Twitter (1)
(Note personnelle) Diagramme de Sanky
Analyse de la source pour Django - INSTALLED_APPS
Programme de publication facile sur Twitter
Analyse négative / positive 3 Analyse négative / positive de Twitter (2)