ruby stem + Linguistics

http://d.hatena.ne.jp/n_shuyo/20071128/vocabulary#c
の内容を理解しようと奮闘中。
(というより、同じようなコードを何も見ないで書けるようになるための方法を模索中?
何かしらに応用できそうな気がする。)

以下の2つのライブラリが使われている

  • linguistics
  • stem

gemでinstall

sudo gem install stemmer linguistics -y

どちらもriで見られるドキュメントは存在しないみたい。
直接コードをみることにした。

まずはstemmerの方

本体は200行程度のひとつのファイル。必要そうなところだけ抽出

  # Porter stemmer in Ruby.
  #
  # This is the Porter stemming algorithm, ported to Ruby from the
  # version coded up in Perl.  It's easy to follow against the rules
  # in the original paper in:
  #
  #   Porter, 1980, An algorithm for suffix stripping, Program, Vol. 14,
  #   no. 3, pp 130-137,
  #
  # See also http://www.tartarus.org/~martin/PorterStemmer



  # make the stem_porter the default stem method, just in case we
  # feel like having multiple stemmers available later.
  #
  alias stem stem_porter


# Add stem method to all Strings
class String
  include Stemmable
end

語幹=語尾が変わっても変化しない部分をstemということが分かった。
require "stemmer"をすると、String#stemが使えるようになるということは分かった。

今度はlinguisticsの方

とりあえず、READMEがあったので、その中をみてみる。
はじめに何語を使うのか知らせる必要があるみたい。

  Linguistics::use( :en )
  # => [String, Numeric, Array]
  "goose".en.plural
  # => "geese"

たぶん、StringとNumericとArrayに新しいメソッドが追加されるんだと思う。
Linguistics*/libのdirectory構成はこんな感じ

$ tree /var/lib/gems/1.8/gems/Linguistics-1.0.3/lib/
/var/lib/gems/1.8/gems/Linguistics-1.0.3/lib/
|-- linguistics
|   |-- en
|   |   |-- infinitive.rb
|   |   |-- linkparser.rb
|   |   `-- wordnet.rb
|   |-- en.rb
|   `-- iso639.rb
`-- linguistics.rb
en.rbを覗いてみる

publicメソッドはこんな感じ
(たぶん、publicメソッドだけを読めばいいんだと思います><)

   1107:	def language
   1114:	def plural( phrase, count=nil )
   1131:	def plural_noun( phrase, count=nil )
   1144:	def plural_verb( phrase, count=nil )
   1159:	def plural_adjective( phrase, count=nil )
   1174:	def a( phrase, count=nil )
   1188:	def no( phrase, count=nil )
   1203:	def present_participle( word )
   1246:	def numwords( number, hashargs={} )
   1359:	def ordinal( number )
   1379:	def quantify( phrase, number=0, args={} )
   1485:	def conjunction( obj, args={} )
   1595:	def camel_case_to_english( string )
   1601:	def english_to_camel_case( string )
   1613:	def titlecase( string ) # :nodoc:
   1654:	def proper_noun( string )
   1672:	def separate( value=:__no_arg__, &block )
   1679:	def separate!( value=:__no_arg__ )

plural=複数形

inifinitive
   1024:		def initialize( word1, word2, suffix, rule )
   1052:	def infinitive( word )

infinitive = 不定

疲れた。linkparser.rbとwordnet.rbはまた今度
楽にどんなメソッドがあるか調べる方法ないかな?
def f(h)
  require 'rubygems'
  h.each{ |k,v| h[k] << k.methods}
  require 'stemmer'
  require 'linguistics'
  Linguistics::use( :en )
  h.each{ |k,v| h[k] << k.methods}
  h.map{ |k,v| {k => (v.last - v.first) }}
end

def g(a)
  a.map do |e| 
    en = e.en
    [e , (en.methods - Object.methods)]
  end
end

h1 = { "string" => [], ["array","A"] => [], 3 => [] }
require 'pp'
pp f(h1)
puts "\n==<Something>.en.methods===\n\n"
pp g(["string", [], 3])
# >> [{3=>["en"]},
# >>  {["array", "A"]=>["en", "separate", "separate!"]},
# >>  {"string"=>["en", "stem_porter", "stem"]}]
# >> 
# >> ==<Something>.en.methods===
# >> 
# >> [["string", ["method_missing"]],
# >>  [[], ["method_missing"]],
# >>  [3, ["method_missing"]]]

#methods_missingで補足しているのかも?
en = "dog".en
en.a # => "a dog"
en.plural # => "dogs"
en.infinitive # => ""
pp en.methods - Object.methods 
# >> ["method_missing", "plural", "infinitive", "a"]