如何将一组相似的产品名称分组?

时间:2019-03-25 02:29:52

标签: python

我有一个产品名称列表,其中一些是多余的或相似的:

List = ['CocaCola','CocaCola 3 Oz','Twix','Twix Caramel','Foldgers 3 Oz','Foldgers 10 Oz','Haagen Dazs Caramel','Black Forest Ham','Black Label Whiskey',...] 

我想编写一个将相似的产品名称分组的函数,以便它返回一个列表:

NewList = ['CocaCola','Twix','Foldgers','Haagen Dazs Caramel','Black Forest Ham','Black Label Whiskey',...]

我曾考虑过匹配子字符串,但是由于'CocaCola 3 Oz'和'Foldgers 3 Oz'都将映射为'3 Oz',所以这是行不通的。

我还考虑了每个产品名称中的第一个子字符串:

 NewList = []
 for w in List: 
     ws = w.split(' ')
     NewList.append(ws[0]) 

但这会将“黑森林火腿”和“黑标威士忌”映射为“黑”。

如何获取此映射?我知道beautifulsoup,并认为它可能会有所帮助,但是我找不到任何表明这一点的帖子。


根据BruceWayne的评论进行澄清: 我从Pandas df获取列表(不知道为什么这样重要吗?)。 “可口可乐”和“百事可乐”将映射到不同的组“可口可乐”和“百事可乐”。 “黑森林火腿”和“奥斯卡·迈耶火腿”也将映射到不同的组,“可口可乐”和“可口可乐Light”将映射到同一组“可口可乐”。基本上,我会根据品牌名称而不是产品类别进行分组。那决定了相似性。

我已经提供了一个基于输入的输出示例的示例。

我认为beautifulsoup会有所帮助,因为它是一个文本处理库。

2 个答案:

答案 0 :(得分:1)

您可以通过在数据集中使用聚类算法来实现您想要的目标。

a = ['CocaCola','CocaCola 3 Oz','Twix','Twix Caramel','Foldgers 3 Oz','Foldgers 10 Oz','Haagen Dazs Caramel','Black Forest Ham','Black Label Whiskey']

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.cluster import KMeans
cv=CountVectorizer()
vect=cv.fit_transform(a)
km=KMeans(n_clusters=6)
km.fit_predict(vect)

输出:

array([0, 0, 1, 1, 2, 2, 4, 3, 5], dtype=int32)

这告诉我们:

集群0:“可口可乐”,“可口可乐3盎司”

集群1:“ Twix”,“ Twix Caramel”

集群2:“ Foldgers 3 Oz”,“ Foldgers 10 Oz”

第3组:“哈根达斯焦糖色”

第4组:“黑森林火腿”

第5组:“黑标威士忌”

您首先将数据向量化,即,将列表中的每个项目转换为一维数字数组。我在这里使用CountVectorizer(易于理解并在此达到目的),但是也有其他可用的矢量化器。一维数组中的每个数字将代表一个单词,该数字的值将代表其在该文本中出现的次数。 This link will help you understand better about CountVectorizer aka Bag of Words algorithm

再一次,有很多聚类算法可供选择,我选择KMeans聚类的原因与以前相同,易于理解和实现。This will help you understand KMeans Clustering

注意:您需要按照km=KMeans(n_clusters=6)中的说明指定所需集群的数量。此处值的更改可能会更改结果。例如,

如果km=KMeans(n_clusters=5),“黑森林火腿”和“黑标威士忌”将归为同一类。

希望对您有帮助。

答案 1 :(得分:0)

您可以使用正则表达式仅提取数字前面的姓名部分。

products = ['CocaCola','CocaCola 3 Oz','Twix','Twix Caramel','Foldgers 3 Oz','Foldgers 10 Oz','Haagen Dazs Caramel','Black Forest Ham','Black Label Whiskey']
import re
products = list(set(re.findall("(.*?)[0-9]",name+"0")[0].strip() for name in products))
print(products)

# ['Black Label Whiskey', 'CocaCola', 'Black Forest Ham', 'Twix Caramel', 'Twix', 'Haagen Dazs Caramel', 'Foldgers']