1. 程式人生 > >coreseek之mmseg分詞和詞庫拓展

coreseek之mmseg分詞和詞庫拓展

mmseg分詞

mmseg分詞演算法是基於統計模型的,所以演算法的規則也是來自對語料庫的分析和數學歸納,因為中文字元沒有明確的分界,會導致大量的字元分界歧義,而且,中文裡面,詞和短語也很難界定,因此,演算法除了要做統計和數學歸納之外,還要做歧義的解決。

在mmseg分詞中,有一個叫chunk的概念:

chunk,是一句話的分詞方式。包括一個詞條陣列和四個規則。

如:研究生命,有“研究/生命”和“研究生/命”兩種分詞方式,這就是兩個chunk。

一個chunk有四個屬性:長度、平均長度(長度/分詞數)、方差、單字自由度(各單詞條詞頻的對數之和)。

下面列出了chunk的4個屬性以及對應的規則:

屬性

含義

對應規則

長度

chuck中各個詞的長度之和

規則1:取最大匹配的chunk

平均長度

長度/詞數

規則2:取平均詞長最大的chunk

標準差的平方

同數學中的定義

規則3:取詞長標準差最小的chunk

單字自由度

各單字詞詞頻的對數之和

規則4:取單字詞自由語素度之和最大的chunk

做好分詞之後,會得到多種分詞方式,這時候就要使用一些過濾規則來完成歧義的解決,以得到最終的分詞方式。

歧義解決規則:

1、最大匹配 匹配最大長度的詞。如“國際化”,有“國際/化”、“國際化”兩種分詞方式,選擇後者。

2、最大平均詞長度 匹配平均詞最大的chunk。如“南京市長江大橋”,有“南京市/長江大橋”、“南京/市長/江大橋”三種分詞方式,前者平均詞長度是7/2=3.5,後者是7/3=2.3,故選擇前者的分詞方式。

3、最大方差 去方差最大的chunk。如“研究生命科學”,有“研究生/命/科學”、“研究/生命/科學“兩種分詞方式,而它們的詞長都一樣是2。所以需要繼續過濾,前者方差是0.82,後者方差是0。所以選擇第二種分詞方式。

4、最大單字自由度 選擇單個字出現最高頻率的chunk。比如”主要是因為“,有”主要/是/因為“,”主/要是/因為“兩種分詞方式,它們的詞長、方差都一樣,而”是“的詞頻較高,所以選擇第一種分詞方式。

如果經過上述四個規則的過濾,剩下的chunk仍然大於一,那這個演算法也無能為力了,只能自己寫擴充套件完成。

Chunk中的4個屬性只有在需要該屬性的值時才進行計算,而且只計算一次。

可以將規則理解為一個過濾器,過濾掉不符合要求的chunk。MMSeg分詞演算法中涉及了4個規則:

這4個規則符合漢語成詞的基本習慣。

詳細匹配過程如下:

1)先使用規則1(長度)來過濾chunks,

2)如果過濾後的結果chunk多於或等於2,則使用規則2繼續過濾,否則終止過濾過程。

3)如果使用規則2(平均長度)得到的過濾結果chunk多於或等於2,則使用規則3繼續過濾,否則終止過濾過程。

4)如果使用規則3(標準差的平方)得到的過濾結果chunk多於或等於2,則使用規則4繼續過濾,否則終止過濾過程。

5)如果使用規則 4(單字自由度)得到的過濾結果chunk多於或等於2,則丟擲一個表示歧義的異常,否則終止過濾過程。

最後通過一個例句--“研究生命起源"來簡述一下複雜最大匹配的分詞過程。

MMSeg分詞演算法會得到7個chunk,分別為:

編號

chunk

長度

0

研_究_生

3

1

研_究_生命

4

2

研究_生_命

4

3

研究_生命_起

5

4

研究_生命_起源

6

5

研究生_命_起

5

6

研究生_命_起源

6

使用規則1過濾後得到2個chunk,如下:

編號

chunk

長度

4

研究_生命_起源

6

6

研究生_命_起源

6

計算平均長度後為:

編號

chunk

長度

平均長度

4

研究_生命_起源

6

2

6

研究生_命_起源

6

2

使用規則2過濾後得到2個chunk,如下:

編號

chunk

長度

平均長度

4

研究_生命_起源

6

2

6

研究生_命_起源

6

2

計算標準差的平方後為:

編號

chunk

長度

平均長度

標準差的平方

4

研究_生命_起源

6

2

0

6

研究生_命_起源

6

2

4/9

