王寶山
摘 要:本文借用語音識(shí)別技術(shù)讀取用戶輸入口令,對(duì)用戶口令和機(jī)器指令分別進(jìn)行分詞處理并建立字典向量,字典向量都以用戶口令中的文字作為鍵所以具有相同的維度,在向量的基礎(chǔ)上對(duì)用戶口令和機(jī)器指令進(jìn)行夾角余弦計(jì)算以實(shí)現(xiàn)對(duì)機(jī)器指令的第一次打分;第二次打分則是在第一次打分的基礎(chǔ)上進(jìn)行,因?yàn)槿绻?dāng)用戶口令和機(jī)器指令在所包含文字上已經(jīng)相似,則有必要對(duì)文字的排列順序做一個(gè)考察。本文通過提取用戶口令中文字的關(guān)系對(duì)并與機(jī)器指令相比較的方式對(duì)機(jī)器指令進(jìn)行一個(gè)順序打分,最終挑選出文字與排序都與用戶口令最相似的機(jī)器指令。
關(guān)鍵詞:語音識(shí)別 字典向量 夾角余弦
中圖分類號(hào):TP18 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1672-3791(2018)02(a)-0059-02
如今計(jì)算機(jī)一詞已經(jīng)不再單純指電腦,因?yàn)椴徽撌謾C(jī)、電視機(jī)、洗衣機(jī)還是手表等許多種機(jī)器都可以被植入計(jì)算機(jī)系統(tǒng),實(shí)現(xiàn)部分計(jì)算機(jī)的功能,雖然它們依然擔(dān)當(dāng)著不同的角色,實(shí)際上它們都在變得越來越同一、越來越智能。然而這些機(jī)器變得越來越強(qiáng)大時(shí),隨之帶來的一個(gè)問題是,這些機(jī)器也變得越來越難于操控,即用戶在享受這些機(jī)器帶來的服務(wù)之前,學(xué)習(xí)如何使用它們反而成為了一種負(fù)擔(dān)。比如許多中老年人想看電視時(shí),結(jié)果就因?yàn)椴粫?huì)使用電視機(jī)盒子最后就不看了。機(jī)器越來越強(qiáng)大的時(shí)候卻反而離人們?cè)絹碓竭h(yuǎn),這絕不是機(jī)器的設(shè)計(jì)者們最初的理想,機(jī)器的設(shè)計(jì)應(yīng)該朝著更人性化的方向前進(jìn)。
本算法就是致力于打造一款面向人機(jī)交流的算法,設(shè)想通過人機(jī)交流的方式來操控機(jī)器,用戶向機(jī)器輸入相關(guān)的口令,機(jī)器識(shí)別這些口令并執(zhí)行對(duì)應(yīng)的功能,最后返回用戶所需的服務(wù)。目前語音識(shí)別的技術(shù)已經(jīng)較為成熟當(dāng),用戶口令通過語音識(shí)別的方式輸入機(jī)器,機(jī)器可以將用戶的聲音語言識(shí)別為書面語言,這給用戶提供了很大的方便,當(dāng)然也可以通過手動(dòng)方式輸入口令,但不管通過哪種方式,機(jī)器真正要做的是識(shí)別用戶口令意圖并執(zhí)行對(duì)應(yīng)功能。
1 研究思路
機(jī)器識(shí)別用戶口令意圖,并不是讓機(jī)器去“聽懂”用戶口令的意思、“理解”用戶語言表達(dá)的思想,實(shí)際上,機(jī)器目前是做不到這一點(diǎn)的。人類的語言應(yīng)該分兩個(gè)層面看待——物理層面和信息層面。物理層面即語言本身包含著哪些文字、這些文字個(gè)數(shù)以及這些文字的排列順序,這是語言所包含的基礎(chǔ)的信息;信息層面即語言背后的含義,也即人類所表達(dá)的思想。同一句話在不同的環(huán)境里可以表達(dá)不同的意思,這種現(xiàn)象正是由于人類能很好的理解、利用語言的第二個(gè)層面,而計(jì)算機(jī)卻不行。
那么如何讓機(jī)器識(shí)別出用戶口令意圖?這就需要利用好計(jì)算機(jī)本身的優(yōu)點(diǎn)。計(jì)算機(jī)具有很好的記憶力和邏輯關(guān)系對(duì)應(yīng)能力,它可以輕松地記住很多條指令、記住每個(gè)按鈕該執(zhí)行什么操作。本算法設(shè)想采用匹配的方式來讓機(jī)器識(shí)別用戶口令,即機(jī)器接收用戶口令后從自己的指令庫里尋找一條最匹配的機(jī)器指令并執(zhí)行相關(guān)的操作,設(shè)計(jì)者們只需要把機(jī)器指令與機(jī)器操作建立一定的對(duì)應(yīng)關(guān)系即可。到時(shí)機(jī)器便能夠像聽懂人類的話一般受用戶擺布,而用戶所需的只是一個(gè)機(jī)器的庫指令清單,這樣機(jī)器一定很受用戶的歡迎。但是用戶說出的口令可能是口語化的并不標(biāo)準(zhǔn),甚至還包括很多方言,而且機(jī)器的語音識(shí)別技術(shù)也不一定能完全還原用戶本來的語言,這就造成用戶口令與機(jī)器指令產(chǎn)生一定偏差,導(dǎo)致機(jī)器檢索相關(guān)指令出現(xiàn)困難。
本文考慮采用打分機(jī)制來匹配用戶口令與機(jī)器指令,分值最高的機(jī)器指令將作為檢索結(jié)果供機(jī)器執(zhí)行。本打分機(jī)制主要分兩個(gè)過程:第一個(gè)過程是利用夾角余弦公式對(duì)用戶口令向量和機(jī)器指令向量就所包含文字的匹配度打一個(gè)分值,此時(shí)可以找出在包含文字上與用戶口令最接近的機(jī)器指令,但可能不止一條,因?yàn)闈h語的魅力是,許多詞語或短語正著反著說可以表達(dá)不同的意思,這對(duì)機(jī)器來說卻是一個(gè)麻煩。所以為了對(duì)用戶口令和機(jī)器指令就文字排列順序做一個(gè)相似度匹配,本文還要指出第二個(gè)打分過程——順序打分。
2 算法步驟
本算法是基于python語言[1]設(shè)計(jì)實(shí)現(xiàn)的一款算法,主要涉及數(shù)學(xué)中的向量、夾角余弦等知識(shí),以及python語言中的列表、集合、字典等工具,具體步驟如下所述:
2.1 建立向量
向量的建立要分兩個(gè)方向:(1)用戶口令向量的建立;(2)機(jī)器指令的向量列表的建立,因?yàn)闄C(jī)器指令不止一條,所以考慮將其向量以列表的形式存儲(chǔ)。
2.1.1 建立用戶口令向量
(1)將用戶口令拆分成文字的列表,記為ul,這個(gè)列表要保持文字原本的順序,因?yàn)槲淖值捻樞蜃鳛檎Z言的基礎(chǔ)物理信息之一也很重要。
(2)以u(píng)l為基礎(chǔ)生成集合,記為us。生成集合的目的是提取用戶口令中的文字并去除重復(fù)的文字,因?yàn)榧喜话貜?fù)的項(xiàng)。這里值得一提的是,用戶口令向量和機(jī)器指令向量的建立都要用到該集合。
(3)以字典的形式建立用戶口令向量:這個(gè)字典的鍵是us中的項(xiàng)(文字),包含用戶口令涉及的所有文字并且沒有重復(fù);鍵所對(duì)應(yīng)的值則是這個(gè)鍵(文字)在ul中的個(gè)數(shù)。把這個(gè)向量記為uh。
2.1.2 建立機(jī)器指令向量列表
(1)考慮到機(jī)器指令不止一條,所以首先需要建立一個(gè)空列表,記為ml,這個(gè)列表用來存儲(chǔ)所有機(jī)器指令。
(2)依次讀取ml中的機(jī)器指令并拆分成以文字為基礎(chǔ)的一維列表,然后將其存儲(chǔ)到一個(gè)空的二位列表中,記為mll。
(3)依次讀取mll中的每一條機(jī)器指令列表,以2.1.1中us里的文字為鍵、以該文字在所讀取列表中的個(gè)數(shù)為值(若沒該字,其值為0)建立機(jī)器指令向量并保存到一個(gè)列表中。最后生成的是一個(gè)向量列表,記為mvl。
2.2 夾角余弦打分
因?yàn)橛脩艨诹钕蛄亢蜋C(jī)器指令向量是以相同的鍵建立的字典,所以它們具有相同的維度。夾角余弦的公式是[2]:
其中,mvl[i]為mvl中第i條向量。之所以建立字典形式的向量,就是為了方便求兩向量的點(diǎn)積。因?yàn)樽值涞囊粋€(gè)鍵就代表向量的一個(gè)維度,如果兩字典向量具有相同的鍵,那么它們就具有相同的維度,這樣一來很容易對(duì)它們的值計(jì)算點(diǎn)積。向量的模即向量的長度,其計(jì)算方法不再贅述。
利用夾角余弦公式可以給每一條機(jī)器指令打分,但是我們必須要讓指令與所得的分值對(duì)應(yīng)起來才行,所以我們依然選擇采用字典的形式保存計(jì)算結(jié)果。這個(gè)字典的鍵取機(jī)器指令向量在mvl中的索引、其值則是該向量獲得的分?jǐn)?shù),將這個(gè)字典記為r1。因?yàn)閙vl、mll、ml這3個(gè)列表是一一對(duì)應(yīng)的,所以r1保存的索引對(duì)3個(gè)列表來說是通用的。
獲取了向量分值之后,就要提取得分最高的機(jī)器指令,這個(gè)過程可以簡單描述為,在r1中找分值最高的索引,然后根據(jù)索引在mll中找出對(duì)應(yīng)的機(jī)器指令。如果分值最高的機(jī)器指令只有一條(至少有一條,假使全部向量都得0分,那么所有指令都是得分最高的,盡管此時(shí)可以特別返回一條請(qǐng)用戶重新輸入的提示)則結(jié)束,否則就要進(jìn)行第二個(gè)過程打分——順序打分。注意到分值最高機(jī)器指令是從mll中提取的,所以這些指令依然是以指令列表的形式存在,這是因?yàn)轫樞虼蚍炙惴ㄒ廊皇窃谥噶盍斜淼幕A(chǔ)上實(shí)現(xiàn)的。又因?yàn)榉种底罡咧噶盍斜聿恢挂粭l,所以考慮以二位列表存儲(chǔ)這些一維列表,記為tll。
2.3 順序打分算法
順序打分算法的思路是這樣的:對(duì)于用戶口令生成的文字列表ul,它保留了原始口令中文字的順序,這種順序關(guān)系將作為我們給機(jī)器指令打分的依據(jù)。
具體地說,用戶口令列表中任意兩個(gè)字之間都具有一個(gè)先后順序關(guān)系,我們稱之為一個(gè)關(guān)系對(duì),如果用戶口令的字?jǐn)?shù)為n,則這種關(guān)系對(duì)的個(gè)數(shù)為。依次取tll中的機(jī)器指令列表,通過兩層循環(huán)給該機(jī)器指令打分:第一層循環(huán)依次取用戶口令列表中第一個(gè)字到倒數(shù)第二個(gè)字,第二層循環(huán)則依次取第一層循環(huán)中所取字之后的字,這樣兩層循環(huán)分別取兩個(gè)字,并且在用戶口令列表中第一個(gè)字排在第二個(gè)字前面,如果在機(jī)器指令列表中第一個(gè)字也是排在第二個(gè)字的前面,則給機(jī)器指令加1分。判斷這兩個(gè)字在機(jī)器指令列表中的順序關(guān)系是根據(jù)這兩個(gè)字的索引,如果第一個(gè)字的索引小于第二個(gè)字,則說明第一個(gè)字排在第二個(gè)字的前面。如果兩個(gè)字中的某個(gè)字在機(jī)器指令列表中不存在,或者第一個(gè)字的索引大于第二個(gè)字,則機(jī)器指令不加分。兩層循環(huán)遍歷完成后,這條機(jī)器指令會(huì)獲得一個(gè)分?jǐn)?shù),我們依然以索引——分?jǐn)?shù)的形式保存在字典里,記為r2。這樣就實(shí)現(xiàn)了對(duì)機(jī)器指令的順序打分,最后根據(jù)分值把得分最高的機(jī)器指令檢索出來即可。
3 具體實(shí)施
下面假設(shè)一臺(tái)電視機(jī)包含如下指令:調(diào)高音量、調(diào)高亮度、切換到10頻道、頻道切換、清理內(nèi)存、打開內(nèi)存清理工具;用戶輸入口令為:清理內(nèi)存。則本算法的整個(gè)執(zhí)行過程描述如下:ul=[清,理,內(nèi),存];us=set([清,理,內(nèi),存]);ml=[調(diào)高音量,調(diào)高亮度,切換到10頻道,頻道切換,清理內(nèi)存,打開內(nèi)存清理工具];mll=[[調(diào),高,音,量],[調(diào),高,亮,度],[切,換,到,10,頻,道],[頻,道,切,換],[清,理,內(nèi),存],[打,開,內(nèi),存,清,理,工,具]];uh={清:1,理:1,內(nèi):1,存:1};mvl=[{調(diào):0,高:0,音:0,量:0},{調(diào):,高:0,亮:0,度:0},{切:0,換:0,到:0,10:0,頻:0,道:0},{頻:0,道:0,切:0,換:0},{清:1,理:1,內(nèi):1,存:1},{打:0,開:0,內(nèi):1,存:1,清:1,理:1,工:0,具:0}]。通過夾角余弦公式為每一條指令打分,打分的結(jié)果保存在r1中:r1={0:0,1:0,2:0,3:0,4:1.0,5:1.0};第一步打分過程中分?jǐn)?shù)最高的是清理內(nèi)存和打開內(nèi)存清理工具,分?jǐn)?shù)都是1.0分,所以接下來還要進(jìn)行第二步打分:tll=[[清,理,內(nèi),存],[打,開,內(nèi),存,清,理,工,具]];r2={0:6,1:2},結(jié)果顯示機(jī)器指令中清理內(nèi)存分?jǐn)?shù)最高,因此這條指令將被執(zhí)行。
參考文獻(xiàn)
[1] 埃里克·馬瑟斯,著.Python編程從入門到實(shí)踐[M].袁國忠,譯.北京:人民郵電出版社,2016.
[2] 劉玉蓮,傅沛仁,林玎.數(shù)學(xué)分析講義[M].北京:高等教育出版社,2008.