句翻譯x模板 再談*小熵原理:“飛象過河”之句模版和語言結構 | 附開源NLP庫
日期:2023-03-11 12:39:36 / 人氣: 654 / 發(fā)布者:成都翻譯公司
事實上,有了前一文的構建詞庫的經驗,事實上就不難構思生成句子模版的算法了。每個語義塊由一個主的句模版生成,其中句模版的占位符部分也是一個語義塊;有了對句子結構的假設,我們就可以描述句模版識別算法了。因為構建句模版是基于詞來統計的,因此還需要一個分詞函數,可以用自帶的分詞器,也可以用外部的,比如結巴分詞。基于句模版來進行句子結構解析。作者丨蘇健林
單位丨廣州火焰信息技術有限公司
研究方向丨NLP,神經網絡
個人主頁丨kexue.fm
在上一篇文章中,我們根據*小熵原理進行了一系列數學推導,*終得到(2.15)和(2.17)) ,這告訴我們應該合并互信息比較大的兩個元素,這樣有助于降低“學習難度”。
從單詞到單詞,從單詞到短語,檢查相鄰元素是否可以組合成一個好的“套路”。但為什么例程必須相鄰?
當然,它不一定是相鄰的。當我們學習一門語言時,我們不僅會學習單詞和短語,還會學習“固定搭配”,這意味著如何使用單詞是合理的。這是語法的一種體現,也是本文所要表達的。查詢,希望*終實現一定程度的無監(jiān)督句法分析。
因為這次考慮的是跨鄰詞的語言聯想,我把它命名為“飛象過江”,正是:“套路寶典”的第二種——“飛象過江”。
語言結構
對于大多數人來說,他們并不真正了解什么是語法。他們腦子里只有一些“固定搭配”、“固定風格”,或者更正式的稱呼“模板”。在大多數情況下,我們會根據模板說合理的話。不同的人可能有不同的說話模板。這是個人的說話風格,甚至是“口頭禪”。
句子模板
比如“What is the Y of X”就是一個簡單的模板,里面有一些明確的詞“of”、“is”、“what”,還有一些占位符X、Y,就用兩個X和Y代替一個名詞,你得到一個語法句子(如果它是真的,那是另一回事)。此類模板的例子有很多,例如“X 和 Y”、“X 的 Y”、“X 可以是 Y”、“Y 有什么 X 有”、“是 XY 還是 Z”等等。
▲句子模板和相互嵌套的例子
當然,雖然可以提取出盡可能多的模板,但有限的模板無法覆蓋千變萬化的語言想象,所以更重要的是,它是基于模板的嵌套使用。例如,對于模板“X 的 Y 是什么”,可以將 X 替換為模板“A 和 B”以得到“(A 和 B) 的 Y 是什么”。這樣,如果模板相互嵌套,你可以得到相當多的句子。
等價類
那么,有了模板“X的Y是什么?”,我們怎么知道X和Y分別可以填什么?
剛才我們說“隨機使用兩個名詞”,但是按照我們的想法,到現在我們只會建立一個詞庫。我們甚至不知道什么是“名詞”,更不用說我們應該填寫名詞了。. 事實上,我們不需要提前知道任何事情。我們可以通過一個大的語料庫來提取每個候選位置的“等價類”。X的候選詞構成一個詞等價類,Y的候選詞也構成一個詞。等價類等
▲句型和等價物的概念
當然,這樣的場景是理想的。其實我們能得到的原始語料要差很多,但不管怎樣,我們還是先解決理想情況,實際使用的時候再考慮一般情況。
下面我們來探討如何從大量原始語料中一一獲取句子模板,考慮如何識別句子中使用的句子模板,甚至挖掘出句子的層次結構。
生成模板
其實,有了上一篇建詞庫的經驗,想出一個生成句子模板的算法其實并不難。
在構建詞庫時,我們的統計對象是單詞?,F在我們的統計對象是詞。另外,詞是由相鄰的詞組成,但句子模板可能不是由相鄰的詞組成(否則會退化為詞或詞組),所以我們還需要考慮跨詞共現,也就是Skip Word2Vec 中的 Gram 模型。
有向無環(huán)圖
有向無環(huán)圖(DAG)實際上是 NLP 中經常遇到的一種圖論模型。實際上,一元分詞模型也可以直接抽象為有向無環(huán)圖上的*短路徑規(guī)劃問題。這里的候選模板集的構建也需要一個有向無環(huán)圖。
因為考慮了Skip Gram模型,我們可以把句子中的“compact”(較大的互信息)“詞對”連接起來。從圖論的角度來看,這構成了一個“有向無環(huán)圖”:
我們直接把圖上的所有路徑都取出來,如果穿過相鄰的節(jié)點,則插入一個占位符(下面全X代表占位符),這樣就可以得到候選模板集了。例如從上圖中提取的候選模板為:
算法步驟
我們可以將上述過程詳細描述如下:
1. 將語料分成句子,切詞;
2. 選擇一個窗口大小的窗口,從語料中統計每個詞(pa, pb)的出現頻率,以及窗口大小(pab)中任意兩個詞的共現頻率;
3. 分別設置頻率閾值min_prob和互信息閾值min_pmi;
4. 遍歷所有句子:
4.1. 為每個句子構造一張圖片,句子中的詞作為圖片上的點處理;
4.2. 句子窗口中的詞對(a, b),若滿足pab>min_prob和>mi_pmi句翻譯x模板,則在圖;
4.3. 找出圖上的所有路徑(孤立點也算路徑),作為候選模板加入統計;
5. 統計每個“準模板”出現的頻率,將“準模板”按頻率降序排序,只取第一部分。
這個算法可以用來提取句子模板,也可以簡單的提取詞組(phrases),只要窗口設置為1就可以了。 所以基本上包括了上一篇提到的詞庫構建,所以上面的算法是一個泛化提取框架。
效果展示
以下是從百度知道的問題集中提取的一些句子模板(數字是統計的頻率,可以忽略):
請注意,實際上,由兩個占位符(如“X of X”和“X how X”)夾在中間的單詞模板是微不足道的。它只告訴我們這個詞可以插入一個句子中。因此,為了看效果,我們排除了這種類型的模板,得到:
從結果來看,我們的句子模板生成確實有效。因為這些句子模板幫助我們發(fā)現語言使用的規(guī)則。例如:
1.“X?”、“X?”、“How about X”模板的占位符出現在前面,表示這些詞可以放在問題的末尾(我們使用的語料庫是問題);
2.模板的占位符如“IX”、“Seeking X”、“Why X”、“Excuse me X”出現在后面,表示這些詞可以放在問句的開頭;
3. “Thank you”和“What to do”模板沒有出現在占位符中,表示可以自行組成句子;
4. “X 意味著 X”、“X 有什么 X 有”等模板反映了語言的一些固定搭配。
從一般的角度來看,這些模板在句法層面描述了語言現象。當然,為了不與當前主流的句法分析相混淆,我們不妨稱之為語言結構規(guī)律,或者直接稱之為“句子模板”。
結構分析
和分詞一樣,在構造句子模板的時候,我們也需要一個算法來識別句子中使用了哪些模板。只有這樣,才能從語料中識別出單詞的等價類。
回顧分詞算法,分詞只是一個句子切分問題。被分割的詞沒有“洞”(占位符)。如果要識別句子中使用了哪些模板,這些模板都有“洞”。并且可能相互嵌套,造成識別困難。然而,一旦我們能夠做到這一點,我們就會得到句子的層次分解,這是一個非常有吸引力的目標。
投射假設
為了實現句子的層次分解,我們可以先借鑒句法分析中普遍使用的“投射假設”。
語言的投影大致是指,如果一個句子可以分成幾個“語義塊”,那么這些語義塊是不重疊的。換句話說,如果第3個詞1、2、構成語義塊,第5個詞構成語義塊,這種情況是允許的,并且1、2、4個詞形成語義塊,第5個詞3、形成語義塊。這種情況是不可能的。大多數語言,包括中文和英文,基本滿足投影。
結構假設
為了完成句子層次的分解,我們需要對句子的構成結構做更完整的假設。受投射假設的啟發(fā),作者認為句子的結構可以假設如下:
1. 每個語義塊都是句子的一個連續(xù)子串,句子本身也被視為一個語義塊;
2. 每個語義塊由一個主句模板生成,句子模板的占位符部分也是一個語義塊;
3. 每一個單獨的詞都可以看作是一個瑣碎的句子模板,或者是一個*小粒度的語義塊。
說白了,這三個假設可以概括為一個句子:每個句子都是通過嵌套句子模板生成的。
乍一看,這個假設不夠合理,但仔細想想,你會發(fā)現這個假設足以描述大多數句子的結構。讀者可能會懷疑“是否可以并行使用兩個句子模板而不是嵌套”?答案是:不應該。
因為如果發(fā)生這種情況,您只需要將“并行”本身視為模板。例如,如果將“X and X”視為模板,則“X and X”模板中的兩個語義塊是平行的。是的,它甚至可以與自身嵌套以獲得“X and (X and X)”來描述更多并行現象。
正是因為我們對語言結構做了這個假設,所以一旦我們確定了一個句子的*優(yōu)句子模板組合,我們就得到了句子層次——因為根據假設,模板以嵌套的方式組合是的,嵌套表示遞歸,遞歸是一個層次樹結構。
分解算法
在句子結構的假設下,我們可以描述句子模板識別算法。首先,讓我們重述分詞算法。一元分詞算法的思想是將句子切分成詞,使這些詞的概率的對數之和*大(信息量之和*?。?/p>
還可以改變表達方式:找一系列詞來覆蓋句子中的每個詞,不重復,使這些詞的概率的對數之和*大(信息量之和*?。?)。
過去,我們會認為分詞是對句子進行分割,但這個等價的表達方式恰恰相反,涵蓋了句子。有了這種逆向思維,可以提出一種模板識別算法:
找一系列的句子模板來覆蓋句子中的每個詞,不重復、不遺漏、不重疊,使這些模板的概率的對數之和*大(信息量之和*?。?。
當然,這只是一個想法。在實現過程中,主要難點是占位符的處理。也就是說,句子中的每個單詞都代表單詞本身和占位符。這種二元性使得掃描和識別變得困難。
幸運的是,如果我們按照上面假設的語言結構,我們可以將其轉化為遞歸操作:在*優(yōu)結構分解方案中,主模板下每個語義塊的分解方案也是*優(yōu)的。
▲句子層次分析,包括句子模板的嵌套調用
所以我們可以得到算法:
1. 掃描句子中所有可能的模板(通過Trie樹結構可以快速掃描);
2. 每個分解方案的得分等于句子主模板的得分,加上每個語料庫的*優(yōu)分解方案的得分。
結果顯示
下面是一些簡單示例的演示。它通過有限數量的模板進行分析??梢钥闯?,句子層次的分析確實已經初步實現了。
+---> (雞蛋)可以(吃)嗎
| +---> 雞蛋
| | +---> 雞蛋
| +---> 可以
| +---> 吃
| | +---> 吃
| +---> 嗎
+---> (牛肉雞蛋)可以(吃)嗎
| +---> 牛肉雞蛋
| | +---> 牛肉
| | +---> 雞蛋
| +---> 可以
| +---> 吃
| | +---> 吃
| +---> 嗎
+---> (蘋果)的(顏色)是(什么)呢
| +---> 蘋果
| | +---> 蘋果
| +---> 的
| +---> 顏色
| | +---> 顏色
| +---> 是
| +---> 什么
| | +---> 什么
| +---> 呢
+---> (雪梨和蘋果和香蕉)的(顏色)是(什么)呢
| +---> (雪梨和蘋果)和(香蕉)
| | +---> (雪梨)和(蘋果)
| | | +---> 雪梨
| | | | +---> 雪梨
| | | +---> 和
| | | +---> 蘋果
| | | | +---> 蘋果
| | +---> 和
| | +---> 香蕉
| | | +---> 香蕉
| +---> 的
| +---> 顏色
| | +---> 顏色
| +---> 是
| +---> 什么
| | +---> 什么
| +---> 呢
當然,報告好壞是不可能的,還有一些失敗的例子:
+---> (我的美味)的(蘋果的顏色)是(什么)呢
| +---> (我)的(美味)
| | +---> 我
| | | +---> 我
| | +---> 的
| | +---> 美味
| | | +---> 美味
| +---> 的
| +---> (蘋果)的(顏色)
| | +---> 蘋果
| | | +---> 蘋果
| | +---> 的
| | +---> 顏色
| | | +---> 顏色
| +---> 是
| +---> 什么
| | +---> 什么
| +---> 呢
+---> (蘋果)的(顏色)是(什么的意思是什么)呢
| +---> 蘋果
| | +---> 蘋果
| +---> 的
| +---> 顏色
| | +---> 顏色
| +---> 是
| +---> (什么)的(意思)是(什么)
| | +---> 什么
| | | +---> 什么
| | +---> 的
| | +---> 意思
| | | +---> 意思
| | +---> 是
| | +---> 什么
| | | +---> 什么
| +---> 呢
我們稍后會分析失敗的例子。
文章摘要
一臉懵逼,各種話想吐,請先看本段。
拼圖游戲
從單詞和短語到句子模板,我們似乎都在玩拼圖游戲:我們發(fā)現這兩個部分盡可能地協同工作,所以讓我們把它們放在一起。因為將大項互信息組合起來,作為一個整體,有利于降低整體信息熵,也降低整體學習難度。
關于句型,如果你在中文世界搞不清楚,那就回顧一下我們在小學和初中是如何學英語的。那我們應該已經學了很多英語句子模板了。
有什么用
“句子模板”是本文提出的一個新概念,用它來識別語言結果也是一種新的嘗試。讀者不禁要問:這玩意有什么用?
我認為回答這個問題*好的方法是引用牛頓的一段話:
我個人認為,我似乎只是一個在沙灘上玩耍的孩子,不時為撿到比平時更光滑的石頭或更漂亮的貝殼而歡欣鼓舞,而展現在我面前的是一片未知的真相。
我引用這段話是為了表明進行這種探究的*根本原因不是出于某種實際目的,而純粹是為了探索自然語言的奧秘。
當然,如果同時研究成果能夠具有一定的應用價值句翻譯x模板,那就更完美了。從目前的結果來看,這個應用價值可能存在。
因為在 NLP 中,我們面對的句子是千變萬化的,但實際上“句型”是有限的,這也意味著句子模板也是有限的。如有必要,我們可以調整每個句子模板的占位符的含義。人工標注可以將句子模板的結構與常規(guī)的句法描述對應起來。通過有限的句子模板(無限地)分解句子,可以使 NLP 可以面對的場景更加靈活多變。
或許以往傳統的自然語言處理中也出現過類似的事情,但本文描述的內容純屬無監(jiān)督結果,也有自洽的理論描述。是一個比較完整的框架,初步效果并不理想。因此,值得進一步考慮其應用價值。
硬進
看完這篇文章,讀者*大的感受可能是“驚呆了”:能不能稍微簡化一下?
要回答這個問題,不得不提一下:距離本系列的上一篇文章已經一個多月了,這篇文章正式發(fā)布了。好像很久了?從形式上看,這篇文章只是對上一篇文章的簡單推廣:不是將相鄰的關聯擴展到非相鄰的關聯嗎?
的確,它在形式上是正確的。但要推動這個想法兼具理論和實踐價值,并不是那么簡單和順利的。例如,在生成句子模板時,如何無遺漏地獲取所有候選模板是一個難題;其次,獲取到句子模板后,如何識別句子中的句子模板(無論是自動生成的還是手動輸入的),這個就更難了。無論是理論思維還是編程實現都存在不少障礙。有必要對樹結構和遞歸編程有一個清晰的掌握。我也是調試了半個多月才把整個流程調整好,但是估計還沒有完成。
所以,你一臉懵逼是正常的,我自己寫完這篇文章還是覺得很震驚。
改進思路
在結果部分,我們還展示了一些失敗的例子。事實上,可能還有更多的失敗。
我們要從兩個方面來看待這個問題。一方面,我們有成功的例子,對應于純無監(jiān)督挖掘的探索。即使我們只能得到一小部分成功的結果,也值得欣喜;另一方面,對于失敗的例子,我們需要思考失敗的原因。并考慮解決方案。
筆者認為整體句子模板思維沒有問題,問題在于我們還沒有達到真正的語義理解層次。比如第一個失敗的例子,結果是:(我的好吃的)(蘋果的顏色)是(什么)。
我們能說這種分解是完全錯誤的嗎?顯然不是。嚴格來說,這種分解沒有任何語法錯誤,但不符合語義,也不符合我們的常識。因此,這不是句子模板的錯,而是無法充分整合語義來構建句子模板。
回顧目前主流的句法分析工作,無論是有監(jiān)督的還是無監(jiān)督的,基本上都要結合“詞性”來完成句法分析。所以這為我們提供了一個方向:*小熵序列的下一步是探索詞聚類問題,以便更好地捕捉詞義和語言共性。
基于*小熵原理的 NLP 庫:NLP Zero
我已經陸續(xù)寫了幾篇關于*小熵原理的文章,致力于無監(jiān)督NLP的一些基礎工作。為方便實驗,將文章中涉及的部分算法封裝為庫,供有需要的讀者測試使用。
由于它是面向無監(jiān)督NLP場景的,而且基本上是NLP任務的基礎工作,所以命名為NLP Zero。
地址
GitHub:
皮皮:
您可以直接通過:
pip install nlp-zero==0.1.6
安裝它。整個庫采用純Python實現,沒有第三方調用,支持Python2.x和3.x。
用
默認分詞
庫中包含字典,可用作簡單的分詞工具。
from nlp_zero import *
t = Tokenizer()
t.tokenize(u'掃描二維碼,關注公眾號')
內置詞典增加了一些通過新詞發(fā)現發(fā)現的新詞,經過作者手動優(yōu)化,質量比較高。
詞庫構建
通過大量原始語料構建詞庫。
首先,我們需要編寫一個迭代容器,這樣我們就不必一次將所有語料加載到內存中。迭代器非常靈活。比如我的數據存儲在MongoDB中,即:
import pymongo
db = pymongo.MongoClient().weixin.text_articles
class D:
def __iter__(self):
for i in db.find().limit(10000):
yield i['text']
如果數據存儲在文本文件中,則可能是:
class D:
def __iter__(self):
with open('text.txt') as f:
for l in f:
yield l.strip() # python2.x還需要轉編碼
然后就可以執(zhí)行了。
from nlp_zero import *
import logging
logging.basicConfig(level = logging.INFO, format = '%(asctime)s - %(name)s - %(message)s')
f = Word_Finder(min_proba=1e-8)
f.train(D()) # 統計互信息
f.find(D()) # 構建詞庫
通過 Pandas 查看結果:
import pandas as pd
words = pd.Series(f.words).sort_values(ascending=False)
直接從統計詞庫中創(chuàng)建分詞工具:
t = f.export_tokenizer()
t.tokenize(u'今天天氣不錯')
句子模板構建
和之前一樣,我們還需要寫一個迭代器,這里不再贅述。因為句子模板的構建是基于詞統計的,所以還需要一個分詞功能。您可以使用內置分詞器或外部分詞器,例如口吃。
from nlp_zero import *
import logging
logging.basicConfig(level = logging.INFO, format = '%(asctime)s - %(name)s - %(message)s')
tokenize = Tokenizer().tokenize # 使用自帶的分詞工具
# 通過 tokenize = jieba.lcut 可以使用結巴分詞
f = Template_Finder(tokenize, window=3)
f.train(D())
f.find(D())
通過 Pandas 查看結果:
import pandas as pd
templates = pd.Series(f.templates).sort_values(ascending=False)
idx = [i for i in templates.index if not i.is_trivial()]
templates = templates[idx] # 篩選出非平凡的模版
每個模板都被封裝成一個類。
層次分解
基于句子模板分析句子結構。
from nlp_zero import *
# 建立一個前綴樹,并加入模版
# 模版可以通過tuple來加入,
# 也可以直接通過“tire[模版類]=10”這樣來加入
trie = XTrie()
trie[(None, u'呢')] = 10
trie[(None, u'可以', None, u'嗎')] = 9
trie[(u'我', None)] = 8
trie[(None, u'的', None, u'是', None)] = 7
trie[(None, u'的', None, u'是', None, u'呢')] = 7
trie[(None, u'的', None)] = 12
trie[(None, u'和', None)] = 12
tokenize = Tokenizer().tokenize # 使用自帶的分詞工具
p = Parser(trie, tokenize) # 建立一個解析器
p.parse(u'雞蛋可以吃嗎') # 對句子進行解析
"""輸出:
>>> p.parse(u'雞蛋可以吃嗎')
+---> (雞蛋)可以(吃)嗎
| +---> 雞蛋
| | +---> 雞蛋
| +---> 可以
| +---> 吃
| | +---> 吃
| +---> 嗎
"""
為了方便結果的調用和可視化,輸出的結果被封裝成一個SentTree類。該類具有三個屬性:模板(當前主模板)、內容(當前主模板覆蓋的字符串)、模塊(語義塊列表,每個語義塊也由SentTree描述)。一般來說,它是根據本文語言結構的假設設計的。
相關閱讀Relate
熱門文章 Recent
- 羅馬尼亞護照翻譯模板 護照照片 簡介2023-03-11
- 招聘英語作文萬能模板帶翻譯 中考英語作文萬能模板帶翻譯2023-03-11
- 匯款單翻譯模板 2015年韓素音翻譯大賽原文2023-03-11
- 英國簽證資料的翻譯模板 英國留學申請材料之翻譯件2023-03-11
- 刻章護照翻譯件模板 簽證翻譯件需要蓋章嗎?2023-03-11
- 專利證書翻譯模板 相關附件清單【模板】2023-03-11
- 雙學位翻譯模板 浙商大教〔2009〕218號 浙江工商大學關于修訂 雙專業(yè)、雙學位實施方案2023-03-11
- 高中畢業(yè)成績翻譯模板 高中三年成績單模板(新留學).pdf 1頁2023-03-11
- 新南威爾士大學學位證書翻譯模板 澳大利亞六大名校翻譯專業(yè)全解析2023-03-11
- 市場部副總監(jiān)翻譯模板 市場部副經理崗位職責2023-03-11