1. 程式人生 > >HanLP-最短路徑分詞

HanLP-最短路徑分詞

今天介紹的內容是最短路徑分詞。最近換回了thinkpad x1,原因是mac的13.3寸的螢幕看程式碼實在是不方便,也可能是人老了吧,^_^。等把HanLP詞法分析介紹結束後,還是會換回macbook pro的。個人有強迫症,只要看或寫Java或C/C++程式碼或者用開發機的化,還是喜歡在windows下工作。看論文特別是理論的研究還是習慣用mac了。感覺開發還是windows比較順手,理論研究還是mac比較順手。

基本思想:首先根據詞典,找出字串中所有可能的詞(也稱全切分),然後構造詞語切分有向無環圖(也稱作粗分詞圖或粗分詞網)。每個詞對應圖中的一條有向邊。若賦給相應的邊長一個權值(該權值可以是常數,也可以是所構成的詞的屬性值),然後根據該切分圖,在起點到終點的所有路徑中,求出長度值(包括權值)為最短的一條路徑,這條路徑上包含的詞就是該句子的切分結果。若每個結點處記錄N個最短路徑值,則該方法也稱N-最短路徑演算法。

為進一步提高切分精度,在詞典中增加詞的屬性值,即給每個詞也給權重。這樣每個詞在漢字串中的權重不同(即構成的有向圖的邊不為等長)。最簡單的詞的權重可以用詞頻表示,高頻詞的權重大,低頻詞的權重小。具體的權重值可以通過大規模語料庫獲得。

雖然HanLP中提供了dijkstra演算法的實現,但是當前HanLP中最短路徑分詞使用的是viterbi演算法。

例子:他說的確實在理

遍歷計算過程和回溯分詞過程

(1) node列與to列

node列的詞語為粗分詞網中所有的詞,to列為在node列為詞word_node的情況下,後邊接的所有可能的詞word_to。第1個詞語前邊有一個“始”詞,最後一個詞語後邊有一個“末”詞。

(2) begin2node_w的計算

表示從“始”到node詞的最短路徑權值。可以從待計算值所在行的node列讀取出word詞,在to列中以待計算值所在行開始向上查詢word,找到word所在行後(以首次遇到的詞為準),begin2to_w列所對應的值就是待計算值。見圖中下劃線。第一個詞對“始-他”的begin2node_w的值為0。

(3) node2to_w的計算

 

由node+w構成的2gram串的概率,也就是轉移概率,計算公式為

計算的HanLP程式碼為https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/utility/MathUtility.java calculateWeight(Vertex from, Vertex to)。“始”的頻次取為MAX_FREQUENCY,“始-他”的共現頻次值為“他”作為句首的頻次,“理-末”的共現頻次值為“理”作為句末的頻次。

(4) begin2to_w_n的計算

表示從“始”到to詞的最短路徑權值。begin2to_w_n = begin2node_w + node2to_w。

(5) begin2to_w_o

表示記錄在to詞下的,到to詞的最短路徑權值,它的初始值為0,之後由begin2to_w來更新。

(6) from

表示詞語to的前驅詞。

可以看錶中(7,9),(8,10),(11,13),(12,14),(15,16),(17,18)成對行來驗證該公式,其中只有(17.18)行滿足了第3個式子。

(6)和(7)的HanLP實現程式碼https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/seg/common/Vertex.java updateFrom(Vertex from)

(8) 回溯確定分詞路徑

從“末”開始向前回溯,末->理->在->確實->的->說->他,可以看錶中黃色單元格進行驗證。

經過(6)、(7)兩步,可以確保粗分詞網中任意詞的前驅都是最短路徑的。

遍歷計算過程和回溯過程的HanLP程式碼https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/seg/Viterbi/ViterbiSegment.java viterbi(WordNet wordNet)

相關推薦

HanLP-路徑

今天介紹的內容是最短路徑分詞。最近換回了thinkpad x1,原因是mac的13.3寸的螢幕看程式碼實在是不方便,也可能是人老了

hanlp中的N路徑

N-最短路徑 是中科院分詞工具NLPIR進行分詞用到的一個重要演算法,張華平、劉群老師在論文《基於N-最短路徑方法的中文詞語粗分模型》中做了比較詳細的介紹。該演算法演算法基本思想很簡單,就是給定一待處理字串,根據詞典,找出詞典中所有可能的詞,構造出字串的一個有向無環圖,算出從

Hanlp中N路徑詳細介紹

開發十年,就只剩下這套架構體系了! >>>   

自然語言處理工具HanLP-N路徑

本篇給大家分享baiziyu 寫的HanLP 中的N-最短路徑分詞。以為下分享的原文,部分地方有稍作修改,內容

中文預處理之N路徑法小結(轉)

  本文演算法來自《基於N-最短路徑方法的中文詞語粗分模型》(張華平、劉群,中文資訊學報,16卷5期)。凡有不解處,當參考原文。        漢語之魅力在於整齊而富有音律美。不像英文,單詞間長短不一,字與字之間還用空格隔開。話雖如此,可計算機處理起來,天然的空格有助於計算機迅速識別單詞間邊界。而中文,美則美

