[PYTHON] Visualisierung und Analyse von Stava Twitter-Datenstandortinformationen

Dies ist der 4. Teil der Starva Twitter-Reihe. Dieses Mal möchte ich die in den Tweet-Daten enthaltenen Standortinformationen verarbeiten!


Teil 1: Importieren Sie Daten mit Twitter-REST-APIs und importieren Sie sie in mongoDB http://qiita.com/kenmatsu4/items/23768cbe32fe381d54a2

Teil 2: Trennung von Spam von erfassten Twitter-Daten http://qiita.com/kenmatsu4/items/8d88e0992ca6e443f446

Teil 3: Warum hat sich die Anzahl der Tweets nach einem Tag erhöht? http://qiita.com/kenmatsu4/items/02034e5688cc186f224b

Teil 4: Visualisierung von in Twitter versteckten Standortinformationen (diesmal) http://qiita.com/kenmatsu4/items/114f3cff815aa5037535


** <<< Zu analysierende Daten >>> **

Anzahl der Daten
600.777 Fälle ... Es hat erheblich zugenommen
Erfassungsdatenperiode
11.03.2015 04:43:42 bis 03.04.2015 02:09:30
Anzahl der Tweets pro Sekunde
3.292 tweet/sec

** Schematische Darstellung dieses Inhalts ** Twitter-Geo-compressor.png

Auch dieses Mal werden wir Tweets analysieren, die "staba" im Text enthalten. Verwenden Sie zusätzlich zu den dem Tweet selbst angehängten Breiten- und Längengradinformationen MeCab, um den Ortsnamen aus dem Tweet-Textkörper und aus der Yahoo! Geocoder-API zu extrahieren. wird zum Konvertieren in Breiten- und Längengradinformationen verwendet. Dieser Inhalt wird auch angezeigt. In der ersten Hälfte geht es darum, wie die Verarbeitung von Daten codiert wird, und in der zweiten Hälfte geht es darum, das Ergebnis der Visualisierung und Visualisierung zu sehen. Wenn Sie also sehen möchten, was bildlich vor sich geht, ist dies der Fall Weitere Informationen finden Sie unter [Über die untere Hälfte] der Seite (http://qiita.com/kenmatsu4/items/114f3cff815aa5037535#2-Visualisierung der Standortinformationen).

1. Erraten von Standortinformationen aus dem Tweet-Text

1-1 Vorbereitung

Importieren Sie zunächst die zu verwendenden Bibliotheken und stellen Sie eine Verbindung zu mongoDB her.

%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

Die Tweet-Informationen selbst enthalten ein Feld namens "Koordinaten". Wenn Sie mit Standortinformationen wie GPS twittern, werden hier die Breiten- und Längengrade angegeben. Lassen Sie uns zunächst sehen, wie viele Personen mit Standortinformationen twittern.

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),"%"

** <<< Ergebnis >>> ** location_ratio-compressor.png

Anzahl der Tweets ohne Standortinformationen
444,188
Anzahl der Tweets mit Standortinformationen
5,122
Tweet-Rate für Standortinformationen
1.140 %
* Zählen ohne RT

@ arieee0s "Einführung der SNS-Benutzerpositionsschätzungsmethode aus Text und Anwendungsbeispiel" Im Fall von p24 beträgt das Verhältnis von Tweet zu Positionsinformationen 0,3% Wie es war, können staba-Enthusiasten dazu neigen, ein wenig w zu bestehen (obwohl ich es nicht sagen kann, wenn ich nicht teste, ob der Unterschied signifikant ist)

1-2. Extraktion von Wörtern, die Ortsnamen angeben

Ich habe nach einigen geografischen Informationen aus dem Text des Tweets gesucht, aber ich habe festgestellt, dass MeCab den Ortsnamen überhaupt extrahieren kann, also werde ich ihn verwenden. Wie praktisch! Nachfolgend finden Sie ein Beispiel für eine morphologische Analyse mit MeCab, die in Roppongi und Shibuya zu finden ist. Diese sind jedoch als "richtige Nomenklatur, Region" gekennzeichnet, damit sie leicht extrahiert werden können: zufrieden:

