[PYTHON] Visualisation et analyse des informations de localisation des données Twitter Stava

Ceci est le 4ème volet de la série Twitter Starva. Cette fois, je souhaite traiter les informations de localisation contenues dans les données du tweet!


Partie 1: Importez des données avec les API REST Twitter et importez-les dans mongoDB http://qiita.com/kenmatsu4/items/23768cbe32fe381d54a2

Partie 2: Séparation du spam des données Twitter acquises http://qiita.com/kenmatsu4/items/8d88e0992ca6e443f446

Partie 3: Pourquoi le nombre de tweets a-t-il augmenté après un jour? http://qiita.com/kenmatsu4/items/02034e5688cc186f224b

Partie 4: Visualisation des informations de localisation cachées dans Twitter (cette fois) http://qiita.com/kenmatsu4/items/114f3cff815aa5037535


** <<< Données à analyser >>> **

Nombre de données
600 777 cas ... Il a considérablement augmenté
Période des données d'acquisition
Du 11/03/2015 04:43:42 au 03/04/2015 02:09:30
Nombre de tweets par seconde
3.292 tweet/sec

** Schéma de principe de ce contenu ** Twitter-Geo-compressor.png

Cette fois aussi, nous analyserons les tweets qui incluent "staba" dans le texte. En outre, en plus des informations de latitude et de longitude attachées au tweet lui-même, utilisez MeCab pour extraire le nom de lieu du corps du tweet et l'extraire de l'API Yahoo! est utilisé pour convertir en informations de latitude et de longitude, et ce contenu est également affiché. La première moitié est de savoir comment coder le traitement des données, et la seconde moitié est de voir le résultat de la visualisation et de la visualisation, donc si vous voulez voir ce qui se passe en images, c'est Veuillez consulter [À propos de la moitié inférieure](http://qiita.com/kenmatsu4/items/114f3cff815aa5037535#2- Visualisation des informations de localisation) sur la page.

1. Estimer les informations de localisation à partir du corps du tweet

1-1. Préparation

Tout d'abord, importez les bibliothèques à utiliser et établissez une connexion à mongoDB.

%matplotlib inline
import numpy as np
import json, requests, pymongo, re
from pymongo import Connection
from collections import defaultdict
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

connect = Connection('localhost', 27017)
db = connect.starbucks
tweetdata = db.tweetdata
location_dict = db.location

Les informations du tweet elles-mêmes contiennent un champ appelé «coordonnées», et si vous tweetez avec des informations de localisation telles que le GPS, la latitude et la longitude seront incluses ici. Voyons d'abord combien de personnes tweetent avec des informations de localisation.

num_not_geo = tweetdata.find({'coordinates':None,'spam':None,'retweeted_status': None},{'_id':1, 'coordinates':1}).count()
num_geo = tweetdata.find({'coordinates':{"$ne":None},'spam':None,'retweeted_status': None},{'_id':1, 'coordinates':1}).count()

print "num_not_geo",num_not_geo
print "num_geo", num_geo
print "%.3f"%(num_geo / float(num_geo+num_not_geo) * 100),"%"

** <<< Résultat >>> ** location_ratio-compressor.png

Nombre de tweets sans informations de localisation
444 188
Nombre de tweets avec informations de localisation
5 122
Taux de tweet des informations de localisation
1.140 %
* Comptage hors RT

@ arieee0's "Introduction de la méthode d'estimation de la position de l'utilisateur SNS à partir d'un exemple de texte et d'application" Dans le cas de p24, le ratio de Tweet avec informations de position est de 0,3% C'est pourquoi les amateurs de staba peuvent avoir tendance à insister un peu w (bien que je ne puisse pas le dire à moins de tester pour voir si la différence est significative).

1-2. Extraction de mots indiquant les noms de lieux

Je cherchais des informations géographiques à partir du corps du tweet, mais j'ai trouvé que MeCab peut extraire le nom du lieu en premier lieu, donc je vais l'utiliser. Comme c'est pratique! Voici un exemple d'analyse morphologique avec MeCab, qui se trouve dans Roppongi, Shibuya et le texte, mais ceux-ci sont étiquetés comme "nomenclature appropriée, région" afin qu'ils puissent être facilement extraits: satisfait:

