【发布时间】:2019-03-27 13:17:55
【问题描述】:
我的输入是这个(spintax)格式的字符串,
"The {PC|Personal Computer|Desktop} is in {good|great|fine|excellent} condition"
然后使用 itertools,我生成所有可能的组合。 例如
"The PC is in good condition"
"The PC is in great condition"
.
.
.
"The Desktop is in excellent condition"
在这些字符串中,我只想根据相似度阈值保留最独特的字符串,例如只保留相似度低于 60% 的字符串。我使用了SequenceMatcher 库,但由于循环,它不适用于大型数据集(250K+ 项)。这是当前的实现,
def filter_descriptions(descriptions):
MAX_SIMILAR_ALLOWED = 0.6 #40% unique and 60% similar
i = 0
while i < len(descriptions):
print("Processing {}/{}...".format(i + 1, len(descriptions)))
desc_to_evaluate = descriptions[i]
j = i + 1
while j < len(descriptions):
similarity_ratio = SequenceMatcher(None, desc_to_evaluate, descriptions[j]).ratio()
if similarity_ratio > MAX_SIMILAR_ALLOWED:
del descriptions[j]
else:
j += 1
i += 1
return descriptions
我(几乎)每次迭代都会缩短列表,以加快进程。但我肯定需要一个更快的算法来解决这个问题。我也尝试了余弦相似度,但在那里遇到了缩放问题。它适用于大约 10K 项目,但超过它只是卡住了我的机器。 这是实现,
from sklearn.metrics.pairwise import cosine_similarity
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(descriptions)
val = cosine_similarity(tfidf_matrix[:10000], tfidf_matrix[:10000])
对此有任何优化的解决方案吗?我只想从列表中挑选 n 个最独特的字符串。
【问题讨论】:
-
不是一个解决方案,但我认为你有一个错误。删除 descriptions[j] 后不应该增加 j。
-
更新了代码,几个小时前修复了这个错误 :)
-
我可能遗漏了一些东西,但是你为什么在找到类似的描述后又重新开始呢?删除 descriptions[j] 后为什么不保留 j 原样?
-
已修复...感谢您指出这一点,难怪需要花费大量时间 :)
-
但我相信还有更好的方法......某处