Nomen heute,Anwalt möglich,*,*,*,*,heute,heute,Kyo
Ist ein Assistent,Hilfe,*,*,*,*,Ist,C.,Beeindruckend
Roppongi Substantiv,Proprietäre Nomenklatur,Bereich,Allgemeines,*,*,Roppongi,Roppongi,Roppongi
Hilfs,Fallassistent,Allgemeines,*,*,*,Zu,D.,D.
Geh verb,Unabhängigkeit,*,*,Fünf-Stufen / Ka-Erinnerung,Grundform,gehen,Iku,Iku
Aber der Assistent,Verb verbinden,*,*,*,*,aber,Ked,Ked
, Symbol,Lesepunkt,*,*,*,*,、,、,、
Dieser Zusatz,*,*,*,*,*,Das,Sono,Sono
Pre-Nomen,Anwalt möglich,*,*,*,*,Bisherige,Mae,Mae
Hilfs,Fallassistent,Allgemeines,*,*,*,Zu,D.,D.
Shibuya Substantiv,Proprietäre Nomenklatur,Bereich,Allgemeines,*,*,Shibuya,Shibuya,Shibuya
Hilfs,Fallassistent,Allgemeines,*,*,*,Zu,D.,D.
Going Verb,Unabhängigkeit,*,*,Fünf-Stufen / Ka-Erinnerung,Kontinuierlicher Typ,gehen,Iki,Iki
Tai Assistent Verb,*,*,*,Spezielles Thailand,Grundform,Wollen,Thailand,Thailand
.. Symbol,Phrase,*,*,*,*,。,。,。

Da die Nomenklatur bereits mit MeCab extrahiert und in die DB eingefügt wurde, wird der Ortsname von hier extrahiert und in ein anderes Feld eingetragen.

#Extrahieren Sie den Bereichsnamen mit Mecab und Feld aus dem Text: location_Als Namen festlegen
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 != "":  #Kopf- und Fußzeilen ausschließen
            #Wählen Sie eine geeignete Nomenklatur und ein lokales Wort
            if (node.feature.split(",")[1] == "Proprietäre Nomenklatur") and (node.feature.split(",")[2] == "Bereich"):
                plain_word = node.feature.split(",")[6]
                if plain_word !="*":
                    result_dict[u'Bereichsname'].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'Bereichsname']}}})

1-3. Vom Ortsnamen in Breiten- und Längengrad umwandeln

Nachdem der Ortsname extrahiert wurde, werden wir die darauf basierenden Längen- und Breitengrade erfassen. Ich verwende die Geopder-API von Yahoo! Wird zu mongoDB gebracht.

Erstellen Sie zunächst eine Liste mit Ortsnamen, für die Sie Längen- und Breitengradinformationen wünschen.

#Tweete den Standort_Machen Sie den Namen eindeutig und das Wörterbuchobjekt"loc_name_dict"Aggregieren zu
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

Setzen Sie den aggregierten Ortsnamen auf Yahoo! Geocoder API, um Informationen zu Längen- und Breitengraden abzurufen. Da appid für die Verwendung der Geocoder-API erforderlich ist, erstellen Sie ein Konto in Yahoo! Developer Network, rufen Sie die Appid ab und legen Sie sie fest.

#Fügen Sie dem aus dem Tweet extrahierten Ortsnamen Breiten- und Längengrade hinzu und importieren Sie ihn in mongoDB
def get_coordinate_from_location(location_name):
    payload = {'appid': '<Yahoo Appid einstellen>', 'output':'json'} #Stellen Sie die Appid auf die Ihres Kontos ein!
    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)
        #Berechnen Sie den Durchschnitt aus der Liste der durch die Abfrage erhaltenen Standortinformationen und verwenden Sie ihn als Breiten- und Längengrad des Ortsnamens.
        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 []
    
