「NLP」利用語法規則自動生成句子


本文主要介紹如何通過預先設定好的語法規則以及單詞,通過Python來自動生成一些句子。

解析語法

在生成句子之前,我們需要先告訴機器生成句子的語法。

因此,我們先定義一個簡單的語法:

simple_grammar = """
sentence => noun_phrase verb_phrase
noun_phrase => Article Adj* noun
Adj* => null | Adj Adj*
verb_phrase => verb noun_phrase
Article =>  一個 | 這個
noun =>   女人 |  籃球 | 桌子 | 小貓
verb => 看着   |  坐在 |  聽着 | 看見
Adj =>  藍色的 | 好看的 | 小小的
"""

上面的語法其實可以表示成一棵語法樹(Syntax Tree),對此感興趣的話可以參考以下文章:

語法說明

  1. sentence => noun_phrase verb_phrase:表示一個 sentencenoun_phraseverb_phrase 組成。
  2. Adj => 藍色的 | 好看的 | 小小的:表示 Adj 一共有 藍色的 | 好看的 | 小小的 3個選擇。

基於上面的兩條規說明,我們就能夠讀懂上面的語法規則。

觀察上面的語法,我們可以發現一共有兩類詞匯,左邊的詞匯是可以繼續拓展的,右邊的詞匯如果不在左邊,那么是不可拓展的。

我們先以adj為例,編寫代碼。Adj語法如下:

adj_grammar = """
Adj* => null | Adj Adj*
Adj =>  藍色的 | 好看的 | 小小的

"""

根據上面的adj_grammar字符串語法規則,我們將其解析成字典格式:

# 解析語法
def create_grammar(grammar_str, split = '=>', line_split = '\n'):
    grammar = {}
    for line in grammar_str.split(line_split):
        if not line.strip():
            continue    # 跳過空行
        else:
            exp, stmt = line.split(split)
            grammar[exp.strip()] = [s.split() for s in stmt.split('|')]
    return grammar

結果如下:

接着我們再將上面的simple_grammar語法規則解析成字典格式:

至此,我們已經能夠使用代碼解析出上面的語法規則了。

生成句子

最后,我們編寫代碼根據上面的語法規則,自動生成句子:

# 生成句子
def generate(gram, target):
    if target not in gram:
        return target    # means target is a terminal expression
    # target in gram 意味着target是可以繼續拓展下去的
    else:
        expaned = [generate(gram, t) for t in random.choice(gram[target])]
        return ''.join([e if e!='/n' else '\n' for e in expaned if e != 'null'])

利用編寫的代碼,隨機生成一個句子:

我們可以再定義兩個語法,看一下效果如何:

# 在西部世界里
# 一個”人類“的語言可以定義為:

human = """
human = 自己 尋找 活動
自己 = 我 | 俺 | 我們 
尋找 = 找找 | 想找點 
活動 = 樂子 | 玩的
"""


# 一個“接待員”的語言可以定義為

host = """
host = 寒暄 報數 詢問 業務相關 結尾 
報數 = 我是 數字 號 ,
數字 = 單個數字 | 數字 單個數字 
單個數字 = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 
寒暄 = 稱謂 打招呼 | 打招呼
稱謂 = 人稱 ,
人稱 = 先生 | 女士 | 小朋友
打招呼 = 你好 | 您好 
詢問 = 請問你要 | 您需要
業務相關 = 玩玩 具體業務
玩玩 = null
具體業務 = 喝酒 | 打牌 | 打獵 | 賭博
結尾 = 嗎?
"""

“人類”和“接待員”各自隨機生成5個句子:

可以看到,我們已經成功地通過自定義的語法規則來讓計算機自動生成句子了。

小結

本文主要通過解析語法樹,自動生成句子等方法,實現了一個自動生成句子的程序。

看完這篇文章,大家也可以設計實現自己的句子生成器。

上面生成了許多句子,但是,我們如何判斷哪些句子更為合理(符合人類說話習慣),哪些句子不合理?這時候就需要用到語言模型了,關於語言模型的相關概念及代碼實現,將會在后面的文章講到,敬請期待。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM