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

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

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

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



답변

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

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

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

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


답변

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

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

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

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

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

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

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

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

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


답변

연산

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

최적화

  1. 현재 단어에서 입력 단어의 하위 문자열 편집 거리가 3보다 크면 현재 노드의 하위 트리에서 단어를 제거 할 수 있습니다.

    github 프로젝트
    에서 더 자세한 설명과 소스 코드를 찾을 수 있습니다 .


답변

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


답변

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

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

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


답변