Создайте пользовательскую функцию коррекции орфографии с помощью Edit Distance Searchers

Этот пример показывает, как исправить орфографию, используя искатели расстояния редактирования и словарь известных слов.

Лемматизация с normalizeWords и word2vec требует правильно написанных слов для работы. Чтобы легко исправить написание слов в тексте, используйте correctSpelling функция. Чтобы узнать, как создать функцию коррекции орфографии с нуля с помощью редактирующих искателей расстояния, используйте этот пример в качестве руководства.

Если у вас есть слова с опечатками в наборе текста, то можно использовать искатели расстояния для редактирования, чтобы найти самые близкие правильно написанные слова к данному словарю. Чтобы исправить написание опечатков слов в документах, замените их ближайшими соседями по словарю. Используйте искатели расстояния редактирования, чтобы найти самое близкое правильно написанное слово для слов с опечатками в соответствии с расстоянием редактирования. Для примера количество смежных свопов графемы и вставок графемы, удалений и замен.

Загрузка данных

Создайте словарь известных слов. Загрузите и извлеките ориентированные списки слов проверки орфографии (SCOWL) из https://sourceforge.net/projects/wordlist/ в папку в директории current. Импортируйте слова из загруженных данных с помощью вспомогательной функции scowlWordList.

folderName = "scowl-2019.10.06";
maxSize = 60;
vocabulary = scowlWordList(folderName,'english',maxSize);

Просмотрите количество слов в словаре.

numWords = numel(vocabulary)
numWords = 98213

Создайте простой корректор орфографии

Используя импортированный словарь, создайте средство поиска расстояния редактирования с максимальным расстоянием 2. Для получения лучших результатов допустим смежные свопы графемы путем установки 'SwapCost' опция 1. Для больших словарей это может занять несколько минут.

maxDist = 2;
eds = editDistanceSearcher(vocabulary,maxDist,'SwapCost',1);

Этот искатель расстояния редактирования чувствителен к регистру, что означает, что изменение регистра символов способствует расстоянию редактирования. Например, средство поиска может найти соседнее «тестирование» для слова «цетинг», потому что оно имеет расстояние редактирования 1 (один своп), но не от слова «TSeTiNG», потому что оно имеет расстояние редактирования 6.

Правильное написание

Исправьте написание слов с опечатками в массиве токенизованных документов, выбрав слова с опечатками и найдя ближайших соседей в средстве поиска расстояния редактирования.

Создайте токенизованный объект документа, содержащий опечатки и орфографические ошибки.

str = "An exmaple dccoument with typos and averyunusualword.";
document = tokenizedDocument(str)
document = 
  tokenizedDocument:

   8 tokens: An exmaple dccoument with typos and averyunusualword .

Преобразуйте документы в строковые массивы слов с помощью строковой функции.

words = string(document)
words = 1×8 string
    "An"    "exmaple"    "dccoument"    "with"    "typos"    "and"    "averyunusualword"    "."

Найдите слова, которые нуждаются в коррекции. Чтобы игнорировать слова, которые правильно написаны, найдите индексы слов уже в словаре. Чтобы игнорировать пунктуацию и сложные лексемы, такие как адреса электронной почты, найдите индексы слов, которые не имеют типов лексем «letters» или «other». Получите сведения о лексеме из документа с помощью tokenDetails функция.

tdetails = tokenDetails(document);
idxVocabularyWords = ismember(tdetails.Token,eds.Vocabulary);

idxComplexTokens = ...
    tdetails.Type ~= "letters" & ...
    tdetails.Type ~= "other";

idxWordsToCheck = ...
    ~idxVocabularyWords & ...
    ~idxComplexTokens
idxWordsToCheck = 8×1 logical array

   1
   1
   1
   0
   0
   0
   1
   0

Найдите числовые индексы слов и посмотрите соответствующие слова.

idxWordsToCheck = find(idxWordsToCheck)
idxWordsToCheck = 4×1

     1
     2
     3
     7

wordsToCheck = words(idxWordsToCheck)
wordsToCheck = 1×4 string
    "An"    "exmaple"    "dccoument"    "averyunusualword"

Заметьте, что слово «An» помечено как слово для проверки. Это слово помечено, потому что словарь не содержит слова «An» с верхним регистром «A». В более позднем разделе примера показано, как создать корректор орфографии без учета регистра.

Найти ближайшие слова и их расстояния можно используя knnsearch функция с поиском расстояния редактирования.

[idxNearestWords,d] = knnsearch(eds,wordsToCheck)
idxNearestWords = 4×1

         165
        1353
        1152
         NaN

d = 4×1

     1
     1
     2
   Inf

Если какое-либо из слов не найдено в поисковике, то функция возвращает индекс NaN с Inf расстояния. Слово «averyunusualword» не имеет соответствия в пределах расстояния редактирования 2, поэтому функция возвращает индекс NaN для этого слова.

Найдите индексы слов с положительными конечными расстояниями редактирования.

idxMatches = ~isnan(idxNearestWords)
idxMatches = 4×1 logical array

   1
   1
   1
   0

Получите индексы слов с совпадениями в поисковике и посмотрите соответствующие исправленные слова в словаре.

idxCorrectedWords = idxNearestWords(idxMatches)
idxCorrectedWords = 3×1

         165
        1353
        1152

