1. 程式人生 > >從“零”開發一款知識圖譜應用產品

從“零”開發一款知識圖譜應用產品

課程介紹

本達人課展現了從“零”開始完成一個知識圖譜應用產品開發過程的完整實錄。

這裡的“零”,意味著對讀者的“零 Python 程式語言基礎”以及“零知識圖譜知識基礎”的要求。本次課程的學習,猶如讀者與作者共同進行的一次徒手攀巖歷程,只要讀者按著作者的思路,邊學邊實踐,最終將勇攀知識和技術的懸崖,提升自我,斬獲下面技能:

  1. 學會利用 Python 駕馭實際專案;
  2. 破除對知識圖譜知識的神祕感;
  3. 掌握一套極具應用開發潛力的知識圖譜應用開發基礎資源。

當然,除了收穫程式設計知識與成果之外,那種面向未知領域發起衝擊和攀登的刺激體驗,或許會成為我們意外的收穫。

作者介紹

邱嘉文,歷任多家 IT 公司技術帶頭人。做過軟、硬體產品研發,主導過 DCS、MES、ERP、ITSM、FMS 和智慧城市領域的資訊化專案。擅長通過總結歸納和創新思維解決實際問題。

課程內容

第01課:原來這就是知識圖譜

攀巖怎能是種生活方式?

記得,在我讀大學時的一個暑假中,那是一個風和日麗的晴朗夏日,我和幾個同學一起穿越了青島嶗山。就在接近山腳海邊之處,一座凸聳的峭壁將我吸引住了,我突然冒出了一個衝動的想法:站在這峭壁的頂上看對面的大海,一定會很美,我要攀上去!

我三蹦兩跳,感覺自己身輕如燕,沒幾分鐘就爬到了半山腰。當我快接近山頂時卻遇到了一處絕境:腳下是一塊傾斜向下的臥牛之地,勉強能站立,向左上方是凸出的斷崖,向右岩石上下一片光滑,往上是倒傾斜約5度的絕壁,絕壁上僅有一道被雨水侵蝕出來的像刀鋒般的石縫。我因為看不到這塊岩石上面到底還有多高,始終不敢上攀,直到岩石上面傳來一個遊客的聲音,讓我發現岩石上面並沒有多高時,我才屏住呼吸,雙手交替鉗住“刀鋒石”向上牽拉身體,身體緊貼岩石,像只壁虎一樣向上蹭了半米左右,終於攀上了岩石。我在岩石上癱軟了足有五分鐘,仰望著無比美麗的藍天白雲,卻沒有絲毫的征服後的喜悅感,有的只是後怕和自責。我發誓:今生決不再用生命來冒險,去換取大自然的美景。

我從此確實再沒有攀過真實的懸崖了。然而,時至今日,驀然回首,我卻驚異地發現,自己的整個人生,從那一刻起,原來早就註定成為了一次漫長的徒手攀巖。從參與我們國家第一套國產電力排程自動化系統的研發,到獨自踐行一套面向資源的應用軟體開發方法;再到獨創事脈順(Smarthings)——萬事互聯架構;然後就是攻克電子式互感器 10kv 高壓計量系統技術的難關,解決了小電流接地故障點判別行業難題;後來,提出對智慧城市的整體建模技術,開啟對人工心靈模型的探索等。一路走來,我總是會選擇一條未來目標明確,卻又前路模糊的道路前行,似乎總是在貪戀那種獨自歷經艱險之後的“這邊風景獨好”的感覺。事實上,對我來說,從對大自然轉移到對知識和技術領域中來的探險衝動,已經不再是一種精神,而是自己的一種生活方式了。

溝通平臺軟體路在何方?

今天,在大資料敲醒人工智慧技術之時,知識圖譜不知不覺再次進入了我的視野,我突然又冒出了一個衝動的想法:運用知識圖譜解決人們在溝通中的問題,一定會有好的結果,我要試一下!剛好 CSDN 旗下的 GitChat 給我提供了一個高階的場地,徒手攀知識和技術的懸崖,不管是攀上了頂峰還是摔了下來,都會是種美妙的感覺,何不再來一試身手?