使用規則3過濾後得到1個chunk,如下:

編號

chunk

長度

平均長度

標準差的平方

4

研究_生命_起源

6

2

0

匹配過程終止。最終取“研究”成詞,以相同的方法繼續處理“生命起源”。

詞庫擴充

由於coreseek帶的mmseg預設詞庫有10w多個字詞,搜尋出來的結果準確度不是很理想。花了半天找了下搜尋引擎相關的資料,現在記錄下一些提高搜尋精度的方法和步驟:
1. 基礎詞庫要足夠豐富,因為只有基礎詞庫豐富了,才能談權重設定。
2. 增加相關業務領域的詞彙,進一步提升詞庫量,如果不是做綜合搜尋,一般都只需要提高自身業務領域的詞彙。
3. 記錄與收集使用者搜尋,把搜尋記錄高的作為新增詞彙加入到詞庫中(前提是詞庫中不存在這個詞)。
         如果要豐富基礎詞庫,詞庫可以去搜狗拼音官網下載。使用工具轉換為txt 明文格式文字。使用指令碼和工具統一處理成mmseg匯入格式(如:單詞\t1\r\nx:1\r\n)。

執行指令碼處理過程如下(WordsProcess.sh):

#"過濾英文字元和空格和回車鍵

filenum=`find ./data -type f -name *.txt|wc -l`

if [ $filenum == 0 ]

then

echo "no input file"

exit 0

fi

echo "input file num $filenum"

find ./data -type f -name "*.txt"|xargs sed -i "s/[A-Za-z' \r]//g"

#替換回車字元為換行字元 find./data -name "*.txt" |xargs sed -i 's/\r/\n/g'

#txt格式的檔案需要先轉換為 .in結尾的檔案

echo "change txt to in"

for file in $(find ./data -type f -name"*.txt")

do

         echo"change $file"

         tmpfile=`echo$file|cut -d . -f 2`

         echo"tmpfile $tmpfile"

         echo"mv $file ./${tmpfile}.in"

         mv$file "./${tmpfile}.in"

done

 #執行產生輸出檔案

find . -type f -name"*.out"|xargs -i rm {}

echo "execute  coreseekTool.sh"

./coreseekTool.sh

 echo "wait for coreseekTool to outputfiles"

sleep 10

 #拷貝輸出檔案

test ./data/總體.out &&sudo cp ./data/總體.out /usr/local/mmseg3/etc/total.out && echo "cp./data/總體.out /usr/local/mmseg3/etc/total.out"

ls -l /usr/local/mmseg3/etc/total.out

 #生成詞庫

sudo /usr/local/mmseg3/bin/mmseg -u/usr/local/mmseg3/etc/total.out && echo "sudo/usr/local/mmseg3/bin/mmseg -u /usr/local/mmseg3/etc/total.out"

ls -l /usr/local/mmseg3/etc/total.out.uni

 #修改產生的二進位制詞庫名

echo "change wordlib name"

test /usr/local/mmseg3/etc/total.out.uni&& sudo cp /usr/local/mmseg3/etc/total.out.uni /usr/local/mmseg3/etc/uni.lib

ls -l /usr/local/mmseg3/etc/uni.lib

 #重新生成索引

searchd_port=9312

running_im_pid=`sudo netstat -apn2>>/dev/null | grep -w $searchd_port | grep searchd | awk -F/'/^tcp/{print $1}' | awk '/LISTEN/{print $NF}'`

echo "running_im_pid:$running_im_pid"

if [ -z "$running_im_pid" ]

then

    #如果searchd未啟動,執行索引:

   echo "/usr/local/coreseek/bin/indexer -c/usr/local/coreseek/etc/sphinx.conf --all"

   sudo /usr/local/coreseek/bin/indexer -c/usr/local/coreseek/etc/sphinx.conf --all

else

    #如果searchd已啟動,執行索引:

   echo "/usr/local/coreseek/bin/indexer -c/usr/local/coreseek/etc/sphinx.conf --all --rotate"

   sudo /usr/local/coreseek/bin/indexer -c/usr/local/coreseek/etc/sphinx.conf --all --rotate

fi

 sleep 1

echo "show indexs"

ls -l --color=tty/usr/local/coreseek/var/data/answer_main_index

ls -l --color=tty/usr/local/coreseek/var/data/answer_rotate_index

#測試

echo "testing search"

/usr/local/coreseek/bin/search -c/usr/local/coreseek/etc/sphinx.conf -p 吃飯

目前使用的搜狗官方的中文詞庫,轉換後的檔案如下: