将名称很少或没有异常的名称聚类/分组到熊猫中的聚类中

时间:2019-06-20 10:36:00

标签: python pandas

我有一个数据框,名称字段为:

print(df)
                              names
   --------------------------------
0  U.S.A.
1  United States of America
2  USA
4  US America
5  Kenyan Footbal League
6  Kenyan Football League
7  Kenya Football League Assoc.
8  Kenya Footbal League Association
9  Tata Motors
10 Tat Motor
11 Tata Motors Ltd.
12 Tata Motor Limited
13 REL
14 Reliance Limited
15 Reliance Co.

现在,我想将所有这些类似的名称归为一类,以使最终数据框看起来像这样:

print(df)
                              names   group_name
   ---------------------------------------------
0  U.S.A.                             USA
1  United States of America           USA
2  USA                                USA
4  US America                         USA
5  Kenyan Footbal League              Kenya Football League
6  Kenyan Football League             Kenya Football League
7  Kenya Football League Assoc.       Kenya Football League
8  Kenya Footbal League Association   Kenya Football League
9  Tata Motors                        Tata Motors
10 Tat Motor                          Tata Motors
11 Tata Motors Ltd.                   Tata Motors
12 Tata Motor Limited                 Tata Motors
13 REL                                Reliance
14 Reliance Limited.                  Reliance
15 Reliance Co.                       Reliance

现在只有16条记录,因此可以轻松查找其名称中所有可能的名称和异常,并创建用于映射的字典。但是实际上我有一个约5800个唯一名称的数据框(注意:“ USA”和“ USA”在说明唯一性计数时被视为不同的实体)。
因此,有没有任何编程方法可以解决此类问题?一个场景?

我尝试使用difflibfuzzywuzzy库运行模糊匹配,但是即使最终结果也不是很具体。很多时候,difflib只会根据'limited','association'等单词进行匹配。即使他们指的是两个不同的名称,只是它们之间的通用词只是“关联”或“受限”。
任何帮助表示赞赏。

编辑:
即使我创建了包含“联想”,“有限”,“合作”,“组”等词的停用词列表,当提及不同时,也有可能会错过这些停用词的名称。例如,如果仅将“关联”和“受限”提到为“关联”,“ ltd”和“ ltd”。我很可能会错过将其中一些添加到停用词列表中的机会。

我已经尝试过,使用LDA和NMF进行主题建模,其结果与我先前使用difflibfuzzywuzzy库获得的结果非常相似。是的,在进行上述任何一种方法之前,我都进行了所有预处理(转换为小写,leamtization,额外的空格处理)

2 个答案:

答案 0 :(得分:1)

迟来的答案,集中精力一个小时,您可以使用difflib.SequenceMatcher并过滤比0.6大的比率,以及一大堆代码...我也很简单删除修改后的names列中每个列表的最后一个单词,得到显然可以得到所需结果的最长单词,这里就是...

import difflib
df2 = df.copy()
df2.loc[df2.names.str.contains('America'), 'names'] = 'US'
df2['names'] = df2.names.str.replace('.', '').str.lstrip()
df2.loc[df2.names.str.contains('REL'), 'names'] = 'Reliance'
df['group_name'] = df2.names.apply(lambda x: max(sorted([i.rsplit(None, 1)[0] for i in df2.names.tolist() if difflib.SequenceMatcher(None, x, i).ratio() > 0.6]), key=len))
print(df)

输出:

                                names             group_name
0                              U.S.A.                    USA
1            United States of America                    USA
2                                 USA                    USA
3                          US America                    USA
4               Kenyan Footbal League  Kenya Football League
5              Kenyan Football League  Kenya Football League
6        Kenya Football League Assoc.  Kenya Football League
7    Kenya Footbal League Association  Kenya Football League
8                         Tata Motors            Tata Motors
9                           Tat Motor            Tata Motors
10                   Tata Motors Ltd.            Tata Motors
11                 Tata Motor Limited            Tata Motors
12                                REL               Reliance
13                   Reliance Limited               Reliance
14                       Reliance Co.               Reliance

尽我所能的代码。

答案 1 :(得分:0)

据我所知。我不认为您可以得到准确的结果,但是您可以做一些事情来帮助您清理数据

  1. 首先使用.lower()降低字符串
  2. 使用strip()剥离字符串以删除多余的空格
  3. 标记字符串
  4. 数据的定型和词条化

您应该研究句子相似性python中存在多个库,例如gensim,nltk
https://radimrehurek.com/gensim/tutorial.html
https://spacy.io/
https://www.nltk.org/

即使我创建了非常基本的文档相似性项目,也可以查看此github
https://github.com/tawabshakeel/Document-similarity-NLP-

我希望所有这些东西都能帮助您解决问题。