С тех пор, как я начал изучать машинное обучение, я могу сказать, что НЛП (обработка естественного языка) было самым сложным для меня предметом для понимания. Я обнаружил, что лучший способ изучить это — понять как можно больше, а затем сразу погрузиться в пример. Итак, я попытался решить простую задачу НЛП, сделав все с нуля. Потому что я считаю, что библиотеки не так полезны, как мы думаем.

Ссылка GitHub на код

Проблема, которую я решил решить

Орфографическая ошибка — это проблема, с которой знакомо большинство из нас. Поскольку я знаю проблему наизусть, я решил выбрать ее.

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

Чтобы узнать, как должна работать эта функция, я прочитал о том, как люди понимают слова. Мы читаем только начальные и конечные буквы слов. Порядок букв в середине не имеет большого значения.

Мы могли бы проверить, совпадают ли первая и конечная буквы двух слов. Но измерение средних слов — болезненная часть. Мне нужно было найти способ проверить, похожи ли средние буквы, не завися от порядка. Для этого я использовал простые числа.

Простые числа — это уникальные числа для процесса деления. Они могут делиться только сами по себе или на 1. Эта ситуация создает возможность найти список чисел, не завися от их порядка, что подходит для решения нашей задачи НЛП.

Время спроектировать систему и запрограммировать ее

Ссылка GitHub на код

Во-первых, простые числа будут импортированы из текстового файла. Затем строка простых чисел будет организована и преобразована в массив Numpy целочисленного типа путем сортировки по возрастанию.

import numpy as np #import numpy module
with open(“.../primeNumbers.txt”, “r”) as txtfile:#open text file
   txtString = txtfile.read()#read text file
   txtfile.close()#close text file
txtSplitString = txtString.split()#Split string
primeNumbers = np.asarray(txtSplitString).astype(int)#convert to integer type numpy array
primeNumbers = sorted(primeNumbers)#sort the numpy array

Затем мы создадим список, содержащий алфавит английского языка.

letters = np.array([“a”,”b”,”c”,”d”,”e”,”f”,”g”,”h”,”i”,”j”,”k”,”l”,”m”,”n”,”o”,”p”,”q”,”r”,”s”,”t”,”u”,”v”,”w”,”x”,”y”,”z”])

Затем мы создадим словарь Python, который сопоставляет буквы простым числам.

myDict = {letters[cnt]:primeNumbers[cnt] for cnt in range(len(letters))}

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

def word2Prime(word1,myDict):
   base = 1
   baseList = []
   cnt = 0
   for letter in word1:
      if cnt == 0:
         baseList.append(myDict[letter])
      elif cnt == len(word1)-1:
         baseList.append(myDict[letter])
      else:
         base= base*myDict[letter]
      cnt = cnt+1
   baseList.append(base1)
   return baseList

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

def findFactors(x,pnl):
   #This function takes a number and prints the factors. Biggest factor can be 101(26th prime number)
   factors = []
   for i in pnl:
      if x % i == 0 and i<102:
         factors.append(i)
   return factors
def measureSimilary(word1,word2,pnl):
   mv = 0
   if word1[0] == word2[0]:#if first letters of test words are similar, then add 0.25 to matching score.
      mv = mv + 0.25
   if word1[1] == word2[1]:#if end letters of test words are similar, then add 0.25 to matching score.
      mv = mv + 0.25
 
   facts = findFactors(word2[2],pnl)#find factors of the multiplication of prime number version of middle letters.
 
   foundFacts = []
   for fact in facts:
      if word1[2]%fact == 0:# if the word1’s middle letters' prime number multiplication can be divided by the factors of word2’s middle letters' prime number multiplication, then append the relevant factor to foundFacts.
         foundFacts.append(fact)
   #Find the ratio between length of foundFacts of word1 and factors of word2. Multiply the calculated ratio by weight 0.5 .
   mv = mv+((len(foundFacts)+0.01)/(len(facts)+0.01))*0.50
   return mv

Давайте протестируем код:

word1 = “mostly”
word2 = “mistlt”
word3 = “likely”
baseList = []
baseList.append(word2Prime(word1,myDict))
baseList.append(word2Prime(word2,myDict))
baseList.append(word2Prime(word3,myDict))
print(word1,word2,measureSimilary(baseList[0],baseList[1],pnl))
print(word2,word3,measureSimilary(baseList[1],baseList[2],pnl))
print(word1,word3,measureSimilary(baseList[0],baseList[2],pnl))

