こんにちは、VOYAGE GROUP システム本部のゆうです。
去年の6月に配属してから統計を勉強し始めて、現在はECナビやリサーチパネルに関する予測分析などをしています。
今回作成する共起語ネットワークグラフとはテキストマイニングの手法のひとつです。単語をグラフの点、単語間のつながりをグラフの辺で表し、点が大きいとその単語の出現頻度が多い(よく使われる単語)だったり、辺が短いと文書中の近いところで出現(単語間の関連が強い)しているなどが表現できます。
実務でもサービスのアンケートのようなテキストからポジティブ・ネガティブワード分析などで利用しています。これを使えばこのVGエンジニアブログ全体の特徴を表現できそうです。
まずはwget でエンジニアブログの記事をダウンロード
-r 同一ドメイン
-l 指定URLからの深さ
-w 待ち時間(秒)
-A ダウンロードするフォーマット。カンマ区切りで複数指定。(Accept) ちなみに -R でダウンロードしたくないフォーマット(Reject)も指定できます。
ダウンロードしたファイルを確認すると、archievesフォルダ以下にcat_XXX.html(カテゴリ別にまとまったページ)と20XX_XX.html(年月別)、XXXX.html(1記事づつ。ちょうど全記事数分のファイルだったので記事IDなのでしょうか?)というページが取得できました。今回は記事ずつのファイルだと扱いやすいのでそれ以外は別フォルダに移動しました。
記事の本文のみを抽出
ダウンロードしたいくつかのHTMLファイルを開いてみて、本文に対応する箇所は article-body-inner というタグが現れ、その後2行目に本文全てが1行で書かれていることがわかりました。grepします。
htmlタグを取り除く
ruby で動くsanitizeというライブラリがあったのでそれを利用します。コマンドラインから利用したら便利かなと思いコマンドライン引数を受け取るように書いてみました。
テキストを渡すと文字コード変換や形態素解析などの前処理に加えて、クラスタリングや対応分析をしてくれる便利なフリーツール。プログラミング不要です。
さきほどrubyでサニタイズしましたが前処理の結果を見ると、htmlやcssの属性に該当する単語が含まれていたのでこれらを分析で抽出する単語から除外します(※1)。 頻度の高いものを調べ除外したい単語があれば記述しておきます。

KHCoderの画面です。グラフに出す必要の無い単語を無視するように設定します。
結果

プログラミング言語ではRuby、Perlという単語を含む記事が多そうです。
共起している単語からなんとなく記事の内容が予想できそうです。(※2)
やってみて
※1 でPerlという単語で記事検索してみると、弊社一番の人気記事への紹介リンクや「 Perlで書いてるけど今回は…」という記事があったのでPerlに関する投稿では無いものもありました。ブログ記事にはRに関する記事も多くあるのですが、もしかしたら形態素解析したときにRは単語として認識されてなかったのかもしれないです。
(KHCoderで除外するのと同様に強制的に単語として抽出する設定もできます。)
さらに※2 でhtmlやcssと関係する単語を除外しましたが、もしHTML5/CSS3に関する記事あってもこのグラフに現れないです。データの準備段階から改善する必要がありそうです。
今回、グラフの出力以前の準備の作業(前処理とかクレンジングとか言ったりします)がほとんどの作業を占めてました。実は上のグラフも一発で出したものではなく、何度かデータを整形しなおしています。
僕自身の実際の業務でも分析以前にデータをかき集めたり、有効なデータがそもそもあるのかどうか、分析できるだけの効果があるものなのか調査することが、作業全体のほとんどを占めていたりします。ARPUやLTVなどの指標を計算するまでいくつもステップがあったりで計算ミスなどあったりしたら影響範囲がとても広いです。そのため結果が出るまでもどかしかったり、不安なときもあります。精神的にツライときも。。しかし何よりもうまくいったときの達成感は大きいです。
これから
定期的に記事を投稿したいです。そのためにも常に学んで文章をおこす癖を身につけていきます。
そしてもちろん面白い記事書きたいですね。
参考にした記事
wget http://ja.wikipedia.org/wiki/GNU_Wget
今回のオプション以外にも使えるものがありそうです。詳しくはコンソールで man wgetと叩いてみましょう。
ruby sanitize https://github.com/rgrove/sanitize
ruby on railsなどで使われているライブラリだそうです。gem で管理できるので今回使う時に便利でした。一緒にnokogiriだったりlibxml2などが必要なので詳しいインストール方法はnokogiriのインストール手順を見ると良いと思います。
KHCoder http://khc.sourceforge.net/index.html
今回の共起ネットワークグラフの他にクラスタリングや対応分析などのテキストマイニングができるフリーソフトウェア です。ソフトのインストール後に詳細なマニュアルが付属していたり、グラフの出力結果をRのコードとして出力できるのでさらに細かい分析もできそうです。
テキストマイニングの基礎 http://homepage2.nifty.com/nandemoarchive/toukei_hosoku/TextAnalysis.htm
今回のグラフ作成に関連する共起語分析やテキストマイニングについて参考にさせていただきました。統計の知識全般についてはこのページのトップである「統計学の補足」もわかりやすいまとめになっています。
去年の6月に配属してから統計を勉強し始めて、現在はECナビやリサーチパネルに関する予測分析などをしています。
今回作成する共起語ネットワークグラフとはテキストマイニングの手法のひとつです。単語をグラフの点、単語間のつながりをグラフの辺で表し、点が大きいとその単語の出現頻度が多い(よく使われる単語)だったり、辺が短いと文書中の近いところで出現(単語間の関連が強い)しているなどが表現できます。
実務でもサービスのアンケートのようなテキストからポジティブ・ネガティブワード分析などで利用しています。これを使えばこのVGエンジニアブログ全体の特徴を表現できそうです。
まずはwget でエンジニアブログの記事をダウンロード
$ wget -l 3 -w 3 -Ahtml,htm -r http://tech.voyagegroup.comオプションの意味は
-r 同一ドメイン
-l 指定URLからの深さ
-w 待ち時間(秒)
-A ダウンロードするフォーマット。カンマ区切りで複数指定。(Accept) ちなみに -R でダウンロードしたくないフォーマット(Reject)も指定できます。
ダウンロードしたファイルを確認すると、archievesフォルダ以下にcat_XXX.html(カテゴリ別にまとまったページ)と20XX_XX.html(年月別)、XXXX.html(1記事づつ。ちょうど全記事数分のファイルだったので記事IDなのでしょうか?)というページが取得できました。今回は記事ずつのファイルだと扱いやすいのでそれ以外は別フォルダに移動しました。
記事の本文のみを抽出
ダウンロードしたいくつかのHTMLファイルを開いてみて、本文に対応する箇所は article-body-inner というタグが現れ、その後2行目に本文全てが1行で書かれていることがわかりました。grepします。
$ grep -A 3 article-body-inner *html > grep.result-A で 該当する行の後三行目まで出力するオプションです。余計な行はviのマクロを使って削除しました。ひとまずこれで1行1記事のテキストができあがりました。
htmlタグを取り除く
ruby で動くsanitizeというライブラリがあったのでそれを利用します。コマンドラインから利用したら便利かなと思いコマンドライン引数を受け取るように書いてみました。
# sanitize_text.rbKHcoderで共起ネットワーク図を作成
require "rubygems"
require "sanitize"
puts Sanitize.clean(open("#{ARGV[0]}","r").read)
-------------------------
# コマンドライン上
$ ruby sanitize_text.rb grep.result >output.txt
テキストを渡すと文字コード変換や形態素解析などの前処理に加えて、クラスタリングや対応分析をしてくれる便利なフリーツール。プログラミング不要です。
さきほどrubyでサニタイズしましたが前処理の結果を見ると、htmlやcssの属性に該当する単語が含まれていたのでこれらを分析で抽出する単語から除外します(※1)。 頻度の高いものを調べ除外したい単語があれば記述しておきます。

