Python繁體中文自然語言處理-HanLP安裝及測試

一、安裝

HanLP原始碼:https://github.com/hankcs/HanLP

由於HanLP是Java的套件,要在Python上使用需要一些額外的步驟,試著參照了這篇文章的步驟進行安裝:Python调用自然语言处理包HanLP(http://www.hankcs.com/nlp/python-calls-hanlp.html#h3-7)。

我的環境:Windows 7/10 + Python 3.6

  1. 安裝Java和Visual C++:我裝的是Java 1.8和Visual C++ 2015。
  2. 安裝Jpype:

原本擔心版本相容問題,所以打算按照原作者指示安裝Jpype 0.5.5.2,但不知道出什麼問題一直裝不起來,於是決定裝最新的版本Jpype 0.6.2。

conda install -c conda-forge jpype1

裝好後,就是世界知名的測試方式 Hello World

from jpype import *
startJVM(getDefaultJVMPath(), "-ea")
java.lang.System.out.println("Hello World")
shutdownJVM()

輸出結果:

Hello World
JVM activity report :
classes loaded : 31
JVM has been shutdown

這邊有件弔詭的事情是,JVM只能啟動一次,shutdown之後再啟動會出現

RuntimeError: Unable to start JVM at native\common\jp_env.cpp:78

有關於這個問題的討論:https://github.com/originell/jpype/issues/84

後來發現其實Jpype官網也有但書了:”Because of lack of JVM support, you cannot shutdown the JVM and then restart it.”(http://jpype.readthedocs.io/en/latest/install.html#known-bugs-limitations

3. 下載HanLP:有Portable版本,但不支援句法分析,所以我還是按照步驟下載安裝。

下載兩個檔案,分別是:hanlp-1.3.3-release.zip和data-for-1.3.3.zip。data檔案有627MB,下載需要一點時間。

4. 在 hanlp.properties 指定路徑:

hanlp-1.3.3-release.zip解完壓縮後會看到hanlp.properties這個檔案,把第一行root的路徑指向data的父目錄,例如data的路徑為C:/HanLP/data的話,root就要設C:/HanLP。

二、測試HanLP基本功能

from jpype import *

# 啟動JVM
startJVM(getDefaultJVMPath(),"-ea",
"-Djava.class.path=C:(我的路徑)\\Python_WorkPlace\\NLP\\HanLP\\hanlp-1.3.3-release;
C:(我的路徑)\\Python_WorkPlace\\NLP\\HanLP\\hanlp-1.3.3-release\\hanlp-1.3.3.jar")
# 調用Java Class
HanLP = JClass('com.hankcs.hanlp.HanLP')

由於目標是要做繁體中文的處理,而很多套件都是用簡體中文去做訓練的,因此第一步先套用HanLP繁簡互轉的功能。HanLP繁簡互轉有一個功能特色是能夠支援繁體跟簡體中文用詞上的互轉,例如「資訊」會轉成「信息」、「印表機」會轉成「打印机」、「士多啤梨」(港)會轉成「草莓」。

  1. 繁簡轉換:

準備文本(節錄於世界民報《同婚釋憲案 司法院5月24日公布結果》http://www.worldpeoplenews.com/content/news/13111

content = '''
台灣同性婚姻釋憲案乃是源自於在台灣長期推動同性婚姻法制化的祁家威,因他與其伴侶於2013年申請登記結婚遭到駁回,而認定《民法》親屬篇第二章婚姻規定中「同性別二人間不能成立法律上婚姻關係」有違憲疑義,因而向大法官提出釋憲聲請;而身為戶政主管機關的台北市政府民政局,也針對相關婚姻法令是否有違憲法、保障人民的自由權、平等權等問題,提出釋憲。
關於此次釋憲案,除了大法官黃瑞明因其妻子為在立法院提案修訂婚姻平權法的民進黨立委尤美女而聲請自行迴避外,其他包含司法院長許宗力在內共14名大法官皆有出席。本次釋憲案若大法官認為合憲,現行民法將維持現狀,但若解釋為違憲,則將進行相關修訂或是增訂法條等應變。
因距離釋憲結果公布還有1個月,國際特赦組織台灣分會今天與全球同步發布「#FirstInAsia 亞洲第一婚姻平權在台灣」倡議運動影片,內容有來自國際特赦組織全球各分會與總部的聲援訊息,已有超過40個國家使用不同語言表達期盼台灣能成為亞洲第一個同婚合法國,大聲詢問「台灣,will you say yes?」,並希望能透過台灣的同婚合法,啟發更多亞洲國家正視這項議題,呼籲台灣政府儘快向婚姻平權「say yes」。
'''
content = HanLP.convertToSimplifiedChinese(content)
print(content)

輸出結果:

台湾同性婚姻释宪案乃是源自于在台湾长期推动同性婚姻法制化的祁家威,因他与其伴侣于2013年申请登记结婚遭到驳回,而认定《民法》亲属篇第二章婚姻规定中“同性别二人间不能成立法律上婚姻关系”有违宪疑义,因而向大法官提出释宪声请;而身为户政主管机关的台北市政府民政局,也针对相关婚姻法令是否有违宪法、保障人民的自由权、平等权等问题,提出释宪。
关于此次释宪案,除了大法官黄瑞明因其妻子为在立法院提案修订婚姻平权法的民进党立委尤美女而声请自行回避外,其他包含司法院长许宗力在内共14名大法官皆有出席。本次释宪案若大法官认为合宪,现行民法将维持现状,但若解释为违宪,则将进行相关修订或是增订法条等应变。
因距离释宪结果公布还有1个月,国际特赦组织台湾分会今天与全球同步发布“#FirstInAsia 亚洲第一婚姻平权在台湾”倡议运动影片,内容有来自国际特赦组织全球各分会与总部的声援信息,已有超过40个国家使用不同语言表达期盼台湾能成为亚洲第一个同婚合法国,大声询问“台湾,will you say yes?”,并希望能透过台湾的同婚合法,启发更多亚洲国家正视这项议题,呼吁台湾政府尽快向婚姻平权“say yes”。

2. 斷字:

print(HanLP.segment(content))

輸出結果:

[
/w, 台湾/ns, 同性/b, 婚姻/n, 释宪/nz, 案/ng, 乃是/v, 源自/v, 于/p, 在/p, 台湾/ns, 长期/d, 推动/v, 同性/b, 婚姻/n, 法制化/vn, 的/ude1, 祁家威/nr, ,/w, 因/p, 他/rr, 与其/c, 伴侣/n, 于/p, 2013/m, 年/qt, 申请/v, 登记/vn, 结婚/vi, 遭到/v, 驳回/v, ,/w, 而/cc, 认定/v, 《/w, 民法/n, 》/w, 亲属/n, 篇/q, 第二/mq, 章/q, 婚姻/n, 规定/n, 中/f, “/w, 同性/b, 别/d, 二/m, 人间/n, 不能/v, 成立/vi, 法律/n, 上/f, 婚姻关系/nz, ”/w, 有/vyou, 违宪/vn, 疑义/n, ,/w, 因而/c, 向/p, 大法官/nnt, 提出/v, 释宪/nz, 声请/nz, ;/w, 而/cc, 身为/v, 户政/nis, 主管机关/n, 的/ude1, 台北市政府/nt, 民政局/nis, ,/w, 也/d, 针对/p, 相关/vn, 婚姻/n, 法令/n, 是否/v, 有违/v, 宪法/n, 、/w, 保障/vn, 人民/n, 的/ude1, 自由权/n, 、/w, 平等权/n, 等/udeng, 问题/n, ,/w, 提出/v, 释宪/nz, 。/w,
/w, 关于/p, 此次/rz, 释宪/nz, 案/ng, ,/w, 除了/p, 大法官/nnt, 黄瑞明/nr, 因其/c, 妻子/n, 为/p, 在/p, 立法院/nz, 提案/n, 修订/v, 婚姻/n, 平权/nz, 法/n, 的/ude1, 民进党/nz, 立委/j, 尤/d, 美女/n, 而/cc, 声请/nz, 自行/d, 回避/v, 外/f, ,/w, 其他/rzv, 包含/v, 司法院长/n, 许宗力/nr, 在/p, 内/f, 共/d, 14/m, 名/q, 大法官/nnt, 皆/d, 有/vyou, 出席/v, 。/w, 本次/r, 释宪/nz, 案/ng, 若/c, 大法官/nnt, 认为/v, 合/v, 宪/ng, ,/w, 现行/b, 民法/n, 将/d, 维持现状/n, ,/w, 但/c, 若/c, 解释/v, 为/p, 违宪/vn, ,/w, 则/d, 将/d, 进行/vn, 相关/vn, 修订/v, 或是/c, 增订/v, 法/n, 条/q, 等/udeng, 应变/vn, 。/w,
/w, 因/p, 距离/n, 释宪/nz, 结果/n, 公布/v, 还有/v, 1/m, 个/q, 月/n, ,/w, 国际特赦/l, 组织/n, 台湾/ns, 分会/nis, 今天/t, 与/cc, 全球/n, 同步/vd, 发布/v, “/w, #FirstInAsia/nx, /w, 亚洲/ns, 第一/mq, 婚姻/n, 平权/nz, 在/p, 台湾/ns, ”/w, 倡议/n, 运动/vn, 影片/n, ,/w, 内容/n, 有/vyou, 来自/v, 国际特赦/l, 组织/n, 全球/n, 各/rz, 分会/nis, 与/cc, 总部/nis, 的/ude1, 声援/v, 信息/n, ,/w, 已有/v, 超过/v, 40/m, 个/q, 国家/n, 使用/v, 不同/a, 语言表达/n, 期盼/v, 台湾/ns, 能/v, 成为/v, 亚洲/ns, 第/mq, 一个/mq, 同/p, 婚/ng, 合/v, 法国/nsf, ,/w, 大声/d, 询问/v, “/w, 台湾/ns, ,/w, will/nx, /w, you/nx, /w, say/nx, /w, yes/nx, ?/w, ”/w, ,/w, 并/cc, 希望/v, 能/v, 透过/v, 台湾/ns, 的/ude1, 同/p, 婚/ng, 合法/a, ,/w, 启发/vn, 更多/ad, 亚洲/ns, 国家/n, 正视/v, 这项/r, 议题/n, ,/w, 呼吁/v, 台湾政府/nt, 尽快/d, 向/p, 婚姻/n, 平权/nz, “/w, say/nx, /w, yes/nx, ”/w, 。/w,
/w]

結果看起來大致上還可以,有些詞需定擴充字典來處理。另外也有標記詞性,這邊有詞性的詳細對照表:http://www.hankcs.com/nlp/part-of-speech-tagging.html

3. 關鍵字提取:

print(HanLP.extractKeyword(content, 5))

輸出結果:

[婚姻, 台湾, 释宪, 大法官, 亚洲]

看起來蠻不錯的,有抓到關鍵字。

4. 短語提取:

print(HanLP.extractPhrase(content, 5))

輸出結果:

[婚姻平权, 国际特赦组织, 释宪案, 不同语言表达, 主管机关台北市政府]

5. 自動摘要:

print(HanLP.extractSummary(content, 5))

輸出結果:

[#FirstInAsia 亚洲第一婚姻平权在台湾, 台湾同性婚姻释宪案乃是源自于在台湾长期推动同性婚姻法制化的祁家威, 因而向大法官提出释宪声请, 本次释宪案若大法官认为合宪, 国际特赦组织台湾分会今天与全球同步发布]

句子前後有點不連貫,但比預期的效果還要好一點。

6. 句法分析:

print(HanLP.parseDependency(content))

輸出結果:(節錄前幾行)

1 wp w _ 7 标点符号 _ _
2 台湾 台湾 ns ns _ 4 定中关系 _ _
3 同性 同性 b b _ 4 定中关系 _ _
4 婚姻 婚姻 n n _ 5 定中关系 _ _
5 释宪 释宪 nz nz _ 6 定中关系 _ _
6 案 案 n ng _ 7 主谓关系 _ _
7 乃是 乃是 v v _ 0 核心关系 _ _
8 源自 源自 v v _ 7 动宾关系 _ _
9 于 于 p p _ 8 动补结构 _ _
10 在 在 p p _ 13 状中结构 _ _
11 台湾 台湾 ns ns _ 10 介宾关系 _ _
12 长期 长期 d d _ 13 状中结构 _ _
13 推动 推动 v v _ 18 定中关系 _ _
14 同性 同性 b b _ 15 定中关系 _ _
15 婚姻 婚姻 n n _ 16 定中关系 _ _
16 法制化 法制化 v vn _ 13 动宾关系 _ _
17 的 的 u ude1 _ 13 右附加关系 _ _
18 祁家威 祁家威 nh nr _ 9 介宾关系 _ _

輸出的是CoNLL格式:空值為 ‘_’,列的分隔符號為 ‘\t’,行的分隔符號為 ’\n’。10個欄位分別為:
ID | FORM | LEMMA | CPOSTAG | POSTAG | FEATS | HEAD | DEPREL | PHEAD | PDEPREL
只用到前8列,分別為 
1 ID:序號,從1開始
2 FORM:詞
3 LEMMA:詞的原型或詞幹,目前用下來這欄都跟FORM相同
4 CPOSTAG:詞性(粗粒度)
5 POSTAG:詞性(细粒度)
6 FEATS:句法特徵,目前用下來這欄都是空值。
7 HEAD:跟詞有關係的詞B的ID
8 DEPREL:詞與詞B的依存關係
(資料來源:http://hanlp.linrunsoft.com/doc/_build/html/dependency_parser.html

以上就是HanLP的簡單嘗試,除了這些基本功能外,還有其他功能可以視需求試試看,但以目前手邊專案而言,應該只會用到這些功能。

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.