Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Goによる近似最近傍探索の実装/Approximate_nearest_neighbor_se...

 Goによる近似最近傍探索の実装/Approximate_nearest_neighbor_search_written_in_Golang.

monochromegane

April 24, 2017
Tweet

More Decks by monochromegane

Other Decks in Programming

Transcript

  1. 4QPUJGZBOOPZ w "QQSPYJNBUF/FBSFTU /FJHICPST0I:FBI w $ ϥΠϒϥϦͱ1ZUIPO౳ͷό ΠϯσΟϯάΛఏڙ w ϥϯμϜαϯϓϦϯάͨ͠ೋ఺Λ

    ݩʹۭؒΛೋ෼ׂΛ܁Γฦͯ͠໦ ߏ଄Λෳ਺ߏங w ୳ࡧ࣌͸෼ׂϕΫτϧͰৼΓ෼͚
  2. 4QPUJGZBOOPZ f = 40 t = AnnoyIndex(f) for i in

    xrange(1000): v = [random.gauss(0, 1) for z in xrange(f)] t.add_item(i, v) t.build(10) t.save('test.ann') # ... u = AnnoyIndex(f) u.load('test.ann') print(u.get_nns_by_item(0, 1000))
  3. NSVCZBOOPZPOOHY@NSVCZ class NNS def call(env) params = env['QUERY_STRING'].split('&') .map {|kv|

    kv.split('=') }.to_h category_id = params['category_id'].to_i product_id = params['product_id'].to_i limit = (params['limit'] || 10).to_i userdata = Userdata.new "annoy_data_key" annoy = userdata.send("category_#{category_id}") return not_found unless annoy nns = annoy.get_nns_by_item(product_id, limit) [200, content_type, [nns.to_json]] end private def not_found return [404, content_type, [{'error' => 'not_found'}.to_json]] end def content_type {'Content-Type' => 'application/json;charset=utf-8'} end end run NNS.new
  4. HBOOPZ # Add item $ curl \ ’http://localhost:1323/databases/hoge/features/100’ \ -H

    "Content-type: application/json” \ -X PUT \ -d '{"features": [1.0, 0.5, 0.2,..]}’ # Search $ curl \ ’http://localhost:1323/search?database=hoge&id=100’
  5. HBOOPZ(PSPVUJOF var wg sync.WaitGroup wg.Add(g.tree) buildChan := make(chan int, g.tree)

    worker := func(n Node) { for index := range buildChan { g.build(index, g.meta.roots()[index], n) wg.Done() } } for i := 0; i < 3; i++ { go worker(n) } for index, _ := range g.meta.roots() { buildChan <- index } wg.Wait() close(buildChan)
  6. HBOOPZγεςϜίʔϧ err := syscall.FcntlFlock(f.file.Fd(), syscall.F_SETLKW, &syscall.Flock_t{ Start: f.offset(index), Len: f.nodeSize(),

    Type: syscall.F_RDLCK, Whence: io.SeekStart, }) if err != nil { fmt.Printf("fcntl error %v\n", err) } defer syscall.FcntlFlock(f.file.Fd(), syscall.F_SETLKW, &syscall.Flock_t{ Start: f.offset(index), Len: f.nodeSize(), Type: syscall.F_UNLCK, Whence: io.SeekStart, }) b := make([]byte, f.nodeSize()) syscall.Pread(int(f.file.Fd()), b, f.offset(index))