我有一个产品名称列表,其中一些是多余的或相似的:
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会有所帮助,因为它是一个文本处理库。
答案 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']