Nom aujourd'hui,Avocat possible,*,*,*,*,aujourd'hui,aujourd'hui,Kyo
Est un assistant,Assistance,*,*,*,*,Est,C,sensationnel
Roppongi substantif,Nomenclature propriétaire,zone,Général,*,*,Roppongi,Roppongi,Roppongi
Auxiliaire,Assistant de cas,Général,*,*,*,À,ré,ré
Aller verbe,Indépendance,*,*,Rappel à cinq étapes / ka,Forme basique,aller,Iku,Iku
Mais l'assistant,Assistant de connexion,*,*,*,*,mais,Ked,Ked
, Symbole,Point de lecture,*,*,*,*,、,、,、
Cet accessoire,*,*,*,*,*,Cette,Donc non,Donc non
Pré-nom,Avocat possible,*,*,*,*,Avant,Mae,Mae
Auxiliaire,Assistant de cas,Général,*,*,*,À,ré,ré
Shibuya substantif,Nomenclature propriétaire,zone,Général,*,*,Shibuya,Shibuya,Shibuya
Auxiliaire,Assistant de cas,Général,*,*,*,À,ré,ré
Aller verbe,Indépendance,*,*,Rappel à cinq étapes / ka,Type continu,aller,Iki,Iki
Verbe assistant Tai,*,*,*,Spécial Thaïlande,Forme basique,Vouloir,Thaïlande,Thaïlande
.. symbole,Phrase,*,*,*,*,。,。,。

Puisque la nomenclature a déjà été extraite avec MeCab et placée dans la base de données, le nom de lieu est extrait d'ici et placé dans un autre champ.

#Extraire le nom de la zone du texte avec Mecab et champ: location_Définir comme nom
def location_name_mecab(sentence):
    t = mc.Tagger('-Ochasen -d /usr/local/Cellar/mecab/0.996/lib/mecab/dic/mecab-ipadic-neologd/')
    sentence = sentence.replace('\n', ' ')
    text = sentence.encode('utf-8') 
    node = t.parseToNode(text) 
    result_dict = defaultdict(list)
    for i in range(140):
        if node.surface != "":  #Exclure les en-têtes et les pieds de page
            #Sélectionnez une nomenclature appropriée et un mot local
            if (node.feature.split(",")[1] == "Nomenclature propriétaire") and (node.feature.split(",")[2] == "zone"):
                plain_word = node.feature.split(",")[6]
                if plain_word !="*":
                    result_dict[u'Nom de la zone'].append(plain_word.decode('utf-8'))
        node = node.next
        if node is None:
            break
    return result_dict

for d in tweetdata.find({'spam':None},{'_id':1, 'text':1}):
    ret = location_name_mecab(d['text'])
    tweetdata.update({'_id' : d['_id']},{'$push': {'location_name':{'$each':ret[u'Nom de la zone']}}})

1-3. Conversion du nom de lieu en latitude et longitude

Maintenant que le nom du lieu a été extrait, nous allons acquérir les informations de latitude et de longitude en fonction de celui-ci. J'utilise l'API Yahoo! Geocoder, mais chaque fois que j'accède, cela consomme le nombre de fois et je reste coincé dans la limite d'accès, alors je choisis d'abord le nom de lieu à convertir et j'ai un ensemble de nom de lieu, de latitude et de longitude. Sera amené à mongoDB.

Commencez par créer une liste de noms de lieux pour lesquels vous souhaitez obtenir des informations de latitude et de longitude.

#Emplacement du Tweet_Rendre le nom unique et l'objet dictionnaire"loc_name_dict"Agréger à
loc_name_dict = defaultdict(int)
for d in tweetdata.find({'spam':None},{'_id':1, 'location_name':1}):
    for name in d['location_name']:
        loc_name_dict[name] += 1

Lancez l'ensemble agrégé de noms de lieux dans Yahoo! Geocoder API pour obtenir des informations de latitude et de longitude. Comme appid est requis pour utiliser l'API de géocodeur, créez un compte sur Yahoo! Developer Network, obtenez l'appid et définissez-le.

#Ajoutez la latitude et la longitude au nom de lieu extrait du tweet et importez-le dans mongoDB
def get_coordinate_from_location(location_name):
    payload = {'appid': '<Définir Yahoo appid>', 'output':'json'} #Définissez l'appid sur celui de votre compte!
    payload['query'] = location_name # eg.g u'Roppongi'
    url = "http://geo.search.olp.yahooapis.jp/OpenLocalPlatform/V1/geoCoder"
    r = requests.get(url, params=payload)
    if r.status_code == 200:
        jdata = json.loads(r.content)
        #Calculez la moyenne à partir de la liste des informations de localisation obtenues par la requête et utilisez-la comme latitude et longitude du nom de lieu.
        try:
            ret = np.array([map(float,j['Geometry']['Coordinates'].split(',')) for j in jdata['Feature']])
        except KeyError, e:
            "KeyError(%s)" % str(e)
            return []
        
        return np.average(ret,axis=0)
    else:
        print "%d: error." % r.status_code
        return []
    
