読者です 読者をやめる 読者になる 読者になる

Abnormalに生きる

化学の研究者→消防士→ITエンジニア(2016年11月〜)

はてなブックマークから特徴語を抽出し、ユーザーの興味・関心を分析する。

Ruby スクレイピング データサイエンス 自然言語処理

 以前、文章から特徴語の抽出や特徴ベクトルを生成するモジュールを作りました。

hirotsuru.hatenablog.com

 今回は、これを使って個人のはてなブックマークから特徴語を抽出し、興味・関心を分析できるのかやってみたいと思います。

 はてなブックマークについては、はてなブログを閲覧されている方々には、説明の必要がないかも知れませんが、オンライン上にブックマークを無料で保存できるソーシャルブックマークサービスです。下の画像は私のはてなブックマークのページです。

f:id:hirotsuru314:20160805173705p:plain

 ユーザーは興味がある記事にしかブックマークをしないので、個人のブックマークを解析することで、その人が興味を持っていることを知ることができるんじゃないかと思いました。もし、個人の興味・関心を知ることができれば、一人一人にパーソナライズされたサービスの提供に繋げられるので、非常に有用ではないかと思います。

目次

つくったもの

 コードは以下のリンクから見れます。

github.com

やったことの流れとしては、以下のような感じです。

1.ユーザーがブックマークした記事をRSSから読み込み、取得

2.ブックマークのタイトルを取り出す。(全タイトルをつなげて、一つの文章のように扱う)

3.Mecabで単語分割(名詞のみを抽出)

4.各単語のTF-IDFを算出し、特徴語を抽出

実際に使ってみる

 実際に私のブックマークを使って、分析の結果をお見せします。コマンドラインからプログラムを実行すると、

$ ruby Sample.rb
はてなIDを入力してください。

まず、はてなIDを聞かれますので、入力します。ここで、注意が必要なのが、はてなの「ニックネーム」じゃなく「はてなID」の方です。

f:id:hirotsuru314:20160805171030p:plain

はてなIDを入力すると、以下のような結果が返ってきます。(関心度が高いものから、ランキング形式で5つの特徴語を抽出しています。)

$ ruby Sample.rb
はてなIDを入力してください。hirotsuru314
1:機械学習
2:Ruby
3:Ruby on Rails
4:コード
5:初心者

 私は、「Ruby」や「Rails」、「機械学習」を勉強し、「コード」を書いているプログラミングの「初心者」ですので、かなり私のことをパーソナライズしています。笑

 この結果から、個人のブックマークを使うと、興味関心をパーソナライズできそうです!

技術メモ

RSSフィードから情報を取得する

 RubyRSSフィードを解析し、何かしらの情報を取得するためには、標準ライブラリの「rss」が有効です。Rubyにはnokogiriという非常に優れたスクレイピングのためのライブラリがありますが、情報の取得先がRSSだけであれば、nokogiriを使わずに標準ライブラリで十分です。

library rss (Ruby 2.2.0)

ユーザーのはてなブックマークRSSのURLは以下のようになります。

http://b.hatena.ne.jp/はてなID/rss

ちなみに、ユーザーのはてなブックマークRSSは最新の20件のみしか表示されません。全件を取得するためには、APIを叩けばできますが、 oauth認証が必要であったり、少し面倒なので今回はやりません。

def get_rss
  url = "http://b.hatena.ne.jp/#{$hatena_id}/rss"
  opt = {}
  opt['User-Agent'] = 'Opera/9.80 (Windows NT 5.1; U; ja) Presto/2.7.62 Version/11.01'
  @rss = open(url, opt) do |file|
    RSS::Parser.parse(file.read)
  end
end

上のコードでUser-Agentの部分は、以下の記事を参考にしています。

はてなブックマークの RSS を Ruby で取得していたのですが、こ… - 人力検索はてな

専門用語の対応はmecab-ipadic-NEologd

 以前の記事にも書きましたが、mecab-ipadic-NEologdという非常に優れた辞書があります。

hirotsuru.hatenablog.com

 IT関連の専門用語はこれを導入すれば十分に対応できます。逆にこれを使わないと、「機械学習」が「機械」と「学習」に分けられてしまったりして、うまく特徴語が抽出できません。

 mecab-ipadic-NEologdを使った単語分割のコードは以下のような感じです。ここで、@bookmark_titlesにRSSから取得した20件のブックマークのタイトルをつなげた文章が入っています。

 #Mecabによる形態素解析
  def split_words
    @arr = Array.new
    nm = Natto::MeCab.new('-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
    nm.parse(@bookmark_titles) do |n|
      surface = n.surface
      feature = n.feature.split(',')
      #名詞のみを抽出する
      if feature.first == '名詞' && feature.last != '*'
        @arr.push(surface) #テキストを単語分割して配列で返す
      end
    end
  end



TF-IDFによる特徴語抽出

 Mecabによる単語分割までできれば、あとはブックマークのタイトルに登場する単語をカウントして、それぞれの単語のTF-IDFを算出します。

  def calculate_tf
    @tf = Hash.new
    @arr.each do |word|
      if(@tf.key?(word))
        @tf[word] += 1
      else
        @tf[word] = 1
      end
    end
    @tf.each do |key, value|
      @tf[key] = value.to_f/@tf.size
    end
  end

  def calculate_tfidf
    @tfidf = Hash.new
    @tf.each do |key, value|
      if $idf.has_key?(key)
        @tfidf[key] = ($idf[key] * value).round(3)
      end
    end
  end

TF-IDFを算出した後に、その値が大きいものから5つを特徴語として取り出しました。

さいごに

 今回、はてなブックマークからの特徴語抽出をやってみて、一人一人の興味・関心をパーソナライズする一つのアプローチとして、ブックマークを使うのは有効だと思いました。今後は、これをもとにユーザごとにパーソナライズされたサービスを提供するようなWebアプリケーションを作ってみたいと思っています。