にゃみかんてっくろぐ

猫か百合を見守る壁になりたい

紅葉スポットと紅葉状況をツイートから推定する

ひとり開発 Advent Calendar 2019 10日目の記事です。

成果物: ソーシャル紅葉見頃情報

Webサービスソーシャル紅葉見頃情報」を作りました。

f:id:no_clock:20191209230023p:plain

動機: 紅葉情報サイトの「見頃」表示が信用できない

以下の写真は、複数の紅葉情報サイトで「紅葉状況:見頃」だった時の御岳昇仙峡(山梨県)の様子です。

f:id:no_clock:20191209230525j:plain

正直、見頃はまだ先だと感じました。Twitterを調べても同様の感想を持った方が多いようで、甲府市観光課も「全体的に3分〜4分付き」と表現されている状況でした。

せっかく紅葉を見に行くなら、見頃のピークに行きたいものです。

しかし、紅葉情報サイトの「見頃」は判定が緩いようで使えません。Twitterで流れているツイートのほうが、はるかに信用できそうです……… ということは、ツイートを活用すれば、より厳しく「見頃」を判断出来る可能性がありそうです。

作ることにしました。

解説: サービス構成

サービスの全体像は以下の通り。ぜんぶ書き慣れている Ruby で楽しく書きました。

f:id:no_clock:20191208204338p:plain

それぞれ順を追って説明していきます。

ツイート収集

「紅葉」「見頃」「色づき」などのキーワードで、紅葉状況と思わしきツイートをひたすらに収集します。

紅葉スポットの自動抽出

紅葉スポットは、それこそ ウォーカープラスの紅葉情報ウェザーニュースの紅葉Ch. から集める方法もありそうですが、依存したくないので ツイートから紅葉スポット名も抽出 します。

形態素解析: MeCab + mecab-ipadic-NEologd

ツイートを形態素解析エンジン MeCab に掛けて 固有名詞 を拾います。辞書には、最新の固有表現が多数採録されている mecab-ipadic-NEologd を用います。例えば、福島県会津地方にある景勝地塔のへつり」も正しく抽出できます。

# 標準の辞書 (mecab-ipadic)
$ echo "福島県南会津郡下郷町、塔のへつり。" | mecab -d /usr/local/lib/mecab/dic/ipadic/
福島  名詞,固有名詞,地域,一般,*,*,福島,フクシマ,フクシマ
県  名詞,接尾,地域,*,*,*,県,ケン,ケン
南会津  名詞,固有名詞,地域,一般,*,*,南会津,ミナミアイヅ,ミナミアイズ
郡  名詞,接尾,地域,*,*,*,郡,グン,グン
下郷  名詞,固有名詞,地域,一般,*,*,下郷,シモゴウ,シモゴー
町  名詞,接尾,地域,*,*,*,町,マチ,マチ
、  記号,読点,*,*,*,*,、,、,、
塔の  名詞,固有名詞,地域,一般,*,*,塔の,トウノ,トーノ
へ  助詞,格助詞,一般,*,*,*,へ,ヘ,エ
つり  名詞,一般,*,*,*,*,つり,ツリ,ツリ
。  記号,句点,*,*,*,*,。,。,。
EOS
# 今回使用する辞書 (mecab-ipadic-NEologd)
$ echo "福島県南会津郡下郷町、塔のへつり。" | mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/
福島県  名詞,固有名詞,地域,一般,*,*,福島県,フクシマケン,フクシマケン
南会津  名詞,固有名詞,地域,一般,*,*,南会津,ミナミアイヅ,ミナミアイズ
郡  名詞,接尾,地域,*,*,*,郡,グン,グン
下郷町  名詞,固有名詞,地域,一般,*,*,下郷町,シモゴウマチ,シモゴーマチ
、  記号,読点,*,*,*,*,、,、,、
塔のへつり  名詞,固有名詞,一般,*,*,*,塔のへつり,トウノヘツリ,トーノエツリ
。  記号,句点,*,*,*,*,。,。,。
EOS

ここから固有名詞を拾って、「福島県」「南会津」「下郷町」「塔のへつり」が紅葉スポットの候補となります。

都道府県推定

紅葉スポットの候補に対し、都道府県を推定します。

