2017-01-16 7 views
0

"가까운"일치가 발견되지 않으면 두 세트 중 가장 가까운 것을 찾으려는 두 세트의 이름이 있습니다. 그 이름을 그 이름과 일치시키고 싶습니다 .두 세트의 이름 사이에서 가장 근사치를 찾는 것

나의 현재 접근 방식은 모든 가능한 조합을 갖는 dataframe 만들고 반복하고 (SM로 가져온) SequenceMatcher 통해 유사성 비율을 계산하거나리스트 .apply 사용하는 것이다.

문제는 두 목록에 수천 개의 이름이있어서 실행하기 힘든 결과를 낳습니다.

내 일치 기준은 두 번째 이름에서 발견되는 이름이 전체 단어 인 이상적으로는> 0.85 이상의 sm 비율이됩니다. 이 기준이 충족되지 않으면 그 이름이 그 자체와 일치해야합니다. 내가 구현하고자하는

마지막 단계는이 일치하는 이름을 가진 원래 시리즈를 대체하기 위해 다음이다. 여기

내 현재의 접근 방식에 대한 코드입니다,이 불분명 한 경우 알려 주시기 바랍니다의 I 명확히 도울 수있는 방법 :

stop_words = [ 
      'pharmaceuticals', 
      'pharmaceutical', 
      'pharma', 
      'therapeutic', 
      'biopharma', 
      'therapeutics', 
      'international', 
      'biotechnology', 
      'vaccines', 
      '\&', 
      '&', 
      'co.', 
      'co', 
      'biotherapeutics', 
      'biotherapeutic', 
      'life science', 
      'life sciences', 
      'laboratories', 
      'biologics', 
      ] 

temp_db_companies = db['Company'] 

def approximate_match(s1, s2): 
    return str(sm(None, str(s1).lower().strip(), str(s2).lower().strip()).ratio()) + '|' + str(s2).strip() 


def replace_val_w_best_match(df, col_initial, series_final, stop_words): 
    init_names = df[col_initial].str.lower().str.split(" ", expand=True).replace(stop_words, "").fillna('') 

    init_names = pd.Series(['' for n in range(len(init_names))]).str.cat([init_names[col] for col in init_names.columns], sep= " ").str.replace(' ', ' ').reset_index() 

    matching_df = pd.DataFrame(columns = list(init_names.columns) + list(series_final), data = init_names) 

    matching_df = pd.melt(matching_df, 
          id_vars = ['index', 0], 
          value_vars = list(series_final), 
          var_name = 'Comparators', 
          value_name = 'Best match') 

# matching = matching_df.apply(lambda row: approximate_match(row[0], row['Comparators']), axis = 1) 

    l = [(matching_df[0]), list(matching_df['Comparators'])] 

    ratio = [sm(None, name1, name2) for name1 in l[0] for name2 in l[1]] 

    match = [name2 for name1 in l[0] for name2 in l[1]] 

    print(ratio[:5]) 
    print(match[:5]) 

답변

1

는 당신이 아마 찾고있는 것은 Levenshtein 거리 알고리즘입니다. 한 문자열을 다른 문자열로 변환하는 데 필요한 최소 편집 수를 계산합니다. 이 라이브러리 밖으로

확인 : https://github.com/ztane/python-Levenshtein/

Levenshtein 라이브러리는이 문제와 함께 당신을 도울 수 있도록 설계 StringMatcher.py라는 클래스가 있습니다. https://github.com/gfairchild/pyxDamerauLevenshtein

+0

순서의 정규 이상이 더 효율적입니다 :

이 라이브러리는 또한 유사한 기능을 포함? 내 문제는 실행 시간 대 근사 문자열 일치 기능입니다. – wingsoficarus116

+0

기존 구현의 타이밍을 보지 않고 말하기는 어렵지만 성능이 가장 중요한 경우 두 번째 구현을 벤치마킹하는 것이 좋습니다. Cython으로 작성되었으므로 매우 빠릅니다. pyxDamerauLevenshtein 라이브러리의 벤치 마크는 2 분 동안 약 500k의 비교를 실행합니다. –

+0

크기가 빠르지 만 MS Visual C++를 먼저 설치해야합니까? 일반 pip 설치 명령이 작동하지 않습니다. 죄송합니다. 평범한 질문이지만 권장 사항을 구현하는 것이 좋습니다. – wingsoficarus116