KHCoderの画面です。グラフに出す必要の無い単語を無視するように設定します。
結果

プログラミング言語ではRuby、Perlという単語を含む記事が多そうです。
共起している単語からなんとなく記事の内容が予想できそうです。(※2)
やってみて
※1 でPerlという単語で記事検索してみると、弊社一番の人気記事への紹介リンクや「 Perlで書いてるけど今回は…」という記事があったのでPerlに関する投稿では無いものもありました。ブログ記事にはRに関する記事も多くあるのですが、もしかしたら形態素解析したときにRは単語として認識されてなかったのかもしれないです。
(KHCoderで除外するのと同様に強制的に単語として抽出する設定もできます。)
さらに※2 でhtmlやcssと関係する単語を除外しましたが、もしHTML5/CSS3に関する記事あってもこのグラフに現れないです。データの準備段階から改善する必要がありそうです。
今回、グラフの出力以前の準備の作業(前処理とかクレンジングとか言ったりします)がほとんどの作業を占めてました。実は上のグラフも一発で出したものではなく、何度かデータを整形しなおしています。
僕自身の実際の業務でも分析以前にデータをかき集めたり、有効なデータがそもそもあるのかどうか、分析できるだけの効果があるものなのか調査することが、作業全体のほとんどを占めていたりします。ARPUやLTVなどの指標を計算するまでいくつもステップがあったりで計算ミスなどあったりしたら影響範囲がとても広いです。そのため結果が出るまでもどかしかったり、不安なときもあります。精神的にツライときも。。しかし何よりもうまくいったときの達成感は大きいです。
これから
定期的に記事を投稿したいです。そのためにも常に学んで文章をおこす癖を身につけていきます。
そしてもちろん面白い記事書きたいですね。
参考にした記事
wget http://ja.wikipedia.org/wiki/GNU_Wget
今回のオプション以外にも使えるものがありそうです。詳しくはコンソールで man wgetと叩いてみましょう。
ruby sanitize https://github.com/rgrove/sanitize
ruby on railsなどで使われているライブラリだそうです。gem で管理できるので今回使う時に便利でした。一緒にnokogiriだったりlibxml2などが必要なので詳しいインストール方法はnokogiriのインストール手順を見ると良いと思います。
KHCoder http://khc.sourceforge.net/index.html
今回の共起ネットワークグラフの他にクラスタリングや対応分析などのテキストマイニングができるフリーソフトウェア です。ソフトのインストール後に詳細なマニュアルが付属していたり、グラフの出力結果をRのコードとして出力できるのでさらに細かい分析もできそうです。
テキストマイニングの基礎 http://homepage2.nifty.com/nandemoarchive/toukei_hosoku/TextAnalysis.htm
今回のグラフ作成に関連する共起語分析やテキストマイニングについて参考にさせていただきました。統計の知識全般についてはこのページのトップである「統計学の補足」もわかりやすいまとめになっています。