맞춤법 검사기에서 제안을 제공하는 알고리즘은 무엇입니까?


114

단어 제안과 함께 맞춤법 검사기를 구현할 때 일반적으로 사용되는 알고리즘은 무엇입니까?

처음에는 입력 된 각각의 새 단어 (사전에없는 경우)를 사전의 다른 모든 단어와 의 Levenshtein 거리 와 비교하여 상위 결과를 반환하는 것이 합리적이라고 생각했습니다 . 그러나 이것은 전체 사전을 반복적으로 평가해야하는 매우 비효율적 인 것처럼 보입니다.

일반적으로 어떻게 수행됩니까?

답변:


203

피터 노르 빅에 의해 좋은 에세이 맞춤법 교정기를 구현하는 방법은. 기본적으로 주어진 편집 거리로 후보 문자열을 시도하는 무차별 대입 방식입니다. ( 다음Bloom Filter더 빠른 후보 해싱을 사용하여 맞춤법 교정기 성능을 향상시킬 수있는 몇 가지 팁 입니다.)

맞춤법 검사기에 대한 요구 사항이 약합니다. 단어가 사전에 없다는 것을 알아 내면됩니다. Bloom Filter 를 사용하여 더 적은 메모리를 사용하는 맞춤법 검사기를 만들 수 있습니다 . 고대 버전은 영어 사전에 64kb를 사용하여 Jon Bentley의 Programming Pearls 에 설명되어 있습니다.

BK-나무는 다른 접근 방식이다. 여기에 좋은 기사가 있습니다 .

Levenshstein 거리는 맞춤법 검사기의 정확한 편집 거리가 아닙니다. 삽입, 삭제 및 대체 만 알고 있습니다. 조옮김이 누락되어 1 문자의 조옮김에 대해 2가 생성됩니다 (삭제 1 회, 삽입 1 회). Damerau–Levenshtein 거리는 올바른 편집 거리입니다.


2
상대적으로 알려지지 않은 BK- 트리 참조의 경우 +1입니다. 이것이 바로 Google과 같은 회사가 실제 [TM] 양의 데이터로 작업하는 방식입니다.
NoozNooz42 2010

2
여기에 BK-Trees에 대한 더 나은 설명이 있습니다 .
Ian Boyd

17

내가 성공적으로 사용한 제안을 생성하는 방법은 "나쁜"해시 함수를 사용하여 제안을 미리 계산하는 것입니다 (사전을 빌드 할 때).

아이디어는 사람들이 만드는 철자 오류의 유형을 살펴보고 올바른 철자와 동일한 버킷에 잘못된 철자를 할당하는 해시 함수를 설계하는 것입니다.

예를 들어, 일반적인 실수는 definite 대신 definate 와 같이 잘못된 모음을 사용하는 입니다. 따라서 모든 모음을 동일한 문자로 취급하는 해시 함수를 설계합니다. 이를 수행하는 쉬운 방법은 먼저 입력 단어를 "정규화"한 다음 정규화 된 결과를 정규 해시 함수를 통해 입력하는 것입니다. 이 예에서, 정규화 기능은 모든 모음을 드롭 할 수 있으므로 definite이된다 dfnt. 그런 다음 "정규화 된"단어는 일반적인 해시 함수로 해시됩니다.

이 특수 해시 함수를 사용하여 모든 사전 단어를 보조 색인 (해시 테이블)에 삽입합니다. 이 테이블의 버킷은 해시 함수가 "나쁨"이기 때문에 긴 충돌 목록을 가지지 만 이러한 충돌 목록은 본질적으로 미리 계산 된 제안입니다.

이제 맞춤법이 잘못된 단어를 찾으면 맞춤법 오류가 보조 색인에서 매핑되는 버킷의 충돌 목록을 조회합니다. Ta da : 제안 목록이 있습니다! 당신이해야 할 일은 단어의 순위를 매기는 것입니다.

실제로는 전치 문자, 단일 / 이중 문자, 심지어 소리 나는 오타를 포착하기위한 단순한 Soundex와 같은 오류와 같은 다른 유형의 오류를 처리하기 위해 다른 해시 함수가있는 몇 가지 보조 색인이 필요합니다. 실제로 저는 단순한 발음이 먼 길을 가고 있으며 사소한 오타를 찾기 위해 고안된 일부 발음을 본질적으로 쓸모 없게 만드는 것을 발견했습니다.

이제 각 보조 색인에서 맞춤법 오류를 찾아 순위를 매기기 전에 충돌 목록을 연결합니다.

충돌 목록에는 사전에있는 단어 만 포함되어 있습니다. (Peter Norvig 기사에서와 같이) 대체 철자를 생성하려는 접근 방식을 사용하면 먼저 사전에 대해 필터링해야하는 수천 개의 후보를 얻을 수 있습니다. 미리 계산 된 접근 방식을 사용하면 수백 명의 후보를 얻을 수 있으며 모두 올바른 철자임을 알고 있으므로 순위로 바로 건너 뛸 수 있습니다.

업데이트 : 이후 FAROO Distributed Search 라는 유사한 알고리즘 설명을 찾았습니다 . 이것은 여전히 ​​편집 거리가 제한된 검색이지만 사전 계산 단계가 내 "나쁜 해시 함수"아이디어처럼 작동하기 때문에 매우 빠릅니다. FAROO는 잘못된 해시 함수라는 제한된 개념을 사용합니다.