#Ortsname-Eine Tabelle mit Links zu Längen- und Breitengraden"location"Einstellen
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. Hinzufügen von Breiten- und Längengradinformationen zu Tweet-Daten

Nachdem der Ortsname und der Breiten- / Längengrad verknüpft wurden, werden wir dies auf die Tweet-Daten anwenden. Katakana-Ortsnamen drücken häufig Ländernamen usw. aus, und es gab nur wenige Fälle, in denen sie als ihr eigener Standort ausgedrückt wurden, sodass Ortsnamen mit nur Katakana ausgeschlossen wurden. Darüber hinaus gibt es in der Stadt Izumi, Präfektur Toyama, ein Gebiet namens Shinkaihotsu, das jedoch ausnahmsweise ausgeschlossen wurde, da es in vielen Fällen in einem anderen Sinne verwendet wurde. (Es ist ein seltener Ortsname) Außerdem ist "Japan" sehr vage, also schließe ich es aus.

#Hinzufügen von Textpositionsinformationen zu Tweet-Daten

#Extrahieren Sie den Ortsnamen und den Breiten- / Längengrad aus der Datenbank und behalten Sie sie im Wörterbuchobjekt
loc_dict = {loc['word']:[loc['longitude'],loc['latitude']] for loc in location_dict.find({})}

def get_coord(loc_name):

    #Schließen Sie Ortsnamen nur in Katakana aus (da es viele Ländernamen gibt und es unwahrscheinlich ist, dass sie den Ort darstellen)
    regex = u'^[EIN-Nieder]*$'
    match = re.search(regex, loc_name, re.U)
    if match:
        return 0
    
    #Ausgeschlossene Wörter (weil die neue Entwicklung aus irgendeinem Grund ein Ortsname ist und Japan zu vage, aber häufig ist)
    if loc_name in [u'Neue Entwicklung', u'Japan']:
        return 0
    
    if loc_name in loc_dict:
        #Wenn dies der Fall ist, geben Sie die Standortinformationen zurück
        return (loc_dict[loc_name][0],loc_dict[loc_name][1])
    else:
        #Wenn nicht, geben Sie Null zurück
        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'])
        #True, wenn Standortinformationen vorhanden sind,Wenn nicht, Generierung falscher Sequenzen
        ind = np.array(map(exist_check, name_list))
        #Wahre Anzahl zählen
        T_num = len(ind[ind==True])

        #Verarbeiten Sie nur Tweets mit Ortsnamen
        if T_num > 0:
            coordRet = map(get_coord, name_list[ind])  # key_list[ind]Ist nur für diejenigen, die Standortinformationen haben
            [coordRet.remove(0) for i in range(coordRet.count(0))]  #0 entfernen
            if len(coordRet) == 0:
                continue
            #Übernehmen Sie den ersten Ortsnamen (Es gibt Fälle, in denen mehrere Ortsnamen im Tweet enthalten sind, aber der erste Platz ist wichtiger)
            lon, lat = coordRet[0]
            #In DB reflektiert
            tweetdata.update({'_id' : d['_id']}, 
                     {'$set' : {'text_coord' : {'longitude':lon, 'latitude': lat}}})

2. Visualisierung der Standortinformationen

2-1. Plot

Nachdem wir alle Daten haben, möchte ich sie visualisieren. Zunächst werde ich endlich planen, ohne an irgendetwas zu denken.

#Extraktion von Breiten- und Längengradinformationen in 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})])

#Extrahieren Sie die Informationsliste zum Extrahieren von Tweets aus der Datenbank
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]  #Breite(latitude)
lon1 = loc_data[:,1]  #Längengrad(longitude)

lat2 = text_coord[:,0]  #Breite(latitude)
lon2 = text_coord[:,1]  #Längengrad(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')

Beginnen wir mit den Tweet-Daten, die ursprünglich Breiten- und Längengrade enthalten.