說起溝通軟體,自然免不了要提到 QQ 和微信,它們都是非常成功的即時通訊軟體。它們成功的根本原因在於,能讓使用者以極小的代價,與親朋好友同事進行聯絡通訊。其中微信已經不知不覺地從一款社交應用變成了承載社會應用和職場應用的平臺。令人司空見慣的是,幾乎每次有一個叫做“專案”事情被啟動,無論是 IT 專案還是基建專案,或是其他專案,參與專案的人聚到一起就必定至少建一個微信群。幾乎每個公司的每個部門的員工、全體員工都會拉起一個群。

微信強大的使用者群成就了它似乎不可撼動的社會地位和高貴价值。也正因如此,業界諸多公司,包括騰訊自己都在想盡一切辦法,尋找下一個能顛覆微信的新社交軟體霸主。

但遺憾的是:即便微信用於職場有諸多的不便,如傳不了大檔案,檔案不能保留查詢,不能和辦公系統對接等,但是多數人還是寧願忍受這些問題的折磨,也不願意放棄微信,甚至都不太願意用回已經解決這些問題的 QQ。即便阿里(A)做出了強大的釘釘,可以更完美解決這些微信使用者職場應用的痛點,依然還是無法在職場應用上替代微信的霸主地位。看來,在社交平臺領域,靠細分市場的做法來贏得競爭似乎是無法奏效的。

未來新社交平臺軟體霸主將出自何方?我做過的一個“攀巖式專案”或顯示出了些許端倪。

“專案通”奇葩需求的啟發

那是在某集團公司的一次創新專案申報的活動中,我建議做一個基於微信進行專案溝通管理的小專案,叫“專案通”。本來只是想把集團公司眾多的在建專案在專案微信群中傳來傳去的工程檔案資料,儲存到集團自己的伺服器上可供查詢。可集團的領導卻提出了一個奇葩要求:要讓我能根據他大腦中僅存的一些蛛絲馬跡的記憶碎片,就能隨時隨地從“在建和已建的工程專案”的檔案資料中,迅速準確地找出他要找的、曾經存在的某一份工程檔案。

要用全文檢索?搜尋引擎?“對不起,”這位領導說:“我都試過百度、谷歌,關鍵字是不太可能被大概率記住的,你要假設,留下的碎片記憶是要找的文件的特殊內容和關鍵字的概率都非常低,這樣,會導致查準率低到無法令人滿意的程度,這可不行!”。

這個作業猛一聽是有點難,這是一個多懸的崖啊!

難道我還能強過百度(B)、谷歌(G)?,哦,不,還要外加強過阿里(A)、騰訊(T),別忘了,要找的工程檔案檔案,可能還只是臨時存在微信裡呢!而阿里的釘釘,可正是最想顛覆微信的主,要是能做到,BGAT 不早就做出來了嗎?但是,曾經都徒手攀過巖的我,還會害怕這個嗎?

“蛛絲馬跡的記憶碎片”讓我自然聯想起“外祖母神經元”的猜想:說是放學出校門的小朋友在眾多接小孩的人群中,一眼就認出了來接自己的外祖母,這個事實背後的神經系統的構造和活動原理,是不是小朋友的大腦中早先已經建立的一個獨立的“外祖母神經元”被激活了呢?

我知道對這個猜想的結果,可以說“不是”,也可以說“也是”。

說“不是”,是因為,神經系統不可能為每個事物單獨生長出一個神經元來記憶,解剖學告訴我們,如果是的話,就需要大腦必須有超出實際體積的 N 多倍的空間,來容納所需要的神經元的個數。

