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

指標を全部実装してみた

Ruby 自然言語処理

この前の続き。先週の水曜で大体作ってしまっていたんだが、使い方ミスっててバグってると勘違いしていたorz。

とりあえずpneの1985年分のテキストを食わせて、それぞれの指標で上位100個を出力させるとかそんな感じのプログラム。70ファイルくらいしかないですが、非常に遅いです。。。

今週の金曜には、これの評価をするプログラムを書いておきたい。次からは機械学習っぽいものを取り込んでいきたいんだけど、この指標を使ったやつをベースラインとしたいので、性能を知っておきたい。

プログラム

# -*- coding: utf-8 -*-
# implementation for this paper
# http://www.r.dl.itc.u-tokyo.ac.jp/~nakagawa/academic-res/jnlp10-1.pdf

require 'MeCab'
require 'yaml'
require 'pp'

class MeCabWrapper
  attr_reader :extraction
  def initialize(mecab)
    @mecab = mecab
    @extraction = []
  end
  
  def add_text(text)
    exclusive_list = [".", ",", "(", ")", ":", ";", "^", ").", "?"]
    n = @mecab.parseToNode(text) 
    prev_word = ""
    prev_pos = ""
    tmp = []
    while n do
      f = n.feature.split(/,/) 
      if (/名詞/ =~ f[0]) && !exclusive_list.include?(n.surface) # 名詞で、禁止リストの単語じゃないとき
        tmp.push n.surface
      else
        if prev_pos == "名詞"
          @extraction.push tmp # これまでが名詞のsequenceだったら、つっこむ
          tmp = []
        end
      end
      prev_word = n.surface
      prev_pos = f[0]
      n = n.next
    end 
    @extraction.delete([])
    filter
  end

  def filter
    #  PerlのTermExtract::MeCab語尾の余分な語の削除のところを参考に
    @extraction.delete_if{|e|
      ( ["など", "", "", "", "", "", "", "", ""].include?(e[-1]) ) || 
      ( [""].include?(e[0]) ) ||
      ( e.inject(true){|result, x| result && (x =~ /^\d+$/)} ) # 数字のみは除去
    }
    return @extraction
  end

end

class Term
  attr_reader :technical_word
  def initialize(technical_word)
    @technical_word = technical_word
    @simple_term = technical_word.flatten.uniq # 単名詞
  end
  
  def print(word)
    return "[#{t.stop_sharp_ldn(word).uniq.map{|i| "[" + i.join(", ") + "]"}.join(", ")}]"
  end

  def stop_sharp_ldn(word) # wordの左側のところを取ってこさせる
    result = []
    @technical_word.each{|array|
      tmp = []
      if array.index(word).nil?
        next
      elsif array.index(word) > 0
        array.each{|i|
          if word != i
            tmp.push i
          else
            tmp.push i
            break
          end
        }
        result.push tmp
      end
    }
    return result
  end

  def stop_sharp_rdn(word) # wordの右側のところを取ってこさせる
    result = []
    @technical_word.each{|array|
      tmp = []
      flag = false
      array.each{|i|
        if word == i
          flag = true
          tmp.push i
        elsif flag
          tmp.push i
        end
      }
      result.push tmp if !tmp.empty?
    }
    result.delete([word]) # 自身のみからなる配列は削除
    return result
  end

  def sharp_ldn(word) # #LDN(N)
    return stop_sharp_ldn(word).uniq.length
  end
  def sharp_rdn(word) # #RDN(N)
    return stop_sharp_rdn(word).uniq.length
  end

  def sharp_ln(word) # #LN(N)
    return stop_sharp_ldn(word).length
  end

  def sharp_rn(word) # #RN(N)
    return stop_sharp_rdn(word).length
  end

  def lr(words) # LR(CN)
    result = 1
    words.each{|word|
      result *= (sharp_ln(word) + 1) * (sharp_rn(word) + 1)
    }
    result = result ** (1.0 / (2 * words.length))
  end

  def flr(words) # FLR(CN)
    f_cn = 0
    @technical_word.each{|t|
      if words == t
        f_cn += 1
      end
    }
    return f_cn * lr(words)
  end
  
  def mc_value(words) # MC-value(CN)
    # 論文の例が間違っているような。。。
    # c(CN)のところの例
    n_cn = 0
    t_cn = 0
    c_cn_array = []
    @technical_word.each{|t|
      if !t.join()[words.join].nil?
        n_cn += 1
      end

      if words.inject(true){|result, word| result && t.include?(word)} && # CNを含む複合名詞
          t.length > words.length # その中でCNより長いもの
        t_cn += 1
        c_cn_array.push t
      end
    }
    return words.length * (n_cn - t_cn.to_f / (c_cn_array.uniq.length + 1.0))
  end

  def index(attention_word)
    index = {
      "#LRN" => sharp_ldn(attention_word.join()),
      "#RDN" => sharp_rdn(attention_word.join()),
      "#LN" => sharp_ln(attention_word.join()),
      "#RN" => sharp_rn(attention_word.join()),
      "LR" => lr(attention_word),
      "FLR" => flr(attention_word),
      "MC-value" => mc_value(attention_word)
    }
  end
