문자열 유사성에 가장 적합한 알고리즘은 무엇입니까?


23

주소를 기반으로 다양한 웹 페이지의 콘텐츠를 고유하게 식별하는 플러그인을 설계하고 있습니다.

따라서 다음과 같은 하나의 주소가있을 수 있습니다.

1 someawesome street, anytown, F100 211

나중에이 주소를 약간 다른 형식으로 찾을 수 있습니다.

1 someawesome street, F100 211,

또는 아마도 모호한

someawesome street F100

이들은 기술적으로 동일한 주소이지만 유사성 수준입니다. a) 각 주소에 대해 고유 한 식별자를 생성하여 조회를 수행하고 b) 매우 유사한 주소가 표시되는시기를 파악하고 싶습니다.

어떤 알고리즘 / 기술 / 문자열 메트릭을보고해야합니까? 레 벤슈 테인 거리는 명백한 선택처럼 보이지만 여기에 적합한 다른 접근법이 있다면 궁금합니다.


"레 븐슈 테인 거리"는 알고리즘이 아닙니다.
gnasher729

기본적인 파싱을 소개하지 않는 한, 레벤 슈타인 원시 거리는 그리 좋지 않을 것입니다. 거리, 도시 이름 등이 될 수있는 단어와 거리 번호 또는 우편 번호가 될 수있는 단어를 식별해야합니다. 그런 다음 실제 장소 / 거리 이름으로 공급되는 통계적 퍼지 매처와 함께 이것에 Levenstein을 적용 할 수 있습니다. 쉬운 일이 아님 :)

7
@gnasher :하지만 Levenshtein 거리를 계산하는 함수 알고리즘이. 그러한 기능이 없다면, 레 벤슈 테인 거리는 단지 지적 호기심 일뿐입니다.
Robert Harvey

나는 algortihms의 비교 예제에서 매우 실용적인 설명을 찾았습니다 . 결론적 으로 Levenstein의 알고리즘이 문자열의 길이에 따라 Jaro-Winkler 유사성 을 사용하는 것이 좋습니다 . 따라서 비교하는 것은 유용하지 않습니다.
Sandra Meneses

답변:


14

Levenstein의 알고리즘 은 문자열의 삽입, 삭제 및 대체 수를 기반으로합니다.

불행히도 2 개의 문자 (예 : somesome 대 vsaewsome)를 바꾼 일반적인 철자법을 고려하지 않습니다. 따라서보다 강력한 Damerau-Levenstein 알고리즘을 선호합니다 .

문자열의 길이와 비교하여 시간이 갑자기 증가하기 때문에 전체 문자열에 거리를 적용하는 것이 좋지 않다고 생각합니다. 그러나 ZIP과 같은 주소 구성 요소가 제거되면 완전히 다른 주소가 더 잘 일치 할 수 있습니다 ( 온라인 Levenshtein 계산기를 사용하여 측정 ).

1 someawesome street, anytown, F100 211       (reference) 
1 someawesome st.,anytown                     (difference of 15, same address)     
1 otherplaces street,anytown,F100211          (difference of 13, different ddress) 
1 sameawesome street, othertown, CA98200      (difference of 13, different ddress)
anytown, 1 someawesome street                 (28 different same address)
anytown, F100 211, 1 someawesome street       (37 different same address)

이 효과는 거리 이름이 짧을수록 악화되는 경향이 있습니다.

따라서 더 똑똑한 알고리즘을 사용하는 것이 좋습니다. 예를 들어 Arthur Ratz는 CodeProject 에 스마트 텍스트 비교 알고리즘을 게시했습니다 . 이 알고리즘은 거리를 출력하지 않지만 (따라서 풍부하게 할 수는 있지만) 텍스트 블록 이동과 같은 어려운 것들을 식별합니다 (예 : 첫 번째 예제와 마지막 예제 사이의 도시와 거리 사이의 스왑).

그러한 알고리즘이 귀하의 경우에 너무 일반적인 경우 실제로 구성 요소별로 작업하고 비교 가능한 구성 요소 만 비교해야합니다. 세계의 주소 형식을 구문 분석하려는 경우 쉽지 않습니다. 그러나 목표가 좀 더 구체적이라면, 미국은 분명히 실현 가능하다. 예를 들어 "street", "st.", "place", "plazza"및 일반적인 철자가 틀린 주소는 주소의 거리 부분을 나타낼 수 있으며, 그 주요 부분은 원칙적으로 숫자입니다. 우편 번호는 도시를 찾는 데 도움이되거나 주소의 마지막 요소 일 수 있습니다. 또는 추측이 마음에 들지 않으면 도시 이름 목록을 찾을 수 있습니다 (예 : 무료 우편 번호 데이터베이스 다운로드). 그런 다음 Damerau-Levenshtein을 관련 부품에만 적용 할 수 있습니다.


비교하기 전에 두 비교 문자열을 정렬하는 것은 어떻습니까? 나는 이것이 전치에 도움이 될 수 있음을 발견했다.
openwonk


1