說“也是”,是因為,如果把大腦中每個神經元受到的激勵大小當作是一個變數,那麼,只需數量不多的“幾個變數”的取值組合,就能產生極大數量的“多激勵組合情況”。好比每個神經元代表一個“數軸”,多個神經元就組成了一個“多維空間”,那麼,多維空間中的“點”的個數將會是無窮多的。“外祖母神經元”會不會就是其中的一個“點”呢?也就是說,是外祖母的形象正好賦予了小朋友大腦中的幾個特定神經元各自一個特定量的激勵,是以它們的激勵量為“座標”的組合,代表了那個“外祖母神經元”。

原來這就是知識圖譜

回到我的任務,我不就是被要求用“蛛絲馬跡的記憶碎片”的刺激,去激活出要搜尋的文件這個“外祖母神經元”嗎?於是,我想到一個方案:能不能自動根據這個片言隻語展開“聯想”?再嘗試把聯想得到的新詞當關鍵字去做搜尋或遞進搜尋?搜尋結果可反過來啟發搜尋者尋找更準確的詞彙聯想路徑,更準確的聯想詞彙又能搜出更精確的結果,這個正反饋是可能建立的,要是這個過程能自動完成,哪怕是經過簡單幾次互動就能完成的話,那麼,最終搜尋查準率的結果應該會比直接進行搜尋好很多的。

怎麼來建立詞彙間的“聯想”呢?不是說,全世界任何兩個陌生人之間,最多通過六個熟人就能建立聯絡關係嗎?如果我們能構建出一個所有詞彙之間的“熟詞”關係網,那麼,要在任何兩個“陌生詞彙”之間建立關聯,不是也可以通過少數幾個詞語的“熟詞”關係,很快就能建立一條聯絡通道嗎?

也就是說,假設關於這個集團所有工程文件的關鍵詞,都包含到這個“熟詞關係網”中了,那麼,只要領導記住的片言隻語也包含在這個網中,就可能通過少數幾步的聯想,找到所需搜尋文件的關鍵詞,如果說,領導要找的檔案是“瓜”,那麼“熟詞關係網”就是“藤”,“順藤摸瓜”的感覺就出來了。而“蛛絲馬跡的記憶碎片”或許只是“藤”上的某一片葉子,或是葉子上的一條小蟲子。

很好,現在來考究“熟詞關係”是什麼東西?

為什麼兩個詞之間可以存在“熟詞關係”?,因為,從一個詞彙的含義可以聯想到另一個詞彙的含義。如果每個詞彙的含義可稱之為“語義”,那麼,“熟詞關係”,就表達了“語義關係”,熟詞關係網,就是“語義關係網”。

再來看,就集團公司的工程專案檔案所包含的所有詞彙資料來說,經過“同義詞合併”與“同詞義的聚集”的神操作(以後你會明白的)而造出來的“語義關係網”,實際又會是什麼東西呢?實際就是關於集團公司所有工程專案的情況描述、工程結構資訊,建設者資訊,施工過程資訊、管理者資訊,機器裝置資訊等等等等,一切關於工程專案的所有資訊,以及這些資訊之間的關係。

說這麼多,簡而言之,就是工程專案的知識。所以,要建的,就是這麼一張所有集團公司工程資訊,通過可聯想的語義關係組成的,一個實際工程專案知識的關係網。

網的數學術語稱為“圖”。原來,這,就是知識圖譜。

......

長話短說,終於,經過半年的努力,我帶領一個5人團隊完成了這個奇葩專案,這個“巖”我還是攀上去了。

回到本文,有哪位讀者從專案通中,看出了顛覆目前社交平臺的端倪了嗎?

沒看出來?恭喜您,您得到了繼續跟隨本教程學習的機會。

接下來,我會用“飛行預覽”的方式,試著帶領您用 Python 重新“攀登”一次這道巖,或許不用攀到最後,您就可以看出這個端倪了。

第02課:如何實現一個簡單的語義網引擎?

最少可以做什麼?

