2014年11月29日土曜日

Twitter分析:インフルエンザ2014-2015

 先日インフルエンザの流行が例年より早く始まったという報道を目にしました

 TwitterのTweet数の変化から、これを確認してみます。
  • 期間:2010年8月1日から2014年11月28日まで(諸原因による欠落あり)
  • 対象:TwitterStreamingAPI で取得できたTweet(全体の約1%)のうち日本語文
  • 抽出:「インフルエンザ」を含む文(「鳥インフルエンザ」を含む文は除外)
  • 1日単位のデータを2つのパターンでグラフ化
    • 出現頻度=「インフルエンザ」を含む文の数
    • 出現率 =出現率/日本語文の数

■出現頻度
クリックで拡大

 毎年明らかなピークができているのがわかります。
 昨年までの傾向をさらに見ると、11月の終わりに小さな山ができて、2月始めに大きな山が来ています。

 11月終わりの山はインフルエンザ予防接種関係のつぶやきによるもので、2月の山がインフルエンザのピークだと考えられます。

 次の資料と比較して、ほぼピークが一致していることが見て取れます。


 さて、例年に比較して今年のTweet数の変化から、今後のインフルエンザの流行の傾向を判断できるでしょうか?

 11月27日、28日にバーストが見られますが、これはむしろ前述の報道を受けてのツイートが多く、「インフルエンザにかかった」というようなTweetとは異なり、患者数と直接的に結びつくものではありません。
 11月26日以前に小規模な山ができてますが、これは例年の予防接種関連のものと判断できます。

 したがって、11月26日までの「インフルエンザ」Tweet数からは、流行が早く始まったことを判断することはできませんでした。

 では、今後、大流行になるか、例年並みなのかを判断する方法はあるでしょうか?

 流行が早く始まった=患者総数が多くなる、ということを示唆しています。
 一方、この報道が社会にフィードバックされた結果、対策を取る人が増えて患者数が抑制される可能性もあります。

 以上から、今後のTweet数に対して、次のような判断が可能ではないかと考えています。
  • 今回のバーストが一時的なもので1月に向けて減少に転ずる → 例年と同等
  • このまま増加する → 大流行 or ピーク前倒し