#Nom du lieu-Une table qui contient des liens pour la latitude et la longitude"location"Mettre en
for name in loc_name_dict.keys():
    loc = get_coordinate_from_location(name)
    if len(loc) > 0:
        location_dict.insert({"word":name,"latitude":loc[1],"longitude":loc[0]}) 

1-4. Ajoutez des informations de latitude et de longitude aux données du Tweet

Maintenant que le nom du lieu et la latitude / longitude ont été liés, nous l'appliquerons aux données du Tweet. Les noms de lieux katakana expriment souvent des noms de pays, etc., et il y avait peu de cas où ils étaient exprimés comme leur propre lieu, de sorte que les noms de lieux ne contenant que du katakana étaient exclus. En outre, il existe une zone appelée Shinkaihotsu dans la ville d'Izumi, dans la préfecture de Toyama, mais elle a également été exclue à titre d'exception car elle était utilisée dans un sens différent dans de nombreux cas. (C'est un nom de lieu rare) De plus, "Japon" est très vague, donc je l'exclus.

#Ajouter des informations de position du texte aux données de Tweet

#Extraire le nom de lieu et la latitude / longitude de la base de données et les conserver dans l'objet dictionnaire
loc_dict = {loc['word']:[loc['longitude'],loc['latitude']] for loc in location_dict.find({})}

def get_coord(loc_name):

    #Excluez les noms de lieux uniquement en Katakana (car il existe de nombreux noms de pays et il est peu probable qu'ils représentent l'emplacement)
    regex = u'^[UNE-Vers le bas]*$'
    match = re.search(regex, loc_name, re.U)
    if match:
        return 0
    
    #Mots exclus (car le nouveau développement est un nom de lieu pour une raison quelconque et le Japon est trop vague mais fréquent)
    if loc_name in [u'Nouveau développement', u'Japon']:
        return 0
    
    if loc_name in loc_dict:
        #Si tel est le cas, renvoyez les informations de localisation
        return (loc_dict[loc_name][0],loc_dict[loc_name][1])
    else:
        #Sinon, renvoie zéro
        return 0
    
def exist_check(word):
    return True if word in loc_dict else False

for d in tweetdata.find({'coordinates':None,'spam':None},{'_id':1, 'location_name':1}):
    if len(d['location_name']) > 0:
        name_list = np.array(d['location_name'])
        #Vrai s'il y a des informations de localisation,Sinon, génération de fausses séquences
        ind = np.array(map(exist_check, name_list))
        #Nombre réel
        T_num = len(ind[ind==True])

        #Traitez uniquement les Tweets avec des noms de lieux
        if T_num > 0:
            coordRet = map(get_coord, name_list[ind])  # key_list[ind]Est uniquement pour ceux qui ont des informations de localisation
            [coordRet.remove(0) for i in range(coordRet.count(0))]  #Supprimer 0
            if len(coordRet) == 0:
                continue
            #Adoptez le premier nom de lieu (il y a des cas où plusieurs noms de lieu sont dans le Tweet, mais la première place est plus importante)
            lon, lat = coordRet[0]
            #Reflété dans DB
            tweetdata.update({'_id' : d['_id']}, 
                     {'$set' : {'text_coord' : {'longitude':lon, 'latitude': lat}}})

2. Visualisation des informations de localisation

2-1. Tracé

Maintenant que nous avons toutes les données, j'aimerais les visualiser. Tout d'abord, je vais enfin comploter sans penser à rien.

#Extraction des informations de latitude et de longitude incluses dans les tweets
loc_data = np.array([[d['coordinates']['coordinates'][1],d['coordinates']['coordinates'][0]]\
           for d in tweetdata.find({'coordinates':{"$ne":None},'spam':None},{'_id':1, 'coordinates':1})])

#Extraire la liste des informations d'emplacement d'extraction de tweet de la base de données
text_coord = np.array([[d['text_coord']['latitude'],d['text_coord']['longitude']] for d in tweetdata.find({'text_coord':{'$ne':None}},{'_id':1, 'text_coord':1})])

lat1 = loc_data[:,0]  #latitude(latitude)
lon1 = loc_data[:,1]  #longitude(longitude)

lat2 = text_coord[:,0]  #latitude(latitude)
lon2 = text_coord[:,1]  #longitude(longitude)

