LoginSignup
23
24

More than 5 years have passed since last update.

Rubyで文字列の類似度を計算する関数を作った

Last updated at Posted at 2014-11-26

はじめに

文字列がどのくらい似ているか比べたいときってありません?
Rubyで文字列を比較する関数を作りました。
文章をベクトル化してコサイン類似度を求めています。
一応動いているのですが、冗長なところや間違っているところがあったら教えてください。

準備

  • Mecabをインストール

コード

cosine_similarity.rb
require 'mecab'
require 'matrix'

# コサイン類似度を計算
# @param [String] str1 文字列
# @param [String] str2 文字列
# @return [Float] スコア
def calc_score(str1,str2)
  vector = []
  vector1 = []
  vector2 = []
  frag_vector1 = []
  frag_vector2 = []

  node1 = MeCab::Tagger.new.parseToNode(str1)
  node2 = MeCab::Tagger.new.parseToNode(str2)

  while node1
    vector1.push(node1.surface)
    node1 = node1.next
  end

  while node2
    vector2.push(node2.surface)
    node2 = node2.next
  end

  vector += vector1
  vector += vector2

  #重複と空文字列を削除
  vector.uniq!.delete("")
  vector1.delete("")
  vector.delete("")
  vector2.delete("")

  vector.each do |word|
    if vector1.include?(word) then
      frag_vector1.push(1)
    else
      frag_vector1.push(0)
    end

    if vector2.include?(word) then
      frag_vector2.push(1)
    else
      frag_vector2.push(0)
    end
  end

  vector1_final = Vector.elements(frag_vector1, copy = true)
  vector2_final = Vector.elements(frag_vector2, copy = true)

  return vector2_final.inner_product(vector1_final)/(vector1_final.norm() * vector2_final.norm())

end
23
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
24