首頁  >  文章  >  科技週邊  >  使用馬可夫鏈建立文字產生器

使用馬可夫鏈建立文字產生器

WBOY
WBOY轉載
2023-04-09 22:11:221202瀏覽

本文中將介紹一個流行的機器學習專案-文字產生器,你將了解如何建立文字產生器,並了解如何實作馬可夫鏈以實現更快的預測模型。

使用馬可夫鏈建立文字產生器

文字產生器簡介

文字生成在各行業都很受歡迎,特別是在行動、應用和資料科學領域。甚至新聞界也使用文字生成來輔助寫作過程。

在日常生活中都會接觸到一些文字生成技術,文字補全、搜尋建議,Smart Compose,聊天機器人都是應用的例子,

本文將使用馬可夫鏈構建一個文字產生器。這將是一個基於字元的模型,它接受鏈的前一個字元並產生序列中的下一個字母。

透過使用範例單字訓練我們的程序,文字產生器將學習常見的字元順序模式。然後,文字產生器將把這些模式應用到輸入,即一個不完整的單字,並輸出完成該單字的機率最高的字元。

使用馬可夫鏈建立文字產生器

文字產生是自然語言處理的一個分支,它根據先前觀察到的語言模式預測並產生下一個字元。

在沒有機器學習之前,NLP是透過建立一個包含英文中所有單字的表,並將傳遞的字串與現有的單字配對來進行文字產生的。這種方法有兩個問題。

  • 搜尋成千上萬個單字會非常慢。
  • 生成器只能補全它以前見過​​的單字。

機器學習和深度學習的出現,使得NLP允許我們大幅減少運行時並增加通用性,因為生成器可以完成它以前從未遇到過的單字。如果需要NLP可以擴展到預測單字、片語或句子!

對於這個項目,我們將專門使用馬可夫鏈來完成。馬可夫過程是許多涉及書面語言和模擬複雜分佈樣本的自然語言處理項目的基礎。

馬可夫過程是非常強大的,以至於它們只需要一個範例文件就可以用來產生表面上看起來真實的文字。

什麼是馬可夫鏈?

馬可夫鍊是一種隨機過程,它為一系列事件建模,其中每個事件的機率取決於前一個事件的狀態。模型有一組有限的狀態,從一個狀態移動到另一個狀態的條件機率是固定的。

每次轉移的機率只取決於模型的前一個狀態,而不是事件的整個歷史。

例如,假設想要建立一個馬可夫鏈模型來預測天氣。

在這個模型中我們有兩種狀態,晴天或雨天。如果我們今天一直處於晴朗的狀態,明天就有更高的機率(70%)是晴天。雨也是如此;如果已經下過雨,很可能還會繼續下雨。

但是天氣會改變狀態是有可能的(30%),所以我們也將其包含在我們的馬可夫鏈模型中。

使用馬可夫鏈建立文字產生器

馬可夫鍊是我們這個文字產生器的完美模型,因為我們的模型將只使用前一個字元預測下一個字元。使用馬可夫鏈的優點是,它是準確的,記憶體少(只儲存1個以前的狀態)並且執行速度快。

文字產生的實作

這裡將透過6個步驟完成文字產生器:

  1. 產生查找表:建立表來記錄詞頻
  2. 將頻率轉換為機率:將我們的發現轉換為可用的形式
  3. 載入資料集:載入並利用一個訓練集
  4. 建立馬可夫鏈:使用機率為每個單字和字元創建鏈
  5. 對資料進行採樣:創建一個函數對語料庫的各個部分進行採樣
  6. #生成文本:測試我們的模型

使用馬可夫鏈建立文字產生器

1、產生查找表

首先,我們將建立一個表,記錄訓練語料庫中每個字元狀態的出現。從訓練語料庫中保存最後的' K '字符和' K 1 '字符,並將它們保存在一個查找表中。

例如,想像我們的訓練語料庫包含,「the man was, they, then, the, the」。那麼單字的出現次數為:

  • 「the」 — 3
  • 「then」 — 1
  • 「they」 — 1
  • 「 man” — 1

下面是查找表中的結果:

使用馬可夫鏈建立文字產生器

在上面的例子中,我們取K = 3,表示將一次考慮3個字符,並將下一個字符(K 1)作為輸出字符。在上面的查找表中將單字(X)作為字符,將輸出字符(Y)作為單個空格(" "),因為第一個the後面沒有單字了。另外也計算了這個序列在資料集中出現的次數,在本例中為3次。

這樣就產生了語料庫中的每個單字的數據,也就是產生所有可能的X和Y對。

下面是我們如何在程式碼中產生查找表:

 def generateTable(data,k=4):
 
 T = {}
for i in range(len(data)-k):
X = data[i:i+k]
Y = data[i+k]
#print("X %s and Y %s "%(X,Y))
if T.get(X) is None:
T[X] = {}
T[X][Y] = 1
else:
if T[X].get(Y) is None:
T[X][Y] = 1
else:
T[X][Y] += 1
return T
 T = generateTable("hello hello helli")
 print(T)
 
 #{'llo ': {'h': 2}, 'ello': {' ': 2}, 'o he': {'l': 2}, 'lo h': {'e': 2}, 'hell': {'i': 1, 'o': 2}, ' hel': {'l': 2}}

程式碼的簡單解釋:

在第3行,建立了一個字典,它將儲存X及其對應的Y和頻率值。第9行到第17行,檢查X和Y的出現情況,如果查找字典中已經有X和Y對,那麼只需增加1。

2、將頻率轉換為機率

一旦我們有了這個表和出現的次數,就可以得到在給定x出現之後出現Y的機率。公式是:

