2010年9月 のアーカイブ

第7回データマイニング+WEB勉強会@東京で発表してきた

2010年9月27日 月曜日

こんにちは。2010/09/26(日)、第7回データマイニング+WEB勉強会@東京に参加してきました。

この勉強会の特徴について

双方向の議論が多く、参加者の多くの方が発言するのが大きな特徴です。またIT系以外の方が参加される異業種交流ができる貴重な勉強回の一つです。内容については「理論〜詳細な実装〜実務」と幅広いものとなってます。
開始時の自己紹介、終了時の振り返り、で少なくとも全員2回ずつ発言する必要がありますw
今回も会場を提供してくださったニフティ・エンジニアサポート様に感謝!また、次回の勉強会は11/14(日)開催予定です。

今回は発表しました

以下発表資料です。

はじめてでもわかるベイズ分類器 -基礎からMahout実装まで-


機会学習も統計も素人ですが、素人なりに勉強した結果と、MahoutというHadoop(またはElastic MapReduce)上で動作する分類器の使い方を解説しています。ベイズ分類器の学習・評価データにはWikipediaのデータを利用してます。

参加者をまとめたホワイトボード

恒例の参加者一覧です。

プレゼン内で紹介した本とRubyのサンプルコード

「この本持っている人います?」の質問に7割近くの人が手を挙げたのが印象的でした。この「集合知プログラミング」の6章では、Pythonによるナイーブベイズ分類器の実装を解説していますが、それを私が使い慣れているRubyで実装してみました。

集合知プログラミング

まず使い方から

# 分類器生成
n = NaiveBayes.new
# 学習
n.train('Nobody owns the water.','good')
n.train('the quick rabbit jumps fences','good')
n.train('buy pharmaceuticals now','bad')
n.train('make quick money at the online casino','bad')
n.train('the quick brown fox jumps','good')
# 推定
puts n.classify("quick rabbit",default="unknown")
puts n.classify("quick money",default="unknown")
# 閾値を与える
n.setthreshold("bad",3.0)
# 推定
puts n.classify("quick money",default="unknown")

分類器のコード

# 特徴抽出クラス
class GetWordFeature
  def get_feature(doc)
    words = doc.split(' ')
    words.map{|w| w.downcase}.select{|w| w.length < 20 && w.length > 2 }.uniq
  end
end
 
# 分類器の基底クラス
class Classifier
  def initialize(f)
    @fc,@cc,@feature = {},{},f
  end
 
  def incf(f,cat)
    @fc[f] ||= {}
    @fc[f][cat] ||= 0.0
    @fc[f][cat] = @fc[f][cat] + 1.0
  end
 
  def incc(cat)
    @cc[cat] ||= 0.0
    @cc[cat] = @cc[cat] + 1.0
  end
 
  def fcount(f,cat)
    @fc[f] ||= {}
    @fc[f][cat] ||= 0.0
    @fc[f][cat]
  end
 
  def catcount(cat)
    @cc[cat] ? @cc[cat].to_f : 0.0
  end
 
  def totalcount
    sum = 0
    @cc.each_value {|value| sum += value}
    return sum
  end
 
  def categories
    @cc.keys
  end
 
  # 条件付き確率 Pr(A|B)
  def fprob(f,cat)
    return 0 if catcount(cat) == 0 || fcount(f,cat) == nil
    fcount(f,cat) / catcount(cat)
  end
 
  # 重み付き確率
  def weightedprob(f, cat, weight=1.0, ap=0.5)
    # 通常の条件付き確率
    basicprob = fprob(f,cat)
    # この特徴がすべてのカテゴリ中に存在する確率
    totals = 0
    categories.each do |c|
      totals = totals + fcount(f,c) if fcount(f,c)
    end
    # 重み付けした平均計算
    ((weight*ap)+(totals*basicprob)) / (weight+totals)
  end
 
  def train(item, cat)
    features =  @feature.get_feature(item);
    features.each do |f|
      incf(f, cat)
    end
    incc(cat)
  end
end
 
# 単純ベイズ分類器
class NaiveBayes < Classifier
  def initialize
    super(GetWordFeature.new)
    @thresholds = {}
  end
 
  # P(B|A):アイテム全体の与えられたカテゴリでの確率を求める(掛け合わせる)
  def docprob(item,cat)
    features = @feature.get_feature(item)
    p = 1.0
    features.each do |f|
      ep = weightedprob(f,cat)
      p = p * ep
    end
    return p
  end
 
  def prob(item,cat)
    catprob = catcount(cat) / totalcount
    docprob = docprob(item,cat)
    return docprob * catprob
  end
 
  def setthreshold(cat,t)
    @thresholds[cat] = t
  end
 
  def getthreshold(cat)
    @thresholds[cat] || 1.0
  end
 
  def classify(item, default=nil)
    probs,max,best = {},0.0,nil
    categories.each do |c|
      probs[c] = prob(item,c)
      if probs[c] > max
        max = probs[c]
        best = c
      end
    end
    probs.each_key do |c|
      # (2番目に確率の高いもの * 閾値)と比較
      second = probs[c].to_f * getthreshold(best)
      return default if second > probs[best]
    end
    return best
  end