white_map_01-compressor.png

Wie wäre es? Ich bin mir nicht sicher.

Wie Sie vielleicht bemerkt haben, befinden sich in der oberen rechten Ecke Flecken.
Ich möchte es ein wenig erweitern.
white_map_02-compressor.png

Es ist Japan! : smile:
Da das Suchwort "staba" ist, ist es natürlich, aber die Tatsache, dass der japanische Archipel mit etwa 1%, 5.000 Tweets identifiziert werden kann, bedeutet, dass die Leute, die mit "staba" twittern, gleichmäßig verteilt sind. Es kann gesagt werden, dass es gibt.

2-2. Plotten auf der Karte

Jetzt möchte ich diese Daten auf die Karte setzen und sie klarer sehen. Wir werden eine Bibliothek namens Matplotlib basemap verwenden. Installieren Sie die Bibliothek daher unter Bezugnahme auf diesen Link.

#Plot auf der Karte
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)))

Nun, das ist das Ergebnis.

map_01-1-compressor.png

Wenn Sie es auf die Karte setzen, können Sie auf einen Blick sehen, aus welchem Bereich Sie twittern. Da ich nach "staba" suche, gibt es viele in Japan, aber überraschenderweise werden "staba" -Tweets auch aus verschiedenen Regionen wie Europa, den USA und Südostasien erstellt!

Ich werde es auch erweitern.

map_01-2-compressor.png

Es füllt Japan w Sie können nach dem Tweet hier und da in Taiwan, China, Südkorea und Südostasien sehen.

Weiter ausbauen.

map_01-2-compressor.png

Obwohl es überall verstreut ist, ist Tomeihan immer noch besonders überfüllt.


map_01-4-compressor.png

Immerhin gibt es viele in städtischen Gebieten, in denen die Bevölkerung groß zu sein scheint, und es wurde nicht aus Berggebieten getwittert.

map_01-5-compressor.png

Dies ist derjenige, der sich auf die Metropolregion mit der höchsten Vergrößerung konzentrierte. Der weißliche Teil ist der einfache Teil, aber es gibt viele Tweets von hier, und es wird nicht vom grünen Bergteil getwittert. Stimmt das nicht irgendwie mit der Intuition überein?

3. Versuchen Sie, die Standortinformationen zu visualisieren, die aus dem Tweet-Body ## abgeleitet wurden

Die Längen- und Breitengradinformationen, die aus dem Text abgeleitet werden können, sind ** 50.310 **, was fast dem Zehnfachen der vorherigen auf GPS-Informationen basierenden Daten entspricht. Da der Prozess des Zeichnens des vom Tweet-Body geschätzten Längen- und Breitengrads mit dem vorherigen Code bereits enthalten ist, werden wir uns die Karte erneut ansehen.

Ich freue mich darauf zu sehen, wie die Handlung anhand des Ortsnamens im Textkörper des Tweets aussehen wird.

map_03-1-compressor.png

Dieses Mal bin ich ganz auf Japan konzentriert. Dies liegt daran, dass MeCab japanische Ortsnamen extrahiert und Katakana-Ortsnamen wie oben erwähnt ausschließt. Ich denke, die Ergebnisse sind wie erwartet.

Vergrößern.

map_03-3-compressor.png

Es ist enger als zuvor! Hokkaido ist weniger dicht, aber Honshu, Shikoku und Kyushu scheinen ziemlich dicht zu sein. Bei der Konvertierung von einem Ortsnamen in Längen- und Breitengrad wurde ein mysteriöser Ortsname oder ein Punkt in der Mitte des Meeres eingeschlossen, sodass ich denke, dass GPS-Informationen hinsichtlich der Genauigkeit nicht zu übertreffen sind. Da der Ortsname im Textkörper des Tweets nicht immer die aktuelle Position angibt, denke ich, dass sich die Genauigkeit verbessern wird, wenn eine Methode zum Erraten der Verwendung des Ortsnamens im Satz aus den umgebenden Wörtern verwendet werden kann. Daher möchte ich dies zu einem Problem machen. Ich werde.

