首页 > 解决方案 > 使用模糊python删除重复的近似词匹配

问题描述

我想问一下如何在python中使用模糊或任何可行的方法来删除重复的近似词匹配。我有一个包含近似相似名称的 excel,此时,我想删除包含高相似性的名称并仅保留一个名称。

例如,这里是输入(excel文件),共有6行5列:

|-------------------|-----|-----|-----|-----|-----|  
| abby_john         | abc | abc | abc | abc | abc |
|-------------------|-----|-----|-----|-----|-----|  
| abby_johnny       | def | def | def | def | def |  
|-------------------|-----|-----|-----|-----|-----|  
| a_j               | ghi | ghi | ghi | ghi | ghi |  
|-------------------|-----|-----|-----|-----|-----|  
| abby_(john)       | abc | abc | abc | abc | abc |  
|-------------------|-----|-----|-----|-----|-----|  
| john_abby_doe     | def | def | def | def | def | 
|-------------------|-----|-----|-----|-----|-----|  
| aby_/_John_Doedy  | ghi | ghi | ghi | ghi | ghi |  
|-------------------|-----|-----|-----|-----|-----|  

尽管上面所有的名称看起来不同,但它们实际上是相同的,python 应该如何知道它们都是相同的并删除重复的名称并保持任何一个名称并保持它的整个行?顺便说一句,输入文件是 Excel 文件格式 (.xlsx)。

期望的输出:

|-------------------|-----|-----|-----|-----|-----|  
| abby_john         | abc | abc | abc | abc | abc |
|-------------------|-----|-----|-----|-----|-----|  

由于下划线不是很重要,它可以用'spacing'代替,因此可以接受另一个输出如下:另一个期望的输出:

|-------------------|-----|-----|-----|-----|-----|  
| abby_john         | abc | abc | abc | abc | abc |
|-------------------|-----|-----|-----|-----|-----|  

如果有人能帮助我,不胜感激,谢谢!

标签: pythonpandasfuzzy

解决方案


这是一类称为语义相似性的问题。

获取数据:

from io import StringIO
s = StringIO("""abby_john         abc   abc   abc   abc 
abby_johnny       def   def   def   def 
a_j               ghi   ghi   ghi   ghi 
abby_(john)       abc   abc   abc   abc 
abby_john_doe     def   def   def   def 
aby_John_Doedy    ghi   ghi   ghi   ghi
abby john         ghi   ghi   ghi   ghi
john_abby_doe     def   def   def   def
aby_/_John_Doedy  ghi   ghi   ghi   ghi
doe jane          abc   abc   abc   abc
doe_jane          def   def   def   def""")

import pandas as pd
df = pd.read_fwf(s,header=None,sep='\s+')
lst_original = df[0].tolist() # the first column 

向量化(变成数字表示):

import numpy as np 
from gensim.models import Word2Vec

m = Word2Vec(lst_original,size=50,min_count=1,cbow_mean=1)  
def vectorizer(sent,m): 
    vec = [] 
    numw = 0 
    for w in sent: 
        try: 
            if numw == 0: 
                vec = m[w] 
            else: 
                vec = np.add(vec, m[w]) 
            numw += 1 
        except Exception as e: 
            print(e) 
    return np.asarray(vec) / numw 

l = []
for i in lst_original:
    l.append(vectorizer(i,m))

X = np.array(l)

KMeans 聚类

from sklearn.cluster import KMeans

clf = KMeans(n_clusters=2,init='k-means++',n_init=100,random_state=0)
labels = clf.fit_predict(X)

然后我们只得到集群交替的值:

previous_cluster = 0
for index, sentence in enumerate(lst_original):
    if index > 0:
        previous_cluster = labels[index - 1]
    cluster = labels[index]
    if previous_cluster != cluster:
        print(str(labels[index]) + ":" + str(sentence))

结果,正如您所看到a_j的,与该组的其他成员不同abby_john

1:a_j
0:abby_(john)
1:doe jane

推荐阅读