첫째, 당신은 주소에 대한 웹 페이지를 구문 분석해야합니다, RegEx는 하나 작성해야하지만 RegEx를 사용하여 주소를 구문 분석하는 것은 매우 어려울 수 있습니다. 잠재적 인 주소 지정 형식 목록과 일치하는 하나 이상의 표현식을 검토해야 할 수도 있습니다. 주소 구문 분석에 익숙하지는 않지만 비슷한 생각을 따르는이 질문을 살펴 보는 것이 좋습니다 . 자유형 텍스트의 일반 주소 구문 분석기.

레 벤슈 테인 거리는 유용하지만 주소를 부분으로 분리 한 후에 만 ​​가능합니다. 다음 주소를 고려하십시오. 123 someawesome st.그리고 124 someawesome st.이 주소는 완전히 다른 위치는, 그러나 그들의 Levenshtein 거리 만이 또한 같은에 적용 할 수있는 1입니다 8th st.9th st.일반적으로 동일한 웹 페이지에 표시되지 않습니다 유사 거리 이름하지만 전례가 아니다. 예를 들어 학교의 웹 페이지에는 길 건너 도서관의 주소가 있거나 몇 블록 떨어진 교회가있을 수 있습니다. 이는 레 벤슈 테인 거리를 쉽게 사용할 수있는 유일한 데이터는 거리와 도시 사이의 거리와 같은 두 데이터 포인트 사이의 거리입니다.

다른 필드를 분리하는 방법을 알아내는 한, 주소 자체를 얻은 후에는 매우 간단합니다. 고맙게도 대부분의 주소는 매우 구체적인 형식으로되어 있으며 약간의 RegEx 마법사를 사용하여 다른 데이터 필드로 분리 할 수 ​​있어야합니다. 주소의 형식이 잘못 되었더라도 여전히 희망이 있습니다. 주소는 항상 (거의) 순서대로 따릅니다. 귀하의 주소는 제공되는 정보의 양과 그 정보에 따라 다음과 같은 선형 그리드에 있어야합니다.

StreetNumber < Street < City < State < Country

주소가 한 필드에서 인접하지 않은 필드로 건너 뛰는 경우는 거의 없습니다. Street, Country 또는 StreetNumber, City를 자주 볼 수는 없습니다.


2
주소는 규칙적이지 않으며 정규식으로 확실하게 구문 분석 할 수 없습니다. 자유 텍스트에 포함되어 있으면 정확하게 식별 할 수 없습니다. 물론 찾고있는 곳을 이미 알고 있다면 다른 일반적인 형식에 맞게 몇 가지 정규 표현식을 작성할 수 있습니다.
쓸모없는

@ 쓸모없는 사실입니다. 이론적으로는 가능하지만, 그 작업에 필요한 작업량을 과소 평가했습니다. 특히 사용 가능한 더 나은 옵션이있을 때. 이것을 반영하기 위해 답변을 수정했습니다.
Ucenna

1

문자열 유사성 알고리즘에 대해 질문하지만 문자열은 주소입니다. Google 지역 정보 검색 과 같은 위치 API에 주소를 제출하고 formatted_address비교 지점으로 사용합니다 . 그것은 가장 정확한 접근법처럼 보입니다.

API를 통해 찾을 수없는 주소 문자열의 경우 유사성 알고리즘으로 대체 할 수 있습니다.


1
+1 아웃소싱하여 전문가의 힘으로 작업을 수행하십시오. 몇몇 서비스 제공 업체가 있으므로 Google이 아니어도됩니다. 주소 일치가 핵심 비즈니스가 아닌 한 시간을 낭비하지 마십시오.
LoztInSpace

0

유용하지만 사전 답변의 사전 설정 데이터베이스가 필요한 멋진 알고리즘을 선 편집 거리라고합니다.

함수로서 라인 편집 거리는 "두 단어가 얼마나 다른가?"를 되돌릴 수 있습니다.

"dogma"및 "dog"과 같은 단어는 3 (추가 문자 3 개)의 값을 다시 얻습니다.

또는 "cat"과 "hat"은 1의 값을 반환합니다 (하나의 다른 문자에 대해).

(출처 : https://en.wikipedia.org/wiki/Edit_distance )


2
OP가 언급 한 Levensthtein에 비해 장점은 무엇입니까?
Christophe

-1

실제로 일부 거리 기능을 사용하는 것이 좋은 접근법처럼 보입니다. 그러나 문제는 주어진 주소에서 가장 가까운 문자열을 찾는 것입니다.

여기서는 광범위한 범주의 알고리즘을 설명합니다. 가장 가까운 이웃 검색 확인

의견에서 언급했듯이 주소의 구성 요소 (거리 이름, 번호 등)를 분리하는 방법을 찾으면 작업이 훨씬 쉬워집니다.


-1

(Apache commons-text의) LongestCommonSubsequence는 주소를 사용해 보는 또 다른 방법이 될 수 있습니다. " 공통 서브 시퀀스 길이 / 최대 (주소 길이) "의 비율로 2의 유사성을 정의 하면 공차 임계 값 (예 : 일치 / 없음을 정의하는 0.8)을 적용 할 수 있습니다. 이렇게하면 " 1 someawesome st., anytown "및 " 1 someawesome street., anytown " 과 같은 주소를 일치시킬 수 있습니다 .

초고속 알고리즘이 아니므로 비교를 최소화하기 위해 빠른 장애 복구를 적용 할 수 있습니다. 우편 번호가 일치하지 않거나 추출 된 숫자 만 순서가 다른 경우 비교를 피하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.