根据条目相似性合并 XML 个文件

Combine XML files based on entry similarity

我需要使用 PHP 组合结构不同的 XML 文件。我正在做的是;

  1. 首先使用 simplexml_load_file()
  2. 读取 XML 文件
  3. 使用新结构重新格式化元素 SimpleXMLElement() class
  4. 对另一个文件执行相同的操作,递增第一个 SimpleXMLElement() 实例
  5. 保存新合并的 XML 文件。

到目前为止一切顺利。棘手的部分是,第一个文件有大约。 3000个条目,第二个文件有5000个。其中将近2000个条目实际上是相同的;可能只有几个字母不同。例如; "Lenovo G50-70 CoreI5" 另一个可能是 "Lenovo G5070 I5".

问题是,如何将第一个文件的条目与第二个文件的相同条目进行匹配;所以在新的组合文件中实际上它恰好只有一个条目?

我同时使用 PHP 和 SmithWatermanGotoh 的 similar_text() 函数来计算相似度,它的数学得分为 86%;这对我来说已经足够了。但是迭代另一个文件的所有条目以仅匹配一个条目对我来说是非常不明智和资源消耗的。因为它意味着大约。每次我保存新的更新文件时,7MB 的文件加载到内存中至少进行 15.000 次迭代。

我考虑将所有条目插入数据库 table 并使用 Sphinx 搜索来匹配条目;但我不确定它是否真的有帮助。

我能看到的最佳方法是使用带有 array_uintersect() 函数的自定义回调。这种方式的工作步骤如下;

1- 编写一个比较函数来计算相似度。查看 php.net 的 array_uintersect() 手册,了解您需要如何编写此回调函数。假设它的名字是 find_similar_entries()

2- 将来自不同 XML 文件的两个条目分别收集到两个数组中。 (为了快速,请先执行 json_encode() 然后 json_decode() 返回。)

3- 具有交集功能,可以找到类似的条目; $similar_products = array_uintersect($xml_array1, $xml_array2, 'find_similar_entries');

4- 现在您在一个数组中收集了相似的条目。

5- 调用 array_diff() 从原始数组中删除相似条目。

6- 最后根据您的意愿将所有三个数组组合成一个新的 XML 结构,使用 SimpleXMLElement() class.

注意 1:我使用 similar_text() 和 SmithWatermanGotoh 来计算相似度,我可以说它们一起工作得很好。但是当涉及到非常接近的产品名称时,它们之间可能只有几个字符不同,它们最终会变成 "identical"。除了从字符串中提取可区分的词外,您无能为力。就像我的 "model name" 一样。

注意 2:此方法按预期工作,但我认为 PHP 的交集函数有一个错误,这使得这些函数非常慢。我为此创建了 a bug report。交集不只比较两个数组的元素。但它也会比较数组自身的元素。这实际上是不合逻辑的,因为只有至少比较两方才能计算出交集。所以从里面比较一个数组其实并不是"intersection"。这就是为什么如果你有大文件,如果你只是 运行 这么直截了当,你的脚本就会死掉。也许你可以一块一块地做。