image

  • フォト Amazonギフト券
    ※この時計の時刻は、閲覧しているパソコンのものであり、必ずしも正確な時間とは限りません

検索

最近のトラックバック

無料ブログはココログ

« タイマー付きダイアログボックス | トップページ | ピックアップ:大規模にしないためにはどうするか」を考えよう, 部下のやる気を育てる為にリーダーが知っておくべき名言, etc... »

2008-09-18

ferret を使いたい (その3)

先週末に 書籍 "Ferret" を入手した。

書籍のサンプルを試して、使い方は分かった気がする。

そこでferret で 郵便番号データ(全国版) を index を作り、検索をさせてみた。
index をつくるのが遅いけど、検索は十分な速さがある。
この程度なら、xfy/xvcd から ruby を呼び出して使う際も、十分な速度が得られると思われる。
// index を作るソースが、我ながらいダサイ。もっとよい書き方に変更できると思うが、まずは動作させることから...

使用マシンは MacBook, MacOSX 10.5。
$ gem list ferret
*** LOCAL GEMS ***
ferret (0.11.6)

$ ruby -version
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9]

インデックスを作る。
$ time ruby ZiptoFerret.rb
..........................................................................................................................
indexed 122535 zips.

real    2m7.108s
user    1m26.578s
sys    0m36.770s

ferret のワイルドカード検索を使う。
$ time ruby search-zipcode.rb '*有楽町*'
1.0: 0383135  青森県 つがる市 木造有楽町
1.0: 3260801  栃木県 足利市 有楽町
1.0: 3591114  埼玉県 所沢市 北有楽町
1.0: 3591117  埼玉県 所沢市 有楽町
1.0: 1000006  東京都 千代田区 有楽町
1.0: 9188008  福井県 福井市 有楽町
1.0: 5020033  岐阜県 岐阜市 長良有楽町
1.0: 5060013  岐阜県 高山市 有楽町
1.0: 4418035  愛知県 豊橋市 有楽町
1.0: 4750837  愛知県 半田市 有楽町
1.0: 5110079  三重県 桑名市 有楽町
1.0: 7450035  山口県 周南市 有楽町
12 hits.

real    0m0.313s
user    0m0.243s
sys    0m0.065s

AND 指定で絞り込むこともできる。
$ time ruby search-zipcode.rb '*東京* AND *有楽町*'

1.0: 1000006  東京都 千代田区 有楽町
1 hits.

real    0m0.424s
user    0m0.333s
sys    0m0.085s

以下にコードを示す。

$ cat LineAnalyzer.rb

require 'pp'
require 'MeCab'

class LineAnalyzer
  def initialize()
  end
  def token_stream(field, str)
   return LineTokenizer.new(str)
  end
end

class LineTokenizer
  def initialize(str)
    self.text = str
  end

  def text=(str)
    @n = str
  end

  attr_reader :text
  def next
    return nil if @n == nil
    token = Analysis::Token.new(@n, 0, @n.length)
    @n = nil
    return token
  end
end

$ cat ZiptoFerret.rb

# See http://webos-goodies.jp/archives/51369852.html

require 'rubygems'
require 'nkf'
require 'csv'
require 'ferret'

require 'LineAnalyzer'

include Ferret
include Ferret::Index
include Ferret::Analysis

$KCODE='UTF8'

Ferret.locale = 'ja_JP.UTF-8'

index_dir = 'zip_index'
csv_fname = 'KEN_ALL.CSV'

data = NKF.nkf('-Sw80m0', IO.read(csv_fname))

# index = Index.new(:path=> index_dir, :create => true, :analyzer => RegExpAnalyzer.new(/.*/, false))
index = Index.new(:path=> index_dir, :create => true, :analyzer => LineAnalyzer.new)

line_count = 0

# 01101,"060  ","0600000","ホッカイドウ","サッポロシチュウオウク","イカニケイサイガナイバアイ","北海道","札幌市中央区","以下に掲載がない場合",0,0,0,0,0,0

CSV::Reader.parse(data) do |row|
  line_count += 1
  index << {
    :id => line_count,
    :zip => row[2],
    :prefecture => (row[6]||''),
    :city => (row[7]||''),
    :street => (row[8]||'')
  }
  if line_count % 1000 == 0
    printf "."
    $stdout.flush
  end

end

index.optimize

index.close
puts "\nindexed #{line_count} zips."

$ cat search-zipcode.rb

require 'rubygems'
require 'ferret'
require 'fileutils'
require 'MecabAnalyzer'

require 'pp'

include Ferret
include Ferret::Index

$KCODE='utf8'

def usage(message = nil)
  puts message if message
  puts "ruby #{File.basename(__FILE__)} <search_pattern>"
  puts "  examples for search_patter:"
  puts "         '*10000*'  "
  puts "         '*千代田区*' "
  puts "         ':zip:*1000*'"
  puts "         ':city:*千代田区*'"
  puts "         ':street:*有楽町*'"
  puts "         '*千代田区* AND *有楽町*'"
  puts " 注意: 文字コードは UTF-8. "
  exit(1)
end

index_dir ="zip_index"
limit = 100
offset = 0

usage() if ARGV.size != 1

search_phrase = ARGV[0]

index = Index.new(:path => index_dir)

results = []

total_hits = index.search_each(search_phrase,
                               :limit => limit, :offset => offset) do |id, score|
  results << " #{score}: #{index[id][:zip]}  #{index[id][:prefecture]} #{index[id][:city]} #{index[id][:street]}"
end

index.close

puts results.join("\n")
puts "#{total_hits} hits."

« タイマー付きダイアログボックス | トップページ | ピックアップ:大規模にしないためにはどうするか」を考えよう, 部下のやる気を育てる為にリーダーが知っておくべき名言, etc... »

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: ferret を使いたい (その3):

« タイマー付きダイアログボックス | トップページ | ピックアップ:大規模にしないためにはどうするか」を考えよう, 部下のやる気を育てる為にリーダーが知っておくべき名言, etc... »

mokuji

2013年12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

google

  • twitter
  • __
  • _
    Googleボットチェッカー

合わせて読む

  • 合わせて読む
    フィードメーター - katoy: cocolog あわせて読みたい

リンク