1003 Emergency (25 )(求路徑

給出N個城市,m條無向邊。每個城市中都有一定數目的救援小組,所有邊的邊權已知。現在給出起點和終點,求從起點到終點的最短路徑條數及最短經上的救緩小組數目只和。如果有多條最短路徑,則輸出數目只和最大的 Dijkstra 做法 #include<bits/stdc++.h> using nam

1018 Public Bike Management (30 )(圖的遍歷and路徑

    這題不能直接在Dijkstra中寫這個第一 標尺和第二標尺的要求 因為這是需要完整路徑以後才能計算的  所以寫完後可以在遍歷   #include<bits/stdc++.h> using namespace std; int c

1030 Travel Plan (30 )(路徑 and dfs)

#include<bits/stdc++.h> using namespace std; const int N=510; const int inf=0x3f3f3f3f; int mp[N][N]; bool vis[N]; int dis[N]; int n,m,s,D; int

1072 Gas Station (30 )(路徑

  #include<bits/stdc++.h> using namespace std; const int N=1e3+100; int n,m,k,Ds; int mp[N][N]; int dis[N]; int vis[N]; int inf=0x3f3f3f3

PAT A1111 Online Map(30 )----路徑麻煩題

總結:最後一個測試點超時。。 1.這道題因為兩個要求,同時求的話要互不影響才行,就像求最短路徑的時候不能更新時間(重新設定個變數更新) 2.以求最快路徑為例,當totalen<minlen一定要更新totalsize,否則結果可能出錯 3.這種題優先採用dijstra方法 程式

PAT A1087 All Roads Lead to Rome(30 )----路徑(加篩選條件)

總結: 1.圖中的點名稱為字母,所以用兩個map來進行轉換 2.先求最短路徑集合,再求符合要求的最短路徑 程式碼: #include<iostream> #include<vector> #include<map> #include<stri

PAT A1072 Gas Station(30 )-------圖路徑---比較難點的題

總結: 1.這道題用了dijstra演算法,關鍵是開始對G1非數字的處理即Gi處理成i+n;我最後一個測試點開始沒過就是因為用s.size()判斷輸入為數字還是G2,但是其實資料n+m是大於99的 程式碼: #include<iostream> #include<alg

PAT A1003 Emergency(25 )----路徑

總結:這道題坑的地方在於求最大集結救援隊是值得一條最短路線上的所有節點之和,而不是所有最短路徑上的節點之和 深搜(dfs): 1.求路徑,點權,邊權。遍歷,最大連通子圖。 2.兩段程式碼分別使用深搜和dijkstra演算法解決的,有興趣可以兩端都看看,第二段程式碼比第一段快,遞迴程式消耗

約束與路徑

差分約束問題(Difference constraints) 一類特殊的線性規劃(Linear Program)問題,例如求一個可行n維解向量X,使得其滿足以下m個式子: 利用“最短路徑”解

約束和路徑

差分約束系統      (1)在一個差分約束系統中,線性規劃矩陣A的每一行包括一個1和一個-1,其它所有項皆為0。由Ax≤b給出的約束條件形式上是m個涉及n個變數的差額限制條件(difference constraints),每個約束條件是以下簡單的線性不等關係:。其中1≤i,j≤n,i≠j,並且

MIT演算法導論公開課之第18課 路徑演算法、Bellman和差約束系統

Bellman-Ford 演算法 圖G=(V,E),選取s∈V作為圖的原點,此演算法可計算最短路徑δ(s,v)(v∈V)或報告出圖中存在負權值的環路。 Exercise 在路徑中存在負權值的環路時,將δ(s,v)設定為-∞。 Bellman-F

(路徑算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理與介紹

void empty borde fast 默認 grand else 理解 scan 這一篇博客以一些OJ上的題目為載體。整理一下最短路徑算法。會陸續的更新。。。 一、多源最短路算法——floyd算法 floyd算法主要用於求隨意兩點間的最短路徑。也成

路徑問題

調用 ini 順序 lba turn init als 所有 lin Dijkstra算法:有權圖的單源最短路 1.最短路必定只經過S中的頂點   如果還存在一個w在S之外,v0>w必定小於v0>v,但路徑是按照遞增順序生成的,那麽w一定已經收錄了,與前提

路徑算法

open 多源 view 一個 family gif 最短路徑 -s dijkstra 最短路徑算法1——Floyed與Dijkstra算法。 求圖中一個點到另一個點的最短路徑,毫無疑問Floyed算法是最簡單的,而且是多源最短路徑,但時間復雜度很高,達到O(n^3)。 原

路徑-Dijkstra算法(轉載)

ges 圖論 測試 log logs 表示 保存 依次 路徑 註意:以下代碼 只是描述思路,沒有測試過!! Dijkstra算法 1.定義概覽 Dijkstra(迪傑斯特拉)算法是典型的單源最短路徑算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心