Faroos의 SymSpell 알고리즘을 참조 해 주셔서 감사합니다. 두 알고리즘 모두 가능한 오타를 미리 계산하고 빠른 조회를 위해 해시 테이블을 사용하지만, 주요 차이점은 SymSpell이 특정 편집 거리까지 가능한 모든 맞춤법 오류를 감지한다는 것입니다 (이 점에서 SymSpell은 Peter Norvig의 알고리즘과 동일합니다. 3..6 자릿수 더 빠름), 알고리즘은 이론적으로 가능한 모든 철자 오류의 제한된 하위 집합 만 감지하는 휴리스틱 접근 방식을 사용합니다 (따라서 사전 계산 비용이 더 낮을 수 있음).
Wolf Garbe

SymSpell 알고리즘은 가능한 오타를 명시 적으로 미리 계산하고 저장하지만 내 "나쁜 해시"체계는 그렇지 않습니다. 영어의 경우 많은 영역을 포함하는 단순한 음성 해시 하나만 추가하는 것은 간단합니다 (예 : 편집 거리가 6 인 "terradacktle"-> "pterodactyl"). 물론 다국어 조회가 필요한 경우 훨씬 더 어려울 수 있습니다.
Adrian McCarthy

당연히 오타 가능성에 대한 경험적 지식을 활용하고이를 제한함으로써 사전 계산 시간과 공간을 절약 할 수 있습니다. 그러나 가능한 모든 철자 오류를 다루기 위해 SymSpell은 그 중 극히 일부만 미리 계산하면됩니다. 5 글자 단어에는 최대 편집 거리 3 개 내에서 약 3 백만 개의 맞춤법 오류가있을 수 있지만 SymSpell을 사용하면 25 개의 삭제 만 미리 계산하고 저장하면됩니다. 이것은 경험적 지식이없는 철자 교정 이상의 퍼지 / 유사성 검색에 중요합니다.
Wolf Garbe

7

연산

  1. 철자가 틀린 단어를 입력하십시오.
  2. 빈도와 함께 영어 단어 목록을 텍스트 파일에 저장합니다.
  3. 사용 가능한 모든 영어 단어 (텍스트 파일에 저장 됨)와 빈도 (영어에서 단어가 사용되는 빈도 측정)를 3 항 검색 트리에 삽입합니다.
  4. 이제 삼항 검색 트리를 따라 이동합니다.
    • 삼항 검색 트리에서 발견 된 각 단어에 대해 철자가 잘못된 단어에서 Levensthein Distance를 계산합니다.
    • Levensthein Distance <= 3이면 우선 순위 대기열에 단어를 저장합니다.
    • 두 단어의 편집 거리가 같으면 빈도가 높은 단어가 더 강해집니다. 우선 순위 대기열에서 상위 10 개 항목을 인쇄합니다.

최적화

  1. 현재 단어에서 입력 단어의 하위 문자열 편집 거리가 3보다 크면 현재 노드의 하위 트리에서 단어를 제거 할 수 있습니다.
    github 프로젝트 에서 더 자세한 설명과 소스 코드를 찾을 수 있습니다 .

흠, '강판'이 사전 단어이기 때문에이 경우 '강판'에서 '더 큰'까지의 Levenshtein 거리는 충분하지 않습니다. ;-)
Tony Brasunas 2017-06-07

1
@TonyBrasunas, 네, 맞아요. 그러나 프로그램은 실제로 'grater'의 경우 10 단어 목록을 입력으로 반환하고 편집 거리가 0 인 'grater'와 편집 거리가 1 인 'greater'를 제안합니다. 도움이 될 수 있습니다. )
amarjeetAnand

한 후보의 거리가 2이지만 매우 빈번하고 다른 후보의 거리가 1이지만 매우 드문 경우 두 후보의 순위를 어떻게 매깁니까? 위의 접근 방식에서 희귀 아이템이 항상 이길 것입니다. 이것이 올바른 결과입니까?
speedplane

@speedplane 예. 희귀 한 사람이 이길 것입니다. 그리고 나는 그것이 올바른 결과라고 생각합니다. 입력 단어의 철자를 기준으로 우리가 기대하는 것이 가장 가까운 단어이기 때문입니다. 여전히 의심 스러우면 이런 식으로 생각하십시오 --- 사용자가 올바르게 입력 한 드문 단어가 있다고 가정하십시오. 이제 거리는 0이지만 주파수는 매우 낮습니다. 이제 제안에서이 희귀 한 단어 (거리 0)를 맨 위에 (최소한 편집 거리가 이기기 때문에) 나열하고 다른 단어는 거리 1-2-3, 아래에 나열해야합니다.
amarjeetAnand

3

사전의 각 단어에 대한 정확한 편집 거리를 알 필요는 없습니다. 한계 값에 도달 한 후 알고리즘을 중지하고 단어를 제외 할 수 있습니다. 이렇게하면 많은 컴퓨팅 시간을 절약 할 수 있습니다.


1

맞춤법 검사기는 Unix 맞춤법 프로그램 에서처럼 구현하기가 매우 쉽습니다. 소스 코드는 공개적으로 사용할 수 있습니다. 수정이 포함될 수 있습니다. 한 가지 기술은 편집을 수행하고이 새 단어가 사전에 있는지 다시 확인하는 것입니다. 이러한 새로운 편집 내용을 그룹화하여 사용자에게 표시 할 수 있습니다.

Unix 시스템은 Mc IllRoy가 작성한 프로그램을 사용합니다. 다른 방법은 대용량 파일의 경우 유용 할 수있는 Trie를 사용하는 것입니다.

유닉스 접근 방식은 분산 해시 알고리즘을 사용하기 때문에 거대한 사전에 대해 매우 적은 공간이 필요합니다.

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