NLP(自然言語処理)研究者をスコアリングしてみた
IR研究者をスコアリングしてみた - 睡眠不足?!
http://d.hatena.ne.jp/sleepy_yoshi/20090215/p1
この記事を読んでNLP分野ではどうだろう、と思ったのでやってみました。
対象とした会議は2001年~2008年のACLとEMNLPです(年によっては他会議との併設含む)。
cf. DO++: 自然言語処理の学会 http://hillbig.cocolog-nifty.com/do/2008/04/post_fe44.html
ACL anthologyから以下のページを利用してデータを取得
ACL: http://www.aclweb.org/anthology-new/P/P08/ (2008年の場合。08の部分を変えれば他の年が見られる)
EMNLP: http://www.aclweb.org/anthology-new/sigdat.html
評価方法
冒頭のIR研究者のスコアリングの場合と同様で、登場回数と著者順位による重みづけによる二つの方法を用いました。
「登場回数は名前が出れば1回とカウント」、「著者順位重みづけは1st authorの重要度をそれ以外の著者よりも重くしてスコアづけ」(複数人の著者がいる場合は1st authorを0.8として、残りの0.2を他の著者に分配、1人の場合は1とする)です。
また、Short PaperやPoster, Workshopなどは対象外としました。
コード
書いたコードは下の通り。名前の表記揺れがいくつかあったので「大文字」+.(ピリオド)は除去してカウントしたりして(例: "Christopher D. Manning" => "Christopher Manning")、最後に手作業で補完しました。
$KCODE = 'u' require 'rubygems' require 'nokogiri' require 'open-uri' #ACLの論文著者名を取得 def acl_authours authors = [] (1 .. 8).each do |y| doc = Nokogiri::HTML(open("http://www.aclweb.org/anthology-new/P/P0#{y}/")) (doc/'p').each do |i| num = (i/'a').first.inner_text.scan(/\d{4}$/).to_s.to_i if num > 1000 && num < 2000 next if (i/'b').inner_text.split(//).size < 1 authors << (i/'b').inner_text.gsub(/(\.)[^ ]/) {$1 + ' '}.gsub('’', "'").gsub(/\(.+?\) /, '').gsub(/ {2,}/, ' ').gsub(/[A-Z]\. /, '').split('; ') end end sleep 3 end authors end #EMNLPの論文著者名を取得 def emnlp_authors authors = [] doc = Nokogiri::HTML(open("http://www.aclweb.org/anthology-new/sigdat.html")) (doc/'li').each do |i| num = (i/'a').first.inner_text.scan(/(\d+)-/).to_s.to_i if num >= 1 && num <= 8 next if (i/'b').inner_text.split(//).size < 1 authors << (i/'b').inner_text.gsub(/([a-z]{2,}|\.)([A-Z])/) {$1 + ' ' + $2}.gsub('’', "'").gsub(/ {2,}/, ' ').gsub(/[A-Z]\. /, '').split('; ') end end authors end #フラットな配列を引数に取りカウント def count_authors(authors) cnt = Hash.new(0) authors.each do |i| cnt[i] += 1 end cnt.to_a.sort {|a, b| b[1] <=> a[1]} end #配列の配列を引数に取りスコアを分配 FIRST_AUTHOR_SCORE = 0.8 def devide_score(authors) score = Hash.new(0) authors.each do |i| if i.size == 1 score[i.shift] += 1 else score[i.shift] += FIRST_AUTHOR_SCORE rest_score = (1 - FIRST_AUTHOR_SCORE) / i.size i.size.times do |t| score[i.shift] += rest_score end end end score.to_a.sort {|a, b| b[1] <=> a[1]} end if __FILE__ == $0 p count_authors((acl_authours + emnlp_authors).flatten) p devide_score((acl_authours + emnlp_authors)) end
結果
登場回数順(10回以上)
スコア順(有効数字4桁, 4.000以上)
最後に
URLは適当なものではない可能性があります。
Christopher D. Manning先生が書かれた教科書は輪講などでも広く使われています。
http://nlp.stanford.edu/fsnlp/
Dan Klein先生の担当されている授業の資料などは誰でも見ることができます。
http://www.cs.berkeley.edu/~klein/cs288/sp09/
がんばります。