この仮説についての検証は行うつもりですが、報告できるかどうかは未定です。
 (個人的事情の見通しが立たないので…



■出現率

 上記の出現頻度による分析で、「インフルエンザ」に関する分析は終わっています。
 ところが、ここで一つ問題があります。「出現頻度でいいのか」ということです。

 TwitterStreamingAPI で取得できたTweet(全体の約1%)のうち日本語文の数は、明らかに大幅に増加しているのです。
  • 2010年10月:約 150,000 ツイート/日
  • 2014年11月:約 850,000 ツイート/日
そこで、試しに出現率=出現頻度/総数でグラフ化すると、次のようになってしまいます。

クリックで拡大

 2月のピーク位置は一致しますが、毎年のピーク量が実際の流行状況から外れています。
 つまり、出現頻度のままの方が、現実との相関が高いのです。

 どうやら、「インフルエンザ」に関しては、出現頻度で見た方が良さそうです。

 Tweet総数が増えれば、「インフルエンザ」Tweetもそれに比例して増えそうなのですが、なぜそうなってないのでしょうか?

 原因としていくつかの仮説が立てられます。
  • 各人の興味の多様化
  • 個人情報や故人の徳的に関わる可能性のあることをTweetしなくなった
  • スパムの増加
  • (その他)
しかし、「インフルエンザ」だけでこの仮説を裏付けすることはできません。
 今後、他のデータの分析も含めての宿題とさせてください。



■参考ページ(インフルエンザ関連)

インフルエンザ対策特集

2014年11月27日木曜日

rubyで日本語文の抽出

 Twitterのつぶやきを収集することはできましたが、現実には日本語以外の文は必要ありません。

 そこで、rubyを使って日本語の文だけを取り出します。
 日本発信の文でも日本人の書いた文でもなく、日本語で書かれた文を抽出するのです。

 ここでは、「ひらがな」と「カタカナ」の含まれている文だけを抽出する方法を紹介します。

 rubyの「=~」メソッドによるマッチングの戻り値を利用して、ひらがなまたはカタカナを含んでいるかどうかを判定します。
  • マッチング成功 → マッチングした文字の位置を返す
  • マッチング失敗 → nil を返す


■サンプルコード
while line = gets
 pos_h = ( line =~ /\p{Hiragana}/) # ひらがなの位置(なければnil)
 pos_k = ( line =~ /\p{Katakana}/) # カタカナの位置(なければnil)

 if pos_h || pos_k then
  puts line
 end
end

■参考ページ


2014/11/28 typoを修正

2014年11月26日水曜日

雇用保険説明会に参加して、驚いたこと

 失業保険をもらうために、ハローワークに登録する必要があります。
 元の会社から必要書類が届いて、その翌日に登録しました。

 登録してから初回認定までの間に「雇用保険説明会」が開催され、それに参加しました。
 内容について、特筆すべきものもなく、「早く再就職すればそれだけ有利ですよ」というようなことを言い方を変えて連呼しているだけのもの。
大型スクリーンに表示した説明を担当者がなぞる形式で行われます。

 それは、担当者がPCをセッテイングしているときに起こりました。

 4月にWindowsXPのサポートが打ち切られましたが、もしかしてXPはダメだと言うことでWindows2000に切り替えた(戻した)のでしょうか?

 しかし、Windows2000はXPよりずーっと前(2010年)にサポート終了されています。
 (『Windows 製品のサポート ライフサイクル について』参照)

 Windows2000はビジネス向けOSということもあり、サポート終了が世間一般では騒がれなかったので知らなかったのかもしれません…

 Windows2000もサポート終了してますよ > ハローワークさん


2014年11月21日金曜日

Ruby2.0でTwitterStreamingAPI (1.1) を使う(改):TweetStream

 以前に、TwitterStreamingAPI 1.1 をhttp接続で使う方法を掲載しました。
 その方法では問題が発生する場合があることがわかり、その対処を行ったので紹介します。

 その問題は、最近の(処理速度の速い)PCを使うと気がつかないかもしれません。
 しかし、少し前の(処理速度の遅い)PCを使うとCPU100%状態が続き、プログラムの処理が追いつかなくなって、エラー終了することが頻繁に発生します。

 以前はとりあえず動作することが目的だったので、速いPCで動作すれば良かったのですが、その後、限られた資源の効率よい役割配分が求められたので、必要に迫られて試行錯誤しました。


 結論としては、以前は不採用としたTwitterStreamを使う方法できちんと動作することを確認しました。

 古いPC上でのCPU負荷を、ざっくりとした比較をすると
http接続による処理  → 100%オーバー
TwitterStreamを使用 → 数%程度
となりました。


■前準備
インストールには、Development Kitが必要です。
(1) Linux
ruby-develをインストールします
yum install ruby-devel

そのほかに、g++など基本的な開発ツール見つからずにエラーになる場合もあるようです。適宜インストールしてください。

(2) Windows
Develipment kitをインストールします。
次のページにわかりやすい説明があるのでご覧ください

■gemのインストール
gem install tweetstream


■サンプルコード
1時間単位で別ファイルに、TweetID、日時、ユーザID、Tweet内容を出力します。
コンシュマーキーやアクセストークンは別途取得してください。
require "tweetstream"
require "date"

consumer_key    = "xxxxxxxx"
consumer_secret = "xxxxxxxx"
access_token           = "xxxxxxxx"
access_token_secret    = "xxxxxxxx"
TweetStream.configure do |config|
 config.consumer_key       = consumer_key
 config.consumer_secret    = consumer_secret
 config.oauth_token        = access_token
 config.oauth_token_secret = access_token_secret
 config.auth_method        = :oauth
end

TweetStream::Client.new.sample do |status|
 next unless status.user

 dt = status.created_at.to_s.split( /[ :-]/ )
 fname = "#{dt[0]}#{dt[1]}#{dt[2]}_#{dt[3]}.txt"
 daytime = "#{dt[0]}-#{dt[1]}-#{dt[2]} #{dt[3]}:#{dt[4]}:#{dt[5]}"

 f = open( fname, "a:utf-8" )
 f.puts "#{status.id}\t#{daytime}\t#{status.user.screen_name}\t#{(status.text).gsub(/[\r\n\t]+/, " ")}"
 f.close
end
exit


※Webを検索するとTweetStreamにパッチの必要性との情報もありますが、最新環境ではパッチ不要で動作しています。RubyやGemのバージョンおよび動作環境に依存する場合もあるので、状況に応じて対応してください。


2014年11月20日木曜日

iPadからブログ投稿(Blogger)する方法を試行錯誤

以前はPCを使ってる時間が長かったのですが、最近は移動時間や外にいることが多くなり、当然のようにPCよりもiPadに触れる時間が圧倒的に長くなりました。

ということは、ブログの更新も、iPadでできるようにしないと、また更新が滞るんじゃなかろうか…

という不安が頭をもたげてきたので、iPadから投稿する方法を試行錯誤しました


1.アプリ

iOSで何かするとしたら、まずアプリですよね。
当然Googleもアプリくらい出してるはず…と思って調べると、すぐ見つかりました。
Blogger」…そのまんまですね。

レビューを読むと、酷い有様なんですが、ものは試しとインストールしました。
使ってみると…やっぱり、ダメですね(>_<)

機能的に劣っているのは覚悟していましたが、最大の難点は、ある程度の行入力していくと、入力している画面がキーボードの下に隠れてしまうということです。

内容確認のためには、一旦キーボードを閉じないといけないという有様。
分割キーボードにすると、なんとか見えますが、入力しづらい。

アンインストールしました。


2.Web

Webを使えば大丈夫でした。
当然ながら、PC版と同じ操作が可能です。

とはいえiPadだけでブログを書くというのは難しいですので、
  • 外出時(iPad)下書き/メモ
  • 自 宅(PC) 清書&必要な情報の付加→公開
という使い分けになりそうです。

しばらくは、これで様子を見てみます。


2014年11月19日水曜日

生きてます(生存確認)

 ここしばらく…というか1年以上、ブログの更新が停滞していましたが、様々なしがらみから解放されたチャンス(?)を最大限に活用して、ブログの更新を再開します。

Twitterでも断片的にTweetしていましたが
  • リストラされました(会社がなくなりました)
  • 現在、無職で求職中です
  • ハローワーク通ってます
というような状況です。

 以前収集していたデータは、元々、個人的に収集していたものなのですが、(大人の事情)で使うために、(大人の事情)に提供したところ、(大人の事情)されてしまいました。そのため、完全なデータは残っていません。

 (大人の事情)に抵触する情報は公開できませんが、Web上で調べれば見つけられる情報をまとめる程度なら大丈夫だと思います。

 今日のところは、生存確認の報告といったところで…