end

mw = MeCabWrapper.new(MeCab::Tagger.new("-Ochasen"))

Dir.glob("/Users/syou6162/dbcls/pne/1985/*.txt").each{|file|
  puts file
  f = File.open(file)
  mw.add_text(f.read.chomp)
  f.close
}

t = Term.new(mw.extraction)
result = {}

mw.extraction.uniq.each{|i|
  puts "#{i.join()}"
  result[i.join()] = t.index(i)
}

table = []
["FLR", "#RDN", "#LN", "#RN", "LR", "FLR", "MC-value"].each{|index|
  tmp = []
  result.to_a.sort{|a,b|
    (b[1][index] <=> a[1][index] )
  }.map{|x,y|
    tmp.push x + "(#{y[index].to_i})"
  }
  table.push tmp
}

file = File.open("/tmp/result.txt","w")

table.transpose[0..100].each{|x|
  file.puts x.join(" ")
}
file.close

実行結果

計算待ちなう。。。→できた。それぞれの指標における上位100個とその指標を書いたやつを貼りつけてみる。

蛋白質(10632) 細胞(24) 細胞(87) 細胞(51) 蛋白質(107) 蛋白質(10632) 蛋白質(395)
細胞(2299) DNA(20) 作用(53) ウイルス(46) ウイルス蛋白質(79) 細胞(2299) A(208)
遺伝子(1080) 酵素(18) DNA(51) DNA(43) 細胞質(77) 遺伝子(1080) N(176)
膜蛋白質(947) 分子(17) レセプター(51) 分子(42) 活性蛋白質(77) 膜蛋白質(947) 細胞(148)
IL-2レセプター(838) ウイルス(17) 遺伝子(47) 活性(35) _蛋白質(75) IL-2レセプター(838) こと(148)
貯蔵蛋白質(768) ATL(11) 活性(44) 成長(32) レセプター蛋白質(71) 貯蔵蛋白質(768) IL-2レセプター(135)
DNA(765) 遺伝子(9) ウイルス(40) 貯蔵(32) 細胞(67) DNA(765) ウイルス(125)
活性(643) 活性(9) 液(35) 添加(32) 蛋白質分子(63) 活性(643) DNA(103)
相互作用(564) 量(9) 量(32) 酵素(28) -1(61) 相互作用(564) IL-2(103)
貯蔵蛋白質レセプター(455) 反応(8) ホルモン(29) 選択(24) ),蛋白質(60) 貯蔵蛋白質レセプター(455) 遺伝子(96)
ウイルス(438) 結合(8) K(24) 膜(24) 膜蛋白質(59) ウイルス(438) l(94)
分子接合体(423) T(8) 結合(20) K(22) 細胞DNA(56) 分子接合体(423) a(93)
結合(377) 合成(8) 酵素(17) レセプター(18) _2(54) 結合(377) T(84)
レセプター(377) 感染(7) 動物(17) 動物(17) 蛋白質合成(51) レセプター(377) 相互作用(78)
酵素(342) 複製(7) 濃度(17) 界面(17) DNA結合性蛋白質(50) 酵素(342) よう(78)
選択的相互作用(331) 分解(7) 基(16) 遺伝子(15) DNA(47) 選択的相互作用(331) 活性(76)
-1(305) 京大(7) 成長(15) ATL(15) DNAウイルス(45) -1(305) の(75)
合成(288) K(7) 後(15) 感染(15) ウイルスDNA(45) 合成(288) 貯蔵蛋白質(75)
_3(262) 成長(7) 導入(15) 導入(15) 粒子蛋白質(44) _3(262) セプター(73)
添加物(254) 発現(7) 機構(14) 初期(14) ウイルス(43) 添加物(254) レセプター(67)
IL-2レセプター遺伝子(241) レセプター(7) 点(13) 増殖(13) _1(41) IL-2レセプター遺伝子(241) 水(65)
導入(240) 初期(7) 由来(13) 反応(13) 2M(41) 導入(240) 添加物(61)
発現(232) ため(6) 溶媒(13) 結合(13) 貯蔵蛋白質(40) 発現(232) 選択的相互作用(60)
界面活性剤(207) 制限(6) 配列(12) T(12) 活性(40) 界面活性剤(207) 作用(59)
活性化(203) TK(6) 膜(12) 複製(11) _2M(39) 活性化(203) 膜蛋白質(57)
20K成長ホルモン(192) 液(6) ベクター(12) 合成(11) 蛋白質分解酵素(38) 20K成長ホルモン(192) 分子接合体(57)
蛋白質分子(191) 培養(6) 可能(12) 溶媒(11) 蛋白質イオン(38) 蛋白質分子(191) 生(56)
特異的(189) 膜(5) 時間(12) 腫瘍(11) IL-2(38) 特異的(189) 分子(55)
哺乳動物細胞(188) 濃度(5) 粒子(11) 測定(10) 貯蔵蛋白質レセプター(37) 哺乳動物細胞(188) これ(55)
ウイルスDNA(183) 末端(5) 分子(11) 量(10) _3(37) ウイルスDNA(183) 後(54)
増殖(177) 構成(5) 合成(11) 分解(9) 蛋白質表面(36) 増殖(177) P(54)
細胞DNA(170) NaCl(5) 部位(10) pH(9) IL-2レセプター(36) 細胞DNA(170) 成長ホルモン(53)
成長ホルモン(164) 転写(5) 末端(10) TK(8) レセプター活性(35) 成長ホルモン(164) 量(52)
細胞質(155) HSV(5) 研究(10) クローン(8) B_3),蛋白質(35) 細胞質(155) 酵素(50)
濃度(155) ヒト(5) 領域(10) 転写(8) 細胞膜(34) 濃度(155) 結合(48)
こと(148) すべて(5) 複製(10) 調節(8) 動物細胞(34) こと(148) 貯蔵蛋白質レセプター(48)
レセプター活性(142) ホルモン(5) T(10) 由来(8) ウイルス遺伝子(34) レセプター活性(142) 液(47)
SV40(141) それぞれ(5) 開始(9) 培養(7) IL-2レセプター遺伝子(34) SV40(141) RNA(47)
添加(141) 動物(5) 増殖(9) 安定(7) env蛋白質(34) 添加(141) g(47)
DNAポリメラーゼ(140) pH(4) 系(9) 変異(7) 2本鎖DNA(33) DNAポリメラーゼ(140) 図1(47)
細胞膜(139) RNA(4) 因子(9) RNA(7) _2M),(33) 細胞膜(139) 20K成長ホルモン(46)
脂肪体(138) 時間(4) mRNA(9) 開始(7) 構成膜蛋白質(32) 脂肪体(138) SV40(45)
水(130) 溶媒(4) 種(9) 液(7) 1M(32) 水(130) 要(45)
存在(124) N(4) RNA(8) サル(7) 性質蛋白質(31) 存在(124) 界面活性剤(43)
プロウイルスDNA(124) 欠(4) 断片(8) 発現(7) 脂肪体膜蛋白質(31) プロウイルスDNA(124) 貯蔵蛋白(43)
可能(124) 増殖(4) 変異(8) ヒト(7) レセプター(31) 可能(124) 基(42)
酵素活性(121) ^-(4) l(8) カラム(7) 蛋白質工学(30) 酵素活性(121) K(40)
蛋白質周辺(118) 由来(4) 表面(8) 構成(7) 吸着蛋白質(30) 蛋白質周辺(118) 発現(39)
細胞株(117) マウス(4) A(8) 京大(7) 蛋白質溶液(30) 細胞株(117) _3(39)
構造(113) 腫瘍(4) 速度(7) ため(7) それぞれ蛋白質(30) 構造(113) 存在(39)
分子(113) 導入(4) 構造(7) 制限(7) 酵素活性(30) 分子(113) ベクター(38)
ウイルス粒子(110) 開始(4) 物質(7) 産(6) 1),(30) ウイルス粒子(110) もの(38)
蛋白質表面(109) 研究(4) 発現(7) 可能(6) 1本鎖DNA(29) 蛋白質表面(109) アミ(38)
可能性(109) 正常(4) 単位(7) ホルモン(6) 蛋白質周辺(29) 可能性(109) 合成(37)
ベクター(108) 測定(3) 感染(6) 塩(6) 単純蛋白質(29) ベクター(108) 解析(37)
作用(108) 変異(3) 取込み(6) 平衡(6) 細胞株(29) 作用(108) ため(37)
研究(105) 欠損(3) 成分(6) HSV(6) ウイルス粒子構成蛋白質(29) 研究(105) ウイルスDNA(36)
腫瘍ウイルス(104) 水(3) 反応(6) NaCl(6) ウイルスDNA合成(29) 腫瘍ウイルス(104) 添加(35)
酵素量(104) クローン(3) 例(6) 時間(5) ウイルスDNA複製(28) 酵素量(104) G(35)
mRNA(94) 作用(3) 分解(6) 制御(5) 150K蛋白質(28) mRNA(94) 種(35)
蛋白質工学(91) 後(3) プロモーター(5) 作用(5) 3M(28) 蛋白質工学(91) IL-2レセプター遺伝子(35)
結合量(90) env(3) 生(5) 異常(5) pol蛋白質(28) 結合量(90) 緩衝液(34)
ため(87) 次(3) 以上(5) すべて(5) 可溶性蛋白質(28) ため(87) 脂肪体(34)
T細胞(85) l(3) 培養(5) 糖(5) 融合蛋白質(28) T細胞(85) 哺乳動物細胞(34)
疎水性(85) ゲル(3) ゲノム(5) 欠(5) T細胞(28) 疎水性(85) 溶化(34)
_1(83) 切断(3) 結果(5) env(5) 細胞増殖(28) _1(83) 細胞株(33)
分子量(83) ベクター(3) dhfr(5) 次(5) ウイルス膜(28) 分子量(83) 塩(33)
有機溶媒(82) 精製(3) ^-(5) 研究(5) 1本(28) 有機溶媒(82) 場合(33)
感染細胞(80) イオン(3) 式(5) イオン(5) 動物ウイルス(28) 感染細胞(80) ホルモン(33)
ウイルス蛋白質(79) アミノ酸(3) 段階(4) 切断(5) 遺伝子(27) ウイルス蛋白質(79) 点(33)
酵素液(78) 選択(3) 産物(4) 上記(5) 活性量(27) 酵素液(78) 濃度(32)
よう(78) 粒子(3) cDNA(4) 変性(5) 蛋白質性トキシン(27) よう(78) 増殖(32)
点(77) 塩(3) 種類(4) それぞれ(5) 分子量1(27) 点(77) 成長(31)
活性蛋白質(77) 界面(3) 測定(4) 正常(5) 貯蔵蛋白(27) 活性蛋白質(77) 導入(30)
ウイルスRNA(77) これら(3) 参照(4) 末端(5) 蛋白質近傍(27) ウイルスRNA(77) 膜(30)
IL-2(76) 平衡(3) 水(4) 濃度(5) 感染細胞(26) IL-2(76) これら(30)
5kb(76) イソアミラーゼ(3) 処理(4) A(4) 3%(25) 5kb(76) b(30)
量(76) 貯蔵(3) 促進(4) ^-(4) 蛋白質),pol(25) 量(76) 形質導入ベクター(28)
感染性ウイルス(75) 調節(3) 添加(4) キナーゼ(4) 活性化(25) 感染性ウイルス(75) 可能(28)
2種(75) 上記(3) 抗原(4) 水(4) 2本鎖DNA末端(25) 2種(75) 出(28)
_蛋白質(75) 糖(3) 飽和(4) マウス(4) キャプシド蛋白質(25) _蛋白質(75) 研究(27)
測定(74) 制御(3) g(3) 構造(4) 感染性ウイルス(25) 測定(74) 構造(27)
pH3(72) サル(3) アミノ酸(3) 粒子(4) 1本鎖(25) pH3(72) 必要(27)
動物(72) 構造(3) N(3) 認識(4) _3'(25) 動物(72) 酢酸緩衝液(26)
K(71) A(3) 界面(3) l(4) E2(24) K(71) 前(26)
DNA断片(71) アデノウイルス(3) 糖(3) 宿主(4) _3=-(N_蛋白質(24) DNA断片(71) それ(26)
レセプター蛋白質(71) neo(2) 次(3) 中間(4) K(23) レセプター蛋白質(71) 貯蔵(25)
安定性(69) 認識(2) 制御(3) ゲル(4) _2-マクログロブリン(23) 安定性(69) 性質(25)
線状2本鎖DNA(69) 最大(2) クロマトグラフィー(3) N(4) ウイルスDNAポリメラーゼ(23) 線状2本鎖DNA(69) 2本鎖DNA(25)
env蛋白質(68) 吸着(2) 切断(3) 促進(4) 成長ホルモン活性(23) env蛋白質(68) 形(25)
形質導入ベクター(68) III(2) ヘプチルチオグルコシド(3) 耐性(3) 相互作用(23) 形質導入ベクター(68) 方法(24)
構成(67) CM(2) 疾患(3) これら(3) DNA複製(23) 構成(67) 機構(24)
RNA(67) カラム(2) イソアミラーゼ(3) イソアミラーゼ(3) 大腸菌膜蛋白質(23) RNA(67) mRNA(24)
2本鎖DNA(67) 単位(2) 腫瘍(3) gag(3) 溶性膜蛋白質(23) 2本鎖DNA(67) 線状2本鎖DNA(24)
IL-2レセプターcDNA(67) 融合(2) 操作(3) mRNA(3) ウイルス粒子構成蛋白質VP1(23) IL-2レセプターcDNA(67) 有機溶媒(24)
6結合(65) これ(2) カラム(3) 融合(3) Tac-2(23) 6結合(65) _2(24)
ATL由来細胞株(64) 速度(2) 透析(3) 翻訳(3) 成長(22) ATL由来細胞株(64) 分子量(24)
解析(62) 核(2) 部分(3) アミノ酸(3) 受容細胞(22) 解析(62) 動物(23)
選択的(62) 翻訳(2) 人(3) 後(3) 酵素(22) 選択的(62) DNAポリメラーゼ(23)
性質(62) 生成(2) 存在(3) アデノウイルス(3) ウイルス増殖(22) 性質(62) 哺乳動物(22)
B_3(62) 基質(2) NaCl(3) 基質(3) A_1(22) B_3(62) 溶媒(22)

TermExtract

専門用語抽出するためのPerlのモジュールとしてTermExtractというのがあるから、午前中はこれ入れてたりした。金曜にやればいいのになんで今日(ry。

MeCab.pmの文字コードをutf8にしないといけないとかではまったりしました。なんか使う側としては、論文に書いてあったような指標とか気にしないで使えるような感じになっていた。が、自分のとちょっと比較したかったので、指標そのまま計算してくれるほうがうれしいんだけどな。

あと、こっちのやつはdbとか使って学習結果を保存とかできるようになっていた。俺のほうはどういう感じにするか。うーん。。。