Edited at

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

More than 3 years have passed since last update.


はじめに

文字列がどのくらい似ているか比べたいときってありません?

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