LoginSignup
14
14

More than 5 years have passed since last update.

多数のフィードを扱う上でのあれこれ

Last updated at Posted at 2014-10-15

昨日は巷で人気の機械学習を利用し、テキストデータの中から興味関心にそった内容をピックアップするという話をしました。

RSS/Atom フィードは、外部から出力されるものですから、実際問題としては提供元によってかなりブレがあります。予想もしていない文字列やバイトコードが混入していることもまれではありません。

こういった問題はひとつひとつ手作業で対処していくしかないのですが、現実にはなかなか泥臭いことになることが結構あります。

今回は経験則的に得られた Tips を載せていきます。

ストップワードを除去する

たとえば新聞社のフィードを購読すると、タイトルのほとんどに「日経」などの新聞社名や「新聞」といった文字、要約フィードから本文へのリンクとなる「全文」、掲載された「写真」といった文字が入ってきます。

こういった語句を分類に利用してしまうと、精度の低下やノイズの発生につながってしまいます。

しかもどの文字を除去したからそれで良いという正解があるわけではなくて、たとえばある月からニュースのタイトルのフォーマットが変わったということがあると、すぐに対応しないとそれまでの間に出力結果がおかしなことになってしまいます。

ストップワードはあらかじめテキストファイルやデータベース、インメモリといった場所に格納しておいて、管理者がすぐに更新できるようにしておく必要があります。

def exclude_words
  words = Array.new
  open(@exclude_txt) do |file|
    file.each_line do |line|
      words << line.force_encoding("utf-8").chomp
    end
  end
  return words
end

上のようにストップワードの語彙群を返すメソッドを用意しておきます。実際の処理でこの配列と付き合わせて語彙を処理対象外にするわけです。

リダイレクトリンクを書き換える

フィードの中には link のアドレスがリダイレクトする前提になっているものもあります。たとえば Google News がそうですし、記事そのものでなくはてなブックマークのコメント欄が格納されているもの、それ以外にも短縮 URL を利用しているものなど色々なケースが考えられます。スクレイピングと組み合わせている場合、ひどいケースではフィードの link にアドレス自体がきれいにおさまってない状態で流れてくるといった場合もあります。

これらについても収集しているフィードをよく吟味して、ひとつひとつ自分の望んだ形式に書き換えるようにしていく必要があります。

たとえば Google News の場合はこんな感じで良いでしょう。

def rewrite_google_link(feed)
  if feed.link.index("http://news.google.com")
    matched = feed.link.match(/(&url=)/)
    unless matched.nil?
      new_link = matched.post_match # &url= から後ろだけを持ってくる
      feed.link = new_link unless new_link.nil?
    end
  end
  return feed
end

処理結果をロギングする

前述したように、日々フィードを収集するプロセスの動きを監視して、なにか変化があった場合はすぐに対応をしなければなりません。そのためには一連の流れをロギングし、必要に応じてメッセージや途中経過を出力しておくことが大切です。

Ruby にそなわっている標準の Logger は、レベルに応じたログの出力はもちろん、ログファイルのローテーションなどもできるスグレモノです。これを利用して日々ロギングし、定期的に処理の経緯をチェックすると良いでしょう。

puts メソッドを書き換えてしまうのもひとつの手です。

require 'logger'
LOG_LEVELS = ['info', 'warn', 'error', 'none']

def level(level)
  @level = level
end

def logger
  @logger ||= Logger.new(STDOUT)
end

def puts(level=:info, message)
  if LOG_LEVELS.index(@level).to_i > LOG_LEVELS.index(level).to_i
    return
  end
  logger.send(level, message)
end

こうしておけば puts メソッドで、外部から与えたレベル以上のメッセージを Logger を利用して出力することができます。

まとめ

紹介した以外にもたくさんのノウハウがあります。どのみち分類の精度は日々チューニングをしていくことになりますので、あわせてフィードが適切に処理されているかという観点で見ていけば良いでしょう。大切なのは継続的に処理の流れをチェックし、日々改善していくという姿勢です。

14
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14