correctedWords = eds.Vocabulary(idxCorrectedWords)
correctedWords = 1×3 string
    "an"    "example"    "document"

Замените опечатки слов, которые совпадают с исправленными словами.

idxToCorrect = idxWordsToCheck(idxMatches);
words(idxToCorrect) = correctedWords
words = 1×8 string
    "an"    "example"    "document"    "with"    "typos"    "and"    "averyunusualword"    "."

Чтобы создать токенизированный документ из этих слов, используйте tokenizedDocument функцию и задать 'TokenizedMethod' на 'none'.

document = tokenizedDocument(words,'TokenizeMethod','none')
document = 
  tokenizedDocument:

   8 tokens: an example document with typos and averyunusualword .

В следующем разделе показано, как исправить орфографию сразу нескольких документов, создав пользовательскую функцию коррекции орфографии и используя docfun.

Создайте функцию коррекции орфографии

Чтобы исправить орфографию сразу в нескольких документах, создайте пользовательскую функцию с помощью кода из предыдущего раздела и используйте эту функцию с docfun функция.

Создайте функцию, которая принимает искатель расстояния редактирования, строковые массивы слов и соответствующую таблицу деталей токена в качестве входов и выводит исправленные слова. The correctSpelling функция, перечисленная в конце примера, исправляет написание в строковые массивы слов, используя соответствующие детали лексемы и средство поиска расстояния редактирования.

Чтобы использовать эту функцию с docfun function, создать указатель на функцию, который принимает в качестве входов строковые массивы слов и соответствующую таблицу подробных данных маркера.

func = @(words,tdetails) correctSpelling(eds,words,tdetails);

Исправьте написание массива токенизированных документов с помощью docfun с помощью указателя на функцию func.

str = [
    "Here is some reallyu badly wrirten texct."
    "Some moree mitsakes here too."];
documents = tokenizedDocument(str);
updatedDocuments = docfun(func,documents)
updatedDocuments = 
  2×1 tokenizedDocument:

    8 tokens: here is some really badly written text .
    6 tokens: come more mistakes here too .

Обратите внимание, что верхние символы могут быть исправлены на различные строчные символы. Например, слово «Некоторые» может быть исправлено, чтобы «прийти». Если несколько слов в словаре искателя расстояния редактирования имеют одинаковое расстояние редактирования к входу, то функция выводит первый найденный результат. Для примера слова «приходят» и «некоторые» имеют расстояние 1 редактирования от слова «некоторые».

В следующем разделе показано, как создать корректор орфографии, который не чувствителен к регистру.

Создайте корректор орфографии без учета регистра

Чтобы предотвратить различия в конфликтах случаев с другими заменами, создайте искатель расстояния редактирования со словарем в нижнем регистре и преобразуйте документы в строчные перед использованием искателя расстояния редактирования.

Преобразуйте словарь в строчный. Эта операция может ввести повторяющиеся слова, удалить их, взяв только уникальные значения.

vocabularyLower = lower(vocabulary);
vocabularyLower = unique(vocabularyLower);

Создайте средство поиска расстояния редактирования с помощью строчного словаря с помощью тех же опций, что и ранее. Это может занять несколько минут.

maxDist = 2;
eds = editDistanceSearcher(vocabularyLower,maxDist,'SwapCost',1);

Используйте средство поиска расстояния редактирования, чтобы исправить написание слов в токенизованном документе. Чтобы использовать корректор орфографии без учета регистра, преобразуйте документы в строчные.

documentsLower = lower(documents);

Исправьте орфографию с помощью нового искателя расстояния редактирования, используя те же шаги, что и ранее.

func = @(words,tdetails) correctSpelling(eds,words,tdetails);
updatedDocuments = docfun(func,documentsLower)
updatedDocuments = 
  2×1 tokenizedDocument:

    8 tokens: here is some really badly written text .
    6 tokens: some more mistakes here too .

Здесь слово «Some» в исходном тексте преобразуется в «some» перед введением в корректор орфографии. Соответствующее слово «some» не затронуто поисковиком, поскольку слово some встречается в словаре.

Функция коррекции орфографии

The correctSpelling функция исправляет орфографию в строковые массивы слов, используя соответствующие детали лексемы и средство поиска расстояния редактирования. Вы можете использовать эту функцию с docfun исправить написание нескольких документов сразу.

function words = correctSpelling(eds,words,tdetails)

% Get indices of misspelled words ignoring complex tokens.
idxVocabularyWords = ismember(tdetails.Token,eds.Vocabulary);

idxComplexTokens = ...
    tdetails.Type ~= "letters" & ...
    tdetails.Type ~= "other";

idxWordsToCheck = ...
    ~idxVocabularyWords & ...
    ~idxComplexTokens;

% Convert to numeric indices.
idxWordsToCheck = find(idxWordsToCheck);

% Find nearest words.
wordsToCheck = words(idxWordsToCheck);
idxNearestWords = knnsearch(eds,wordsToCheck);

% Find words with matches.
idxMatches = ~isnan(idxNearestWords);

% Get corrected words.
idxCorrectedWords = idxNearestWords(idxMatches);
correctedWords = eds.Vocabulary(idxCorrectedWords);

% Correct words.
idxToCorrect = idxWordsToCheck(idxMatches);
words(idxToCorrect) = correctedWords;

end

См. также

| | | | | |

Похожие темы