xlim_min = [np.min(lon)*.9,120,139]
xlim_max = [np.max(lon)*1.1,150,140.5]
ylim_min = [np.min(lat)*.9,20,35.1]
ylim_max = [np.max(lat)*1.1,50,36.1]

for x1,x2,y1,y2 in zip(xlim_min,xlim_max,ylim_min,ylim_max):
    plt.figure(figsize=(10,10))
    plt.xlim(x1,x2)
    plt.ylim(y1,y2)
    plt.scatter(lon1, lat1, s=20, alpha=0.4, c='b')
    
    
for x1,x2,y1,y2 in zip(xlim_min,xlim_max,ylim_min,ylim_max):
    plt.figure(figsize=(10,10))
    plt.xlim(x1,x2)
    plt.ylim(y1,y2)
    plt.scatter(lon2, lat2, s=20, alpha=0.4, c='g')

Commençons par les données du Tweet qui contiennent à l'origine la latitude et la longitude.

white_map_01-compressor.png

Et ça? Je ne suis pas sûr.

Cependant, comme vous l'avez peut-être remarqué, il y a des taches dans le coin supérieur droit.
Je voudrais l'élargir un peu.
white_map_02-compressor.png

C'est le Japon! : sourire:
Puisque le mot recherché est «staba», c'est naturel, mais le fait que l'archipel japonais puisse être identifié à environ 1%, 5 000 tweets signifie que les personnes qui tweetent avec «staba» sont uniformément réparties. On peut dire qu'il y en a.

2-2. Tracer sur la carte

Maintenant, je voudrais mettre ces données sur la carte et les voir plus clairement. Nous utiliserons une bibliothèque appelée Matplotlib basemap, donc installez la bibliothèque en vous référant à ce lien.

#Tracer sur la carte
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

#ite = 20
ar = np.arange

enlarge = [1,2,4,8,16,32]
w_list = [15000000./(i) for i in enlarge]
h_list = [9000000./(i) for i in enlarge]

xlim_min = [-142,  80,  120,  135,   139]#[3:5]
xlim_max = [ 192, 160,  150,  142,   141]#[3:5]
ylim_min = [ -55,   0,   20,   33,    35]#[3:5]
ylim_max = [  75,  50,   50,   37,  36.2]#[3:5]
ss       = [ 0.7, 0.3,  0.1, 0.03, 0.005]#[3:5]

for lon, lat in zip([lon1,lon2],[lat1,lat2]):
    for i, s in zip(ar(len(xlim_min)),ss):
    
        m = Basemap(projection='merc',llcrnrlat=ylim_min[i] ,urcrnrlat=ylim_max[i] ,\
            llcrnrlon=xlim_min[i],urcrnrlon=xlim_max[i] ,lat_ts=20, resolution='c')
        plt.figure(figsize=(13,13))

        m.bluemarble()
    
        if i > 2:
            m.drawcoastlines(linewidth=0.25)
    
        for x, y in zip(lon,lat):
            m.tissot(x,  y, s,100,facecolor='red',zorder=100,alpha=0.4)

        plt.show()
        plt.savefig('plot_map_%s.png'%(str(i)))

Eh bien, c'est le résultat.

map_01-1-compressor.png

Si vous le mettez sur la carte, vous pouvez voir d'un coup d'œil de quelle zone vous tweetez. Depuis que je recherche "staba", il y en a beaucoup au Japon, mais étonnamment, des tweets "staba" sont également créés à partir de diverses régions telles que l'Europe, les États-Unis et l'Asie du Sud-Est!

Aussi, je vais l'élargir.

map_01-2-compressor.png

Il remplit le Japon w Vous pouvez voir après le tweet ici et là à Taiwan, en Chine, en Corée du Sud et en Asie du Sud-Est.

Développez encore.

map_01-2-compressor.png

Bien qu'il soit dispersé un peu partout, Tomeihan est toujours particulièrement bondé.


map_01-4-compressor.png

Après tout, il y en a beaucoup dans les zones urbaines où la population semble importante et qui n'a pas été tweetée depuis les zones montagneuses.

map_01-5-compressor.png

C'est celui qui s'est concentré sur la zone métropolitaine avec le plus fort grossissement. La partie blanchâtre est la partie plaine, mais il y a beaucoup de tweets d'ici, et elle n'est pas tweetée depuis la partie verte de la montagne. N'est-ce pas en quelque sorte conforme à l'intuition?

3. Essayez de visualiser les informations de localisation déduites du texte du tweet