使用馬可夫鏈建立文字產生器

例如如果X = the, Y = n,我們的公式是這樣的:

當X =the時Y = n的頻率:2,表中總頻率:8,因此:P = 2/8= 0.125= 12.5%

以下是我們如何應用這個公式將查找表轉換為馬爾科夫鏈可用的機率:

 def convertFreqIntoProb(T):
for kx in T.keys():
s = float(sum(T[kx].values()))
for k in T[kx].keys():
T[kx][k] = T[kx][k]/s
 
return T
 
 T = convertFreqIntoProb(T)
 print(T)
 #{'llo ': {'h': 1.0}, 'ello': {' ': 1.0}, 'o he': {'l': 1.0}, 'lo h': {'e': 1.0}, 'hell': {'i': 0.3333333333333333, 'o': 0.6666666666666666}, ' hel': {'l': 1.0}}

簡單解釋:

把一個特定鍵的頻率值加起來,然後把這個鍵的每個頻率值除以這個加起來的值,就得到了機率。

3、載入資料集

接下來將載入真正的訓練語料庫。可以使用任何想要的長文本(.txt)文件。

為了簡單起見將使用一個政治演講來提供足夠的詞彙來教導我們的模型。

 text_path = "train_corpus.txt"
 def load_text(filename):
with open(filename,encoding='utf8') as f:
return f.read().lower()
 
 text = load_text(text_path)
 print('Loaded the dataset.')

這個資料集可以為我們這個範例的項目提供足夠的事件,從而做出合理準確的預測。與所有機器學習一樣,更大的訓練語料庫將產生更準確的預測。

4、建立馬可夫鏈

讓我們建立馬可夫鏈,並將機率與每個字元連結起來。這裡將使用在第1步和第2步中建立的generateTable()和convertFreqIntoProb()函數來建立馬可夫模型。

 def MarkovChain(text,k=4):
T = generateTable(text,k)
T = convertFreqIntoProb(T)
return T
 
 model = MarkovChain(text)

第1行,創建了一個方法來產生馬可夫模型。此方法接受文字語料庫和K值,K值是告訴馬可夫模型考慮K個字元並預測下一個字元的值。第2行,透過提供方法generateTable()文字語料庫和K來產生查找表,該方法是我們在上一節中建立的。第3行,使用convertFreqIntoProb()方法將頻率轉換為機率值,該方法也是我們在上一課中創建的。

5、文字取樣

建立一個抽樣函數,它使用未完成的單字(ctx)、第4步中的馬可夫鏈模型(模型)和用於形成單字基的字元數量(k)。

我們將使用這個函數對傳遞的上下文進行取樣,並返回下一個可能的字符,並判斷它是正確的字符的機率。

 import numpy as np
 
 def sample_next(ctx,model,k):
 
ctx = ctx[-k:]
if model.get(ctx) is None:
return " "
possible_Chars = list(model[ctx].keys())
possible_values = list(model[ctx].values())
 
print(possible_Chars)
print(possible_values)
 
return np.random.choice(possible_Chars,p=possible_values)
 
 sample_next("commo",model,4)
 
 #['n']
 #[1.0]

程式碼解釋:

函數sample_next接受三個參數:ctx、model和k的值。

ctx是用來產生一些新文字的文字。但這裡只有ctx中的最後K個字元會被模型用來預測序列中的下一個字元。例如,我們傳遞common,K = 4,模型用來產生下一個字元的文字是ommo,因為馬可夫模型只使用以前的歷史。

在第 9 行和第 10 行,列印了可能的字元及其機率值,因為這些字元也存在於我們的模型中。我們得到下一個預測字元為n,其機率為1.0。因為 commo 這個字在產生下一個字元後更可能是更常見的

在第12行,我們根據上面討論的機率值傳回一個字元。

6、生成文字

最後結合上述所有函數來產生一些文字。

def generateText(starting_sent,k=4,maxLen=1000):
 
 sentence = starting_sent
ctx = starting_sent[-k:]
 
for ix in range(maxLen):
next_prediction = sample_next(ctx,model,k)
sentence += next_prediction
ctx = sentence[-k:]
return sentence
 
 print("Function Created Successfully!")
 
 text = generateText("dear",k=4,maxLen=2000)
 print(text)

結果如下:

dear country brought new consciousness. i heartily great service of their lives, our country, many of tricoloring a color flag on their lives independence today.my devoted to be oppression of independence.these day the obc common many country, millions of oppression of massacrifice of indian whom everest.
 my dear country is not in the sevents went was demanding and nights by plowing in the message of the country is crossed, oppressed, women, to overcrowding for years of the south, it is like the ashok chakra of constitutional states crossed, deprived, oppressions of freedom, i bow my heart to proud of our country.my dear country, millions under to be a hundred years of the south, it is going their heroes.

上面的函數接受三個參數:產生文字的起始字、K的值、需要文字的最大字元長度。運行程式碼將會得到一個以「dear」開頭的2000個字元的文字。

雖然這段演講可能沒有太多意義,但這些單字都是完整的,通常模仿了單字中熟悉的模式。

接下來要學什麼

這是一個簡單的文字產生專案。透過這個專案可以了解自然語言處理和馬可夫鏈實際工作模式,可以在繼續您的深度學習之旅時使用。

本文只是為了介紹馬可夫鏈來進行的實驗項目,因為它不會再實際應用中起到任何的作用,如果你想獲得更好的文本生成效果,那麼請學習GPT- 3這樣的工具。

以上是使用馬可夫鏈建立文字產生器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:51cto.com。如有侵權,請聯絡admin@php.cn刪除