說白了,“專案通”只是在搜尋引擎的基礎上,附加了一個“語義網”,通過這個“語義網”做語義導航來進行關鍵字的篩選,然後再用選取的關鍵字集合來鎖定目標文件。“語義網”在這裡,只是起到了查詢關鍵字的作用。

專案通同時還啟發了我:如果將一個語義網中內聚程度較高的一個子網“打包”起來的話,得到的就是一個“知識塊”,如果將語義網中所有的知識塊都打包出來,語義網就變成了“知識圖譜”,這說明語義網是知識圖譜的底層實現。所以,要是能將這個“語義網”獨立出來做成一個通用服務元件,用處一定會很大。

那麼,如何來構建一個這樣的“語義網”服務元件呢?

按照我的經驗,如果想要做一個新玩意,第一步一定要儘可能地做小,只要保證符合我們心目中的用處,做的越小,越容易做好,結果就是:未來的元件核心就越牢靠,所以,“我們最少可以做什麼?”就成了我的口頭禪之一了。當然,你可以說,奧卡姆剃刀原理早就說明了這個道理,我不會在乎,我只在乎這個道理本身。

我也曾學習過人工智慧教科書提到的語義網,但我只記得其中的這個結論——描述這個世界的所有的語句,最終都可以簡化為這兩種形式的語句的連線:“A 是 B 的一種”和“ X 是 Y 的一部分”。舉例說就是,牛是動物的一種,牛頭是牛的一部分。這個結論實際告訴我們的是:這個世界的所有事實都可以分解為上述兩類“原子事實”。這提示我,最少要做的就是先描述事實,語義網,實際就是一個事實關係網。

從知識圖譜的知識來說,其對“原子事實”的表述形式更為簡單,就是“A 的 B 是 C”。舉例說,牛的種類是動物,牛的前部是牛頭,小明的年齡是12歲,……。我忽然“通靈”了一下,類似這樣的結論,在圖形學上也似曾相識:任何三維表面都可以簡化表述成是 N 個三角形連成的一個網格。所以,我選擇相信這一點——對這個世界的所有可描述的事實,最終從含義上來講,都可以分解為形如這樣的“原子事實”的組合:A 的 B 是 C。

就是它了,我們最少可以做一個“原子事實描述記錄器”,專門用來記錄形如“A 的 B 是 C”這樣的原子事實描述(注意,我已經不給它加引號了,表示這個概念已經被我確認)。

普通程式設計師看到這裡或許會覺得:So asy!,不就是一個三個欄位的表嗎?

呵呵,請先彆著急。

如何在計算機裡表示“語義”這種東西?

第一個問題出現了,請思考一下:我們要構建的是“描述關係網”,還是“語義關係網”?

有沒有注意到:“描述”和“語義”的區別?

“描述”是由詞彙連線而成的,說的更抽象一點,是圖形符號串。而“語義”,則是詞彙所表達的含義,不用嚴格思維都知道,二者是不同的概念。不用說,在計算機裡,一個描述,就是一個字串,那麼,一個“語義”呢?

這個問題實際就是:如何在計算機裡面表示“語義”這種東西?

這可不是個小問題,不信你去百度一下。

毋庸置疑,在計算機裡表示任何事物,都是用數字的,所以,對語義這種東西也不例外,在計算機裡,一個語義,必定是一個數字,而且每個語義,都有一個特定的數字對應。

問題是:如何在“表示語義的數字”和“描述語義的字串”之間建立聯絡呢?

一個詞語可能有多個含義;而一個含義又可能用多個詞語來表達。

以上是語言應用上的基本事實,也就是存在“多義詞”和“同義詞”的事實。這兩個基本事實說明了“描述”和“語義”這兩類事物之間的關係。

所以,答案竟如此精確而簡單:

給一組同義詞建立一個數字標識,這個數字標識,就是一個“語義”。

“語義三角形網格”長啥樣?