Les informations de latitude et de longitude qui peuvent être déduites du texte sont ** 50 310 **, soit près de 10 fois plus que les données GPS précédentes. Étant donné que le processus de traçage de la latitude et de la longitude estimées à partir du corps du tweet avec le code précédent est déjà inclus, nous examinerons à nouveau la carte.

J'ai hâte de voir à quoi ressemblera l'intrigue d'après le nom du lieu dans le corps du tweet.

map_03-1-compressor.png

Cette fois, je suis complètement concentré sur le Japon. Parce que les noms de lieux en japonais sont extraits par MeCab et que les noms de lieux Katakana sont exclus comme mentionné ci-dessus, je pense que le résultat peut être considéré comme attendu.

Agrandir.

map_03-3-compressor.png

C'est plus serré qu'avant! Hokkaido est moins dense, mais Honshu, Shikoku et Kyushu semblent assez denses. Lors de la conversion d'un nom de lieu en latitude et longitude, un nom de lieu mystérieux a été inclus, ou un point au milieu de la mer a également été inclus, donc je pense que les informations GPS sont imbattables en termes de précision. De plus, comme le nom de lieu dans le corps du tweet n'indique pas toujours la position actuelle, je pense que la précision s'améliorera si une méthode permettant de deviner comment le nom de lieu est utilisé dans la phrase à partir des mots environnants peut être prise, alors j'aimerais en faire un problème. Je vais.

Agrandir.

map_03-4-compressor.png

Cela dit, c'est dispersé de manière sympa!

Enfin, la zone métropolitaine à nouveau.

map_03-5-compressor.png

D'une manière ou d'une autre, le nombre semble être inférieur à celui des informations GPS, car la latitude et la longitude sont obtenues à partir du nom du lieu, elles sont donc agrégées au même point. Vous pouvez voir des points orange foncé, ce qui signifie que de nombreux points sont rassemblés au même endroit.

Donc, cette fois, j'ai pris les informations de position des données du Tweet et les ai visualisées. Quel est le contenu de marmonner "Staba" à l'étranger? Il y a certaines choses qui m'intéressent, mais cela fait longtemps, alors j'écrirai les résultats de l'analyse dans le prochain épisode.
Le code complet peut être trouvé sur Gist.


Recommended Posts

Visualisation et analyse des informations de localisation des données Twitter Stava
Analyse des données financières par pandas et leur visualisation (2)
Analyse des données financières par pandas et leur visualisation (1)
Analyse des données Twitter | Analyse des tendances
Obtenez une grande quantité de données Twitter de Starba avec python et essayez l'analyse de données Partie 1
Analyse de données à partir de python (visualisation de données 1)
Analyse de données à partir de python (visualisation de données 2)
Outil de visualisation Python pour le travail d'analyse de données
[Didacticiel d'analyse Python dans la base de données avec SQL Server 2017] Étape 3: Exploration et visualisation des données
Analyse des données Titanic 2
Un beau dessin graphique avec Python -seaborn facilite l'analyse et la visualisation des données Partie 1
Analyse de données python
Implémentez "Data Visualization Design # 3" avec pandas et matplotlib
Un beau dessin graphique avec Python -seaborn facilite l'analyse et la visualisation des données Partie 2
Analyse des données Titanic 1
Traitement et jugement de la collecte du plan d'analyse des données (partie 1)
Analyse des données Titanic 3
Traitement et jugement de la collecte du plan d'analyse des données (partie 2)
Organisation des procédures de base pour l'analyse des données et le traitement statistique (4)
Essayez une analyse rudimentaire des sentiments sur les données de l'API Twitter Stream.
Vue d'ensemble et astuces de Seaborn avec visualisation de données statistiques
Organisation des procédures de base pour l'analyse des données et le traitement statistique (2)
Histoire de l'analyse d'image du fichier PDF et de l'extraction de données
Essayez de diviser les données Twitter en SPAM et HAM
[Ingénierie de contrôle] Visualisation et analyse du contrôle PID et de la réponse par étapes
Analyse des données de mesure (2) -Hydrobacter et raccord, recommandation lmfit-
Comment visualiser les données par variable explicative et variable objective
Analyse des données à l'aide de xarray
Bibliothèques de visualisation de données Python
Présentation de l'analyse de données python
Analyse négative / positive 2 Analyse négative / positive Twitter (1)
Visualisation des données avec les pandas
Analyse et partage faciles avec re: dash, un outil de visualisation de données open source Partie 1-Installation
Modèle d'analyse de données Python
Analyse négative / positive 3 Analyse négative / positive de Twitter (2)
Analyse de données avec Python
[Introduction aux Data Scientists] Statistiques descriptives et analyse de régression simple ♬