根据条目相似性组合 XML 文件
Posted
技术标签:
【中文标题】根据条目相似性组合 XML 文件【英文标题】:Combine XML files based on entry similarity 【发布时间】:2017-03-07 17:35:45 【问题描述】:我需要使用 php 组合不同结构的 XML 文件。我正在做的是;
-
使用
simplexml_load_file()
读取第一个XML文件
使用 SimpleXMLElement()
类的新结构重新格式化元素
对另一个文件执行相同操作,递增第一个 SimpleXMLElement()
实例
保存新合并的 XML 文件。
到目前为止一切顺利。棘手的部分是,第一个文件大约有。 3000 个条目,第二个文件有 5000 个。其中近 2000 个条目实际上是相同的;只是可能有几个字母不同。比如说; “Lenovo G50-70 CoreI5”,另一个可能是“Lenovo G5070 I5”。
问题是,如何将第一个文件的条目与第二个文件的相等条目匹配;所以实际上它恰好只是一个条目,在新的组合文件中?
我同时使用 PHP 的 similar_text()
函数和 SmithWatermanGotoh 来计算相似度,它的得分为 86%;这对我来说已经足够了。但是迭代另一个文件的所有条目以仅匹配一个条目对我来说是非常不明智和资源消耗的。 Beucase 这意味着大约。每次我保存一个新的更新文件时,都会将 7MB 的文件加载到内存中,至少进行 15.000 次迭代。
我考虑将所有条目插入数据库表并使用 Sphinx Search 来匹配条目;但我不确定它是否真的有足够的帮助。
【问题讨论】:
如果内存是个问题,generators 可能会有所帮助。 我认为这里的主要问题是similar_text()
的复杂性。如果我是你,我会定义一组规则,以独特的方式格式化每个条目,然后你可以轻松找到重复项。
@CasimiretHippolyte,我无法清楚地实践您的建议,请您更具体一些吗?顺便说一句,有完全相同的条目,也就是重复;但也有一些条目实际上相同,但不完全相同。就像问题中给出的例子一样。
我的意思是这样的:eval.in/666262
【参考方案1】:
我能看到的最好的方法是使用带有array_uintersect()
函数的自定义回调。这种方式的工作步骤如下:
1- 编写一个比较函数来计算相似度。查看 php.net 中的 array_uintersect()
手册,了解如何编写此回调函数。说它的名字是find_similar_entries()
2- 将来自不同 XML 文件的两个条目分别收集到两个数组中。 (为了快速,请先执行json_encode()
,然后执行json_decode()
back。)
3- 有交集功能找到类似的条目; $similar_products = array_uintersect($xml_array1, $xml_array2, 'find_similar_entries');
4- 现在您在一个数组中收集了类似的条目。
5- 调用array_diff()
以从原始数组中删除类似条目。
6- 最后,使用SimpleXMLElement()
类,按照您的意愿将所有三个数组组合成一个新的 XML 结构。
注意1:我使用similar_text()
和SmithWatermanGotoh 来计算相似度,我可以说它们可以很好地协同工作。但是当涉及到非常接近的产品名称时,它们之间可能只有几个字符不同,它们最终会“相同”。除了从字符串中提取有区别的单词之外,您无能为力。就我而言,就像“型号名称”。
注意2:这种方法按预期工作,但我认为PHP的交集函数有一个错误,这使得这些函数变得如此缓慢。我为此创建了a bug report。 Intersection 不只横向比较两个数组的元素;但它也比较数组自己的元素。这实际上是不合逻辑的,因为只能通过比较至少两方来计算交集。因此,从内部比较一个数组实际上并不是“交集”。这就是为什么如果你有大文件,如果你直接运行它,你的脚本就会死掉。也许你可以一块一块地做。
【讨论】:
以上是关于根据条目相似性组合 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章
有没有一种方法可以根据不完全相同的值在 SQL 中组合相似的行?