Pythonを使ってTwitterのタイムラインを収集する
「実践 機械学習システム」の第六章ではTwitterのタイムラインを使った感情分析を行っています。ただし英語のTweetを対象としているので、(たぶん)*1サンプルコードを実行してもあまり面白くはないのです。できることなら日本語でやりたい、というわけで自分のタイムラインからTweetを収集してみましょう。実行環境はPython3系を想定してますが、2系でも動くはずです。
基本的には↓のやり方を踏襲します。
必要なものは以下
Twitter APIの認証キーを取得する
Twitterのアプリケーションマネジメントサイトに行ってアプリケーションの登録を行います。
"Create New App"から必要事項を入力していくと特に問題なく登録できるはず。最近は電話番号の登録を迫られるみたいです。営業電話でもかかってくるんだろうか。。
登録が完了したら"Consumer Key (API Key)"の欄にある"manage keys and access tokens"のリンクから先に進み、以下の4種類のキーを取得します。
これはコピペでどっかわかるところに保管しておきます。
Pythonライブラリの取得
pip使って導入。
pip3 install requests_oauthlib pip3 install pandas
タイムラインの収集
Twitter APIでタイムラインを取得しますが、一度に取得できるTweet数の上限とAPI制限があるのでその辺と上手く付き合います。取得Tweetの上限が100件、API制限が15分に15回までとのこと。
分類器作る場合には10,000件ほどのTweetが欲しいので、パラメータで100件とってくるよう指定して、数分ごとに再取得を繰り返すようにしておきます。
CK、CS、AT、ASには先ほどコピペしたConsumer Key (API Key)、Consumer Secret (API Secret)、Access Token、Access Token Secretをそれぞれ入れておきます。
from requests_oauthlib import OAuth1Session import json import time CK = 'XXXXXXXXXXXXXXXXXXXXXX' CS = 'XXXXXXXXXXXXXXXXXXXXXX' AT = 'XXXXXXXXXXXXXXXXXXXXXX' AS = 'XXXXXXXXXXXXXXXXXXXXXX' url = "https://api.twitter.com/1.1/statuses/home_timeline.json" params = {'count': 100} TweetList = [] twitter = OAuth1Session(CK, CS, AT, AS) for i in range(100): req = twitter.get(url, params = params) if req.status_code == 200: timeline = json.loads(req.text) for tweet in timeline: TweetList.append(tweet["text"]) else: print ("Error: %d" % req.status_code) time.sleep(240)
4分もあればタイムラインが一巡しそうだったので、timeモジュールを使って240秒ごとに回るように指定をかけています。これを7時間ほど置いとくとTweetListにタイムラインが格納されていきます。
CSVで吐き出す
とってきたタイムラインをテキストデータとして加工したいので、Pandasを使ってデータフレームに落とし込み、それをCSVとして吐き出します。他にもやり方はありますが、型やエンコードで嵌らないのでPandasがおすすめです。
import pandas as pd df = pd.DataFrame(TweetList) df.to_csv('hogehoge.csv')
これで教師用データの収集はできたはず。後は発言にネガティブ/ポジティブ/そのほかのラベル貼りをやらないと。その辺は別枠で。
追記
Tweetは200件まで取れました。教えていただいてありがとうございます!
@Takaki_ Twitterの取得制限について、15分に何回APIが叩けるかはここですね。https://t.co/AEG08RJV2J
— まぽよん@しばらくポケモン勢 (@mapoyon) May 8, 2016
一度に取得出来る量については200件まで取れそうですけどダメでしたか?https://t.co/niDEazahLR
*1:実際に動かしてないのでホントのところは不明
Python3でJSONデータを解析する
ググって出てくるJSON解析の方法はPython2系ばっかりなので、Python3系でのやり方をまとめます。 JSONデータは「 pythonのurllib2でjsonを取得して解析する - 文系プログラマによるTIPSブログ 」でも使われているお天気Webサービスを使います。
APIから読み込む
JSON形式のデータはWEBAPIから呼ぶことが多いかと思います。Pythonの標準ライブラリurllibとjsonを使ってAPI経由でデータを取りに行きます。
import urllib import json url = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=400040' html = urllib.request.urlopen(url) jsonfile = json.loads(html.read().decode('utf-8'))
これで変数jsonfile内にデータが格納されました。jsonfileを呼び出してやるとそれっぽいデータが返ってきます。 以下はiPython環境での出力サンプルです。
In [1]jsonfile Out[1]: {'copyright': {'image': {'height': 26, 'link': 'http://weather.livedoor.com/', 'title': 'livedoor 天気情報', 'url': 'http://weather.livedoor.com/img/cmn/livedoor.gif', 'width': 118}, 'link': 'http://weather.livedoor.com/', 'provider': [{'link': 'http://tenki.jp/', 'name': '日本気象協会'}], 'title': '(C) LINE Corporation'}, 'description': {'publicTime': '2016-04-30T16:32:00+0900', 'text': ' 九州北部地方は、高気圧に覆われ、晴れています。\n\n 30日の九州北部地方は、高気圧に覆われ、晴れでしょう。\n\n 5月1日の九州北部地方は、高気圧に覆われ、晴れでしょう。\n\n 波の高さは、対馬海峡では30日と5月1日は2メートルでしょう。九州\n西海上では30日と5月1日は1.5メートルでしょう。豊後水道では30\n日と5月1日は1メートルでしょう。\n 福岡県の内海では、30日と5月1日は0.5メートルでしょう。\n\n<天気変化等の留意点>\n 特にありません。'}, 'forecasts': [{'date': '2016-04-30', 'dateLabel': '今日', 'image': {'height': 31, 'title': '晴れ', 'url': 'http://weather.livedoor.com/img/icon/1.gif', 'width': 50}, 'telop': '晴れ', 'temperature': {'max': None, 'min': None}}, {'date': '2016-05-01', 'dateLabel': '明日', 'image': {'height': 31, 'title': '晴れ', 'url': 'http://weather.livedoor.com/img/icon/1.gif', 'width': 50}, 'telop': '晴れ', 'temperature': {'max': {'celsius': '26', 'fahrenheit': '78.8'}, 'min': {'celsius': '12', 'fahrenheit': '53.6'}}}, {'date': '2016-05-02', 'dateLabel': '明後日', 'image': {'height': 31, 'title': '晴のち曇', 'url': 'http://weather.livedoor.com/img/icon/5.gif', 'width': 50}, 'telop': '晴のち曇', 'temperature': {'max': None, 'min': None}}], 'link': 'http://weather.livedoor.com/area/forecast/400040', 'location': {'area': '九州', 'city': '久留米', 'prefecture': '福岡県'}, 'pinpointLocations': [{'link': 'http://weather.livedoor.com/area/forecast/4020200', 'name': '大牟田市'}, {'link': 'http://weather.livedoor.com/area/forecast/4020300', 'name': '久留米市'}, {'link': 'http://weather.livedoor.com/area/forecast/4020700', 'name': '柳川市'}, {'link': 'http://weather.livedoor.com/area/forecast/4021000', 'name': '八女市'}, {'link': 'http://weather.livedoor.com/area/forecast/4021100', 'name': '筑後市'}, {'link': 'http://weather.livedoor.com/area/forecast/4021200', 'name': '大川市'}, {'link': 'http://weather.livedoor.com/area/forecast/4021600', 'name': '小郡市'}, {'link': 'http://weather.livedoor.com/area/forecast/4022500', 'name': 'うきは市'}, {'link': 'http://weather.livedoor.com/area/forecast/4022800', 'name': '朝倉市'}, {'link': 'http://weather.livedoor.com/area/forecast/4022900', 'name': 'みやま市'}, {'link': 'http://weather.livedoor.com/area/forecast/4044700', 'name': '筑前町'}, {'link': 'http://weather.livedoor.com/area/forecast/4044800', 'name': '東峰村'}, {'link': 'http://weather.livedoor.com/area/forecast/4050300', 'name': '大刀洗町'}, {'link': 'http://weather.livedoor.com/area/forecast/4052200', 'name': '大木町'}, {'link': 'http://weather.livedoor.com/area/forecast/4054400', 'name': '広川町'}], 'publicTime': '2016-04-30T17:00:00+0900', 'title': '福岡県 久留米 の天気'}
要素ごとにアクセスしようとおもったら、パースした後の変数に引数を渡します。
In [1]:jsonfile['description'] Out[1]: {'publicTime': '2016-04-30T16:32:00+0900', 'text': ' 九州北部地方は、高気圧に覆われ、晴れています。\n\n 30日の九州北部地方は、高気圧に覆われ、晴れでしょう。\n\n 5月1日の九州北部地方は、高気圧に覆われ、晴れでしょう。\n\n 波の高さは、対馬海峡では30日と5月1日は2メートルでしょう。九州\n西海上では30日と5月1日は1.5メートルでしょう。豊後水道では30\n日と5月1日は1メートルでしょう。\n 福岡県の内海では、30日と5月1日は0.5メートルでしょう。\n\n<天気変化等の留意点>\n 特にありません。'}
はまりどころ
Python2系のurllib2ではエンコーディング処理までやってくれていたような気がします。 Python3のurllibではデコードしないとエラーが出ます。JSONのパース時にdecode('utf-8')でデコードします。
やりたいこと
これ使って総務省API(Ver2)を上手くたたく方法模索中。
追記
Pythonの2系ではurllib2を使ってURLを読み込むのが通例でした。
import urllib import urllib2 url = urllib2.urlopen('http://www.hogehoge.com')
python3系ではurllib2の持っていた機能がurllibに統合され、urllib.requestから呼び出せるようになっているようです。
最近読んだ本・読んでいる本
余裕がなくなってても定期的に本を読む習慣は続けたい今日この頃。最近読んだ本と読んでいる本の棚卸をしておきます。
コンテンツの秘密―ぼくがジブリで考えたこと (NHK出版新書 458)
- 作者: 川上量生
- 出版社/メーカー: NHK出版
- 発売日: 2015/04/10
- メディア: 新書
- この商品を含むブログ (11件) を見る
アニメやドラマ、その他のコンテンツがなぜ人を惹きつけるのかということを探求した本。川上量生さんはぼんやりした概念をまとめることが素晴らしく上手いです。 天才クリエータとは、人を魅了するコンテンツとは何かということをまとめつつ、良質のコンテンツは普遍化し、良いクリエータは普遍化するコンテンツの中に引っかかりや別の軸を作っているという。この本はもう一回通読して自分の中で咀嚼しておきたい感じ。
- 作者: G.M.ワインバーグ,木村泉,ジェラルド・M・ワインバーグ
- 出版社/メーカー: 共立出版
- 発売日: 1990/12
- メディア: 単行本
- 購入: 21人 クリック: 197回
- この商品を含むブログ (93件) を見る
秘密続き。この本がすこぶる読みにくくて読み進まない。書いてあること、伝えたいメッセージはわかるものの読むのがつらい。物理本(書籍)という制限もあって空き時間に読めないのもつらい。読書継続中。
- 作者: ジェラルド・M・ワインバーグ,伊豆原弓
- 出版社/メーカー: 日経BP社
- 発売日: 2003/07/29
- メディア: 単行本(ソフトカバー)
- 購入: 8人 クリック: 133回
- この商品を含むブログ (78件) を見る
とはいえ尊敬するベンチャー社長の人がお勧めしてて、ちょっと読んだだけでも知見を得られることはわかったので何とか慣れたい。こういう時には同じ著者の簡単な本から読むのが良いと思ってるので、ワインバーグ氏の電子書籍も並行して読んでおります。こっちは個人的に結構読みやすい。コンサルタントの道具箱はおそらく「コンサルタントの秘密」の要約版なので、こちらの本からぼちぼち攻めて行こうと思います。電子書籍なのでいつでも気軽に読めますし。
3月に入れば若干仕事の余裕・心の余裕が出てくるといいなあ。
近況
仕事が色々積みあがっててココロボで遊ぶのも、機械学習を手掛けるのも何も進んでおりません。やることが増えるとパフォーマンスが落ちてくるのは知ってたので、再度GTDの教本を読みつつ何とかしようとしてる今日この頃。
- 作者: デビッド・アレン,田口元
- 出版社/メーカー: 二見書房
- 発売日: 2008/12/24
- メディア: 単行本(ソフトカバー)
- 購入: 127人 クリック: 1,493回
- この商品を含むブログ (304件) を見る
最近社内の活動として、オープンソースの利用を推進しようとしていたり。地理空間系の業界ではOSSで出来ることが結構多くて(というか普段の作業はOSSで賄えるので)、作業を効率的にやるためにもOSS普及させたいなと考えています。
地理空間系のOSSはFOSS4Gと言われますが、この導入マニュアルと書籍ライクな形にして社内に波及させていければと。可能であれば世の中にも共有できればと。OSSで得たものはOSSに返す的な。
しかしGISに関わってたかが数年。まだまだつまるところが多いなあ。MapServer系の話やタイルづくりのところが全然理解できない。。