有了對語義的精確表達的定義,一個最簡單的語義網就就可以寫成這個樣子:

A 的 B 是 C,D 的 A 是 E,B 的 F 是 G,E 的 C 是 H,G 的 H 是 I……

畫成圖,就是這樣子的:

像不像描述三維曲面的三角形網格?真像!對應的語義網事實就是:對於任何的事物的描述(任何的知識),都可以用一個“語義三角形網格”來逼近。

其中的任何一個帶字母的結點,代表的是一個唯一的同義詞集合,也就是一個“語義網結點”,整張圖,就是所謂的“同義詞合併”構成的“語義網”。

在這個語義網中,一個詞彙可能同時存在於多個結點之中,這意味著:語義網結點之間,除了存在顯式的語義連線關係之外,還存在隱含的“多義詞近鄰關係”。也就是說,有多義詞出現的多個語義結點之間的“語義距離”是相對較近的,在語義網中,它們應該聚集在相互接近的區域內,這就是所謂的“同詞義聚集”的神操作。

這樣的一個語義網,既可以用來進行詞彙聯想,又可以用來進行語義聯想。

為啥這是本次攀巖的頂峰?

這個語義網成功地將語義從語言中形式化地剝離出來了,清晰而準確地描繪出了在“語言的世界”這個外殼下,濃縮的“語義的世界”。這兩個世界是以“同義詞”為“蟲洞”來相互溝通的平行世界。在語言的世界裡,符號關係是顯在的,而語義關係是隱含的;而在“語義世界”裡,則正好相反。人們日常的溝通,只能通過在語言世界交流,來達到彼此在語義世界的同步,即所謂“心有靈犀”,而苦於語義世界的隱藏不可見,導致“一點通”來之不易。關於溝通的理論告訴我們,此乃溝通的頭號障礙。

關鍵是:這兩個平行世界,現在可以精準地在計算機中實現了!

這意味著,人們之間的溝通難以從語言世界穿透到語義世界的困難,可以用電腦來幫助解決。藉助電腦,人們可以將各自的“語義世界”同步展現出來,每個人內心的語義世界從此可以顯式地相互透明,從而易於融合,易於最終達成一致!

這個,就是我的這次“攀巖”活動希望到達的頂峰。

就讓我們立即著手準備攀登!

設計一個最簡單的語義網

第一步,我們要在電腦中,構建這樣一個最簡單的語義網。

我們暫且拋開語義結點內的同義詞集合,僅考慮如何構建這樣的一個網路結構。

如果把形如“A 的 B 是 C”這樣的三元語義關係稱為一個“語義事實”,把“A”,“B”,“C”稱為“語義原子”,那麼,語義網的物件模型就是這樣的:

  • 一個語義事實包含三個語義原子;
  • 一個語義原子可參與陳述一到多個語義事實;
  • 一個語義原子可能出現在一個語義事實陳述的三個序位中的一個上。

如果用一個整數代表一個語義原子,那麼,一個語義事實就是3個整陣列成的一個連結串列,整個語義網,就是多個連結串列的集合。

對這樣超級簡單的物件模型程式設計,簡直就是小菜一碟,毫無挑戰性可言。

為了加大挑戰,我決定這次採用我比較陌生的 Python 來寫它,背後的原因,是我隱約可以感覺到,這個專案未來會是一個大資料的應用,而 Python 在這方面的優勢,自然給了我強大的吸引力。

從下篇開始,你會看到一開始的身輕如燕,預示著可能到最後的絕境難生。

第03課:怎麼用 Python 來做?
第04課:用 Python 實現語義原子
第05課:用 Python 實現語義分子
第06課:用 Python 實現語義細胞
第07課:用 Python 實現語義小生命
第08課:語義物件池的實現
第09課:測試語義網伺服器小生命
第10課:接下來可以怎麼做?

閱讀全文: http://gitbook.cn/gitchat/column/5b4445fb88bf540ab6007339