Vergrößern.

map_03-4-compressor.png

Das heißt, es ist auf eine schöne Weise verstreut!

Endlich wieder die Metropolregion.

map_03-5-compressor.png

Irgendwie scheint die Anzahl geringer zu sein als die der GPS-Informationen, da der Breiten- und Längengrad aus dem Ortsnamen ermittelt wird und daher am selben Punkt aggregiert wird. Sie können dunkelorange Punkte sehen, was bedeutet, dass viele Punkte an derselben Stelle gesammelt werden.

Also habe ich diesmal die Positionsinformationen aus den Tweet-Daten herausgenommen und visualisiert. Was ist der Inhalt des Murmelns von "Staba" in Übersee? Es gibt einige Dinge, auf die ich neugierig bin, aber es ist lange her, deshalb werde ich in der nächsten Folge über die Analyseergebnisse schreiben.
Den vollständigen Code finden Sie unter Gist.


Recommended Posts

Visualisierung und Analyse von Stava Twitter-Datenstandortinformationen
Analyse von Finanzdaten durch Pandas und deren Visualisierung (2)
Analyse von Finanzdaten durch Pandas und deren Visualisierung (1)
Twitter-Daten analysieren | Trendanalyse
Holen Sie sich mit Python eine große Menge von Starbas Twitter-Daten und probieren Sie die Datenanalyse Teil 1 aus
Datenanalyse beginnend mit Python (Datenvisualisierung 1)
Datenanalyse beginnend mit Python (Datenvisualisierung 2)
Python-Visualisierungstool für die Datenanalyse
[In-Database Python Analysis-Lernprogramm mit SQL Server 2017] Schritt 3: Erkunden und Visualisieren von Daten
Datenanalyse Titanic 2
Schöne Grafikzeichnung mit Python-Seaborn erleichtert die Datenanalyse und -visualisierung Teil 1
Datenanalyse Python
Implementieren Sie "Data Visualization Design # 3" mit Pandas und Matplotlib
Wunderschönes Zeichnen mit Python-Seaborn erleichtert die Datenanalyse und -visualisierung Teil 2
Datenanalyse Titanic 1
Verarbeitung und Beurteilung des Datenanalyseplans (Teil 1)
Datenanalyse Titanic 3
Verarbeitung und Beurteilung des Datenanalyseplans (Teil 2)
Organisation grundlegender Verfahren zur Datenanalyse und statistischen Verarbeitung (4)
Versuchen Sie eine rudimentäre Stimmungsanalyse für Twitter Stream API-Daten.
Übersicht und Tipps von Seaborn mit statistischer Datenvisualisierung
Organisation grundlegender Verfahren zur Datenanalyse und statistischen Verarbeitung (2)
Geschichte der Bildanalyse von PDF-Dateien und Datenextraktion
Versuchen Sie, Twitter-Daten in SPAM und HAM zu unterteilen
[Regelungstechnik] Visualisierung und Analyse der PID-Regelung und der Sprungantwort
Analyse der Messdaten (2) -Hydrobacter und Anpassung, lmfit Empfehlung-
Visualisierung von Daten anhand einer erklärenden Variablen und einer objektiven Variablen
Datenanalyse mit xarray
Python-Datenvisualisierungsbibliotheken
Datenanalyse Übersicht Python
Negative / Positive Analyse 2 Twitter Negative / Positive Analyse (1)
Datenvisualisierung mit Pandas
Einfache Analyse und gemeinsame Nutzung mit re: dash, einem Open-Source-Tool zur Datenvisualisierung Teil 1 - Installation
Python-Datenanalysevorlage
Negative / Positive Analyse 3 Twitter Negative / Positive Analyse (2)
Datenanalyse mit Python
[Einführung in Data Scientists] Deskriptive Statistik und einfache Regressionsanalyse ♬