end

以上です!

ブログにmixiチェックボタンを設置してみた

2010年9月10日 金曜日

こんにちは。

mixiチェックボタン、本当に簡単に設置できました!
さきほど「mixi meetup 2010」にて発表があったmixiチェックボタンをさっそくブログのに貼り付けてみました。
個人ブログに簡単に導入するための便利プラグインがmixiエンジニアblogにて提供されていたのでそれを使いました。

このページに貼り付けてもあまり意味はないのだが、商品ページやニュース記事ページなど、集客を目的とするページでの設置であれば、それなりの効果があるのかもしれない。ただし、以下の意見もある。

これまでも日記に「いいね!」ボタンをつけることができたんだけど、「チェック」はニュースやmixiコレクションの中で興味のあるものに対して「チェック」できるという。まあ災害のニュースに「いいね!」ボタンはつけられないしね。「いいね!」より広い領域の事象に対する興味、関心を、友人、知人と共有するというコミュニケーションの形を提案しているわけだ。 「mixiチェック」正式発表【湯川】

Facebookの「いいね!」ボタンと「mixiチェック」ボタンの違いの一つとして、ネガティブなコンテンツやコメント付加に対応できるにあると湯川さんはおっしゃってるんですね。

ただし、楽天やYahooも、mixi対応するようなので、注目です。

RubyWorld Conference 2010に参加してきた

2010年9月7日 火曜日

こんばんは。

昨日から二日間(2010年9月6日~2010年9月7日)、「RubyWorld Conference 2010」に参加してきました。

http://www.rubyworld-conf.org/

( Twitterハッシュタグ: #RWC2010 )

参加者の他県率は8割くらい(レセプション時の感覚)で、スーツ率はなんと9割くらいでした。参加者は、6日 415名、7日 693名とのことです。

発表内容からメモした言葉をちょっとだけ紹介し、後は写真をアップして寝ることにします。

基調講演:まつもとゆきひろ氏(@yukihiro_matz)『持続可能なRuby』

1993 ruby開発開始 ユーザまつもとさん1人

1995 ruby公開

2009 Rubyユーザ100万人(ガートナ調査結果)

2013 Rubyユーザ400万人(ガートナー予想)

すごいユーザ数の推移ですね。400万人予想はRails全盛期の予想らしく実際にはそこまでいかないらしいけど。

角谷信太郎氏(@kakutani)『ふつうのシステム開発~Rubyを活用した受託開発をアジャイルにするためのパターンの紹介』

「時を超えた建設の道: クリストファー アレグザンダー著」からの言葉

生きている花をつくろうとすれば、ピンセットで細胞を一つ一つ物理的に組み立てるのではなく種から育てるのであろう。

これは、ささりました。

何か事を成すときの考え方として、どんなケースでも当てはまる言葉ですよね。

そしてきっと誰でも思い当たる事があるでしょう。

Stevie Clifton氏(Animoto Productions)『How Ruby Enables Startup Success』

Stevie氏はANIMOTO(http://animoto.com/)という動画サービスのCTO。こういうサクセスストーリーを聞くのは楽しいです。とてつもない苦労をされてるんだろうけど、それにも増してサービスの提供を楽しんでいることが言葉の壁を超えて伝わってくる。クローゼット内のサーバで始めたサービス→EC2で30インスタンス規模まで拡大。Facebookアプリによって30台から3,000台までスケールアウト。そしてアーキテクチャの再構成。すべてのフェーズにてRubyとその周辺のプロダクトを採用したとのことです。

まさに海外でのRuby&Railsの成功例ですね。そしてANIMOTOのデモすげーかっこよかった。

-

全て1日目のレポートになってしまいましたが。2日目も楽天・三木谷社長の講演など内容は濃かったですよ。

-

以下写真。

会場:島根県立産業交流会館「くにびきメッセ」

-

ノベルティのエコ箸と、売店で売ってるRuby on 松江ラーメン(2食分)

ラーメンの箱の上部に書いてあるのはMatzのサインだろうか…。

-

Aホール:まつもとさん講演中

-

1日目昼食お弁当:ボリュームたっぷり

-

B会場

-

1日目:多目的ホール。夜のレセプションの開始直前

-

2日目昼食お弁当

-

なんか食べ物の写真ばかりで申し訳ない(汗)

以上です。何を言いたいかというと、来年も参加したいなーということです。