方法はシンプルで、『京都の南禅寺』のように都道府県名が一緒になっているものを拾い上げ、その最頻値を推定結果としているだけです。ただし、「高尾山口」が「山口」になったり「東京都」が「京都」になったりしないよう、一部正規表現で避けています。

ノイズ除去

紅葉スポットの候補から、ノイズと思われる名称を除外します。

  • 都道府県の推定が分散しすぎている場合
    • 例えば「植物園」は全国にあり、特定のスポットを指していないので除外したい
  • 半角文字を含むか、漢字が1文字も含まれない場合
    • 「1日」「エモい」なども固有名詞として候補に挙がっているため除外したい

紅葉状況の推定

ここまでで紅葉スポットの候補が定まったため、紅葉状況を推定します。

スコア算出

ツイートに含まれる「紅葉状況っぽいキーワード」を抽出し、 0(青葉)〜1(見頃)〜2(落葉) の間で数値化します。

正直ここはかなりゴリ押しです。たとえば 「早かった」は0.4、「もう少し」は0.7、「ちょうど」は1、 のようにで数値を設定しています。複数あれば平均を取ります。

Webサービス

これで紅葉スポット・紅葉状況の情報が揃ったため、Webサービスとして提供します。息を吸うようにフロントエンドを書ける人間ではないので、古き良き非SPAでの実装です。

非紅葉スポットフィルタ(雑)

ノイズ除去をしても紅葉スポット「でない」固有名詞が大量に残るため、ここでフィルタします。ひたすらキーワードでフィルタを掛ける一時しのぎで、改善の余地が残る部分です。

place !~ /^(.+観光客|外国人.+|最盛期|今日この頃|.+気温|何度|四季桜|可能性|寒い朝|世界遺産|誕生日|今シーズン|黄緑|[0-9]+|皇室献上|.+観光|お久しぶり|開催中|全国的|敷地内|温暖化|五平餅|お勧め|青紅葉|.+|.+|.+流星群|.+|.+旅行|暑さ|.+|桜の木|桜を見る会|ロケ地|.+公開|女子力|仙山線|お題|お姉ちゃん|外国人|私たち|朝活|好きだ|平野部|数年|異常気象|トロッコ列車|知らんけど|山手線|予防接種|午前中|募集中|.週間|観光.+|冬桜|落葉高木|今月末|.+市内|目的地|質問箱|.+|.+年前|リア充|.|分からん|.+希望|オフ会|聖地巡礼|子どもたち|大嘗宮|代表者|落羽松|つけ麺|定点観測|入場料|競馬場|.|.|.?週末|冷たい雨||お客さん|時間帯|)$/

検証: 紅葉状況の推定結果

約3週間動かしたので、推定結果を見ておきます。と言っても、Twitterのツイート群からの推定結果とツイートを比べるので出来レースです。

高尾山

f:id:no_clock:20191208212934p:plain

東京 高尾山の推定結果ですが、11/27頃から見頃に近く、12/7頃に見頃を過ぎようとしているようです。高尾ビジターセンターのTwitterアカウントと比べてみます。

11/16 見頃間近

11/24 見頃

12/1 見頃

12/6 落葉進む

推定結果「11/27頃から見頃に近く、12/7頃に見頃を過ぎ」は実際の様子とかなり近そうです。

東福寺

f:id:no_clock:20191208212922p:plain

京都 東福寺は、11/23〜11/30頃で見頃間近〜見頃を行ったり来たりしています。12/1以降は見頃過ぎのようです。公式Twitterアカウントがないため、ユーザのツイートと比べてみます。

11/16 見頃間近

11/23 見頃

11/27 見頃

12/1 落葉始まり

12/7 ほぼ終わり

推定結果「11/23〜11/30頃で見頃間近〜見頃」と期間的には合致しました。スコアがもう少し安定していれば、良い結果と言えそうです。

課題

概ね出来上がりましたが、まだまだ課題は多いです。

  • サンプル数の不足。マイナーな紅葉スポットではほとんど推定出来ない
  • 紅葉スポットのノイズ。紅葉スポット以外が大量に含まれている
  • 紅葉以外への対応。春までに桜の開花状況に対応したい

まとめ

  • 紅葉スポットと紅葉状況を推定するWebサービスを開発した
  • 有名所の推定精度はそれなりにありそうだった
  • 精度向上や桜への対応なんかは今後の課題

ソースコードGitHubに公開しています。