Результаты:

word1: mostly , word2: mistlt 
Matching Result: 0.6253117206982544

word2: mistlt , word3: likely 
Matching Result: 0.2506234413965087

word1: mostly , word3: likely 
Matching Result: 0.25124688279301743

Ссылка GitHub на код

Вывод:

С помощью функции измерения соответствия, созданной выше, мы можем найти правильную версию слова, которое мы неправильно написали. Например, когда вы разговариваете со своим другом в приложении для обмена сообщениями, вы можете написать «mistlt» вместо «в основном». Используя приведенное выше измерение соответствия и некоторые алгоритмы поиска, вы можете найти правильную версию слова «в основном».

Использование функции сопоставления измерений для исправления орфографических ошибок:

Я собираюсь использовать функцию измерения соответствия, чтобы исправить Text-1.

Текст-1: «Применительно к исследованию и в начальных точках, это не имеет значения в том, что происходит в мире, а только в том, что первое и последнее должны быть в правильном месте. Установка может быть полной, и вы можете оставить ее без изменений. Это связано с тем, что люди не искажаются истлефом, а рождаются как живые существа».

Я буду использовать исправленную версию текста, чтобы иметь правильный словарь слов.

Text-2 = «По словам исследователя из Кембриджского университета, не имеет значения, в каком порядке стоят буквы в слове, важно лишь то, чтобы первая и последняя буквы были на нужном месте. Остальное может быть полным беспорядком, и вы все равно можете прочитать его без проблем. Это потому, что человеческий разум читает не каждую букву отдельно, а слово в целом».

Во-первых, давайте очистим наши текстовые данные и извлечем слова.

text1 = text1.replace(“,”,””)
text2 = text2.replace(“,”,””)
text1 = text1.replace(“.”,””)
text2 = text2.replace(“.”,””)
text1S = text1.split()
text2S = text2.split()

Затем давайте измерим значение соответствия между каждым словом в text1S и text2S и добавим совпадающие значения в CorrectList.

pnl = primeNumbers[0:26] #This is necessary to measure similarity, check the explanation above.
correctionList = []
for elm1 in text1S:
   correctionList.append([])
   for elm2 in text2S:
      #print(elm1, elm2)
      if len(elm1)>3 and len(elm2)>3:
      elm1L = all2lowercase(elm1)
      elm1Prime = word2Prime(elm1L,myDict)
      elm2L = all2lowercase(elm2)
      elm2Prime = word2Prime(elm2L,myDict)
      mv = measureSimilary(elm1Prime,elm2Prime,pnl)
      if mv>0.5:
         print(“The word -{}- and -{}- are alike with value {}.”.format(elm1,elm2,mv))
      correctionList[-1].append([elm1,elm2,mv])

Теперь давайте отсортируем каждый список в correctList. Это делается для того, чтобы получить наибольшее количество совпадений для каждого сравниваемого слова.

for cnt in range(len(correctionList)):
   correctionList[cnt] = sorted(correctionList[cnt],key=lambda column:column[2], reverse=True)

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

for cnt in range(len(correctionList)):
   if len(correctionList[cnt])>0:
      text1 = text1.replace(correctionList[cnt][0][0],correctionList[cnt][0][1])

Ссылка GitHub на код

Ввод кода:

Text-1: “Aoccdrnig to a rscheearch and at Cmabrigde Uinervtisy, it deos not mttaer in waht oredr the ltteers in a wrod are, the olny iprmoetnt tihng is taht the frist and lsat ltteer be at the rghit pclae. The rset can be a toatl mses and you can sitll raed it wouthit porbelm. Tihs is bcuseae the huamn mnid deos not raed ervey lteter by istlef, but the wrod as a wlohe.”
Text-2 = “According to a researcher at Cambridge University, it does not matter in what order the letters in a word are, the only important thing is that the first and last letter be at the right place. The rest can be a total mess and you can still read it without problem. This is because the human mind does not read every letter by itself but the word as a whole.”

Вывод кода:

Text-1 = “According to a researcher at Cambridge University, it does not matter in what order the letters in a word are, the only important thing is that the first and last letter be at the right place. The rest can be a total mess and you can still read it without problem. This is because the human mind does not read every letter by itself but the word as a whole.”