【问题标题】:is that possible to group a array of string based on the similarity in ruby是否可以根据 ruby​​ 中的相似性对字符串数组进行分组
【发布时间】:2017-06-15 16:56:36
【问题描述】:

我已经实现了一个自定义的 ruby​​ 方法,它使用循环对相似的文本进行分组,

 array = ["South East Queensland", "Wide Bay Burnett", "Margaret River", "Port Pirie", "Gippsland", "Elizabeth", "Barossa"]
similarity_group = []
similarity_percentage = 60.0

array.each do |first_text|
  results.each do |second_text|
    result = first_text.upcase.similar(second_text.upcase)
     if result >= similarity_percentage
      ...
      ...
      ...
    end  
  end
end

考虑2000个元素的上述实现,然后将它们分组将花费4000000次迭代,因为每个元素将相互检查。

是否有任何高性能解决方案或 gem 或库,例如根据它们的相似性对大容量数组进行分组。

(我需要使用相同的数组元素进行相似性检查)

样本期望:[array1].similarity([array1])

【问题讨论】:

  • similar 来自哪里?是来自宝石吗?哪一个?
  • 注意:您使用了两次first_text。我想相似性总是 1 :) 一个明显的优化是仅在 string1 >= string2 时检查 2 个字符串。它将迭代次数减半。

标签: ruby-on-rails ruby similarity


【解决方案1】:

我认为您正在寻找基于字符串距离的clustering(例如Levensthein)。从您的代码来看,similar 似乎已经实现,所以必须清楚您正在考虑的距离。

对于集群,这些 two gems 可能会有所帮助。

问题是hard,所以相比之下,你的 O(n**2) 实际上并没有那么糟糕。您可以通过在计算距离之前检查 string1 > string2 来避免两次比较字符串对。你需要(2000*1999)/2 迭代而不是2000**2

【讨论】:

  • 感谢@Eric Duminil,是的,相似是一个有助于找到两个字符串之间相似度百分比的宝石。抱歉,这是一个错字。我更新了我的问题。
【解决方案2】:

我有一个过去用来比较电子书的矩阵解决方案,因为这些电子书非常大并且需要时间来处理这些书同样准确且速度更快。我可以为您搜索矩阵解决方案,但我有另一个基于 levenshtein 的简单例程,它看起来很像您想要完成的,创建一个相似度数组(此处为哈希)。

我在我的脚本库中发布我的脚本的工作版本,所以你可能想要调整其中的一些。 我以前用它作为this问题的答案。 例如,您可以用同样的方式构建一个数组。

require 'levenshtein'

MAX_DISTANCE, COMPENSATION = 3, 5

strings = [
    "Hazard Const. Company",
    "hazard construction company",
    "PETERSON-CHASE GENERAL ENGINEERING CONSTRUCTION INC",
    "peterson-chase general  engineering construction inc",
    "TRAFFIC DEVELOPMENT SERVICES ",
    "traffic development services"
]

result = {}
strings.each do |s|
    s.downcase!
  similar = result.keys.select { |key| Levenshtein.distance(key, s) < MAX_DISTANCE+(s.length/COMPENSATION) }
  if similar.any?
    result[similar.first] += 1
  else
    result.merge!({s => 1})
  end
end

p result
# {"hazard const. company"=>2, "peterson-chase general engineering construction inc"=>2, "traffic development services "=>2}

【讨论】:

  • 非常感谢您和@Eric Duminil。让我试试你的两个解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
  • 2017-07-01
  • 1970-01-01
  • 2013-12-07
  • 2010-12-15
  • 2011-09-03
  • 1970-01-01
相关资源
最近更新 更多