HarvestText
本人的作品,在Github上開源,歡迎大家使用:https://github.com/blmoistawinde/HarvestText
HarvestText
Sow with little data seed, harvest much from a text field.
播撒幾多種子詞,收獲萬千領域實
用途
HarvestText是一個專注無(弱)監督方法,能夠整合領域知識(如類型,別名)對特定領域文本進行簡單高效地處理和分析的庫。
具體功能如下:
目錄:
- 基本處理
- 精細分詞分句
- 可包含指定詞和類別的分詞。充分考慮省略號,雙引號等特殊標點的分句。
- 實體鏈接
- 把別名,縮寫與他們的標準名聯系起來。
- 命名實體識別
- 找到一句句子中的人名,地名,機構名等命名實體。
- 依存句法分析
- 分析語句中各個詞語(包括鏈接到的實體)的主謂賓語修飾等語法關系,
- 內置資源
- 通用停用詞,通用情感詞,IT、財經、飲食、法律等領域詞典。可直接用于以上任務。
- 信息檢索
- 統計特定實體出現的位置,次數等。
- 新詞發現
- 利用統計規律(或規則)發現語料中可能會被傳統分詞遺漏的特殊詞匯。也便于從文本中快速篩選出關鍵詞。
- 字符拼音糾錯
- 把語句中有可能是已知實體的錯誤拼寫(誤差一個字符或拼音)的詞語鏈接到對應實體。
- 存取消除
- 可以本地保存模型再讀取復用,也可以消除當前模型的記錄。
- 精細分詞分句
- 高層應用
- 情感分析
- 給出少量種子詞(通用的褒貶義詞語),得到語料中各個詞語和語段的褒貶度。
- 關系網絡
- 利用共現關系,獲得關鍵詞之間的網絡。或者以一個給定詞語為中心,探索與其相關的詞語網絡。
- 文本摘要
- 基于Textrank算法,得到一系列句子中的代表性句子。
- 事實抽取
- 利用句法分析,提取可能表示事件的三元組。
- 簡易問答系統
- 從三元組中建立知識圖譜并應用于問答,可以定制一些問題模板。效果有待提升,僅作為示例。
- 情感分析
使用案例:
- 《三國演義》中的社交網絡(實體分詞,文本摘要,關系網絡等)
- 2018中超輿情展示系統(實體分詞,情感分析,新詞發現[輔助綽號識別]等)
- 近代史綱要信息抽取及問答系統(命名實體識別,依存句法分析,簡易問答系統)
用法
首先安裝,
使用pip
或進入setup.py所在目錄,然后命令行:
python setup.py install隨后在代碼中:
from harvesttext import HarvestText ht = HarvestText()即可調用本庫的功能接口。
實體鏈接
給定某些實體及其可能的代稱,以及實體對應類型。將其登錄到詞典中,在分詞時優先切分出來,并且以對應類型作為詞性。也可以單獨獲得語料中的所有實體及其位置:
para = "上港的武磊和恒大的郜林,誰是中國最好的前鋒?那當然是武磊武球王了,他是射手榜第一,原來是弱點的單刀也有了進步" entity_mention_dict = {'武磊':['武磊','武球王'],'郜林':['郜林','郜飛機'],'前鋒':['前鋒'],'上海上港':['上港'],'廣州恒大':['恒大'],'單刀球':['單刀']} entity_type_dict = {'武磊':'球員','郜林':'球員','前鋒':'位置','上海上港':'球隊','廣州恒大':'球隊','單刀球':'術語'} ht.add_entities(entity_mention_dict,entity_type_dict) print("\nSentence segmentation") print(ht.seg(para,return_sent=True)) # return_sent=False時,則返回詞語列表上港 的 武磊 和 恒大 的 郜林 , 誰 是 中國 最好 的 前鋒 ? 那 當然 是 武磊 武球王 了, 他 是 射手榜 第一 , 原來 是 弱點 的 單刀 也 有 了 進步
采用傳統的分詞工具很容易把“武球王”拆分為“武 球王”
詞性標注,包括指定的特殊類型。
print("\nPOS tagging with entity types") for word, flag in ht.posseg(para):print("%s:%s" % (word, flag),end = " ")上港:球隊 的:uj 武磊:球員 和:c 恒大:球隊 的:uj 郜林:球員 ,:x 誰:r 是:v 中國:ns 最好:a 的:uj 前鋒:位置 ?:x 那:r 當然:d 是:v 武磊:球員 武球王:球員 了:ul ,:x 他:r 是:v 射手榜:n 第一:m ,:x 原來:d 是:v 弱點:n 的:uj 單刀:術語 也:d 有:v 了:ul 進步:d
for span, entity in ht.entity_linking(para):print(span, entity)[0, 2] (‘上海上港’, ‘#球隊#’)
[3, 5] (‘武磊’, ‘#球員#’)
[6, 8] (‘廣州恒大’, ‘#球隊#’)
[9, 11] (‘郜林’, ‘#球員#’)
[19, 21] (‘前鋒’, ‘#位置#’)
[26, 28] (‘武磊’, ‘#球員#’)
[28, 31] (‘武磊’, ‘#球員#’)
[47, 49] (‘單刀球’, ‘#術語#’)
這里把“武球王”轉化為了標準指稱“武磊”,可以便于標準統一的統計工作。
分句:
print(ht.cut_sentences(para))[‘上港的武磊和恒大的郜林,誰是中國最好的前鋒?’, ‘那當然是武磊武球王了,他是射手榜第一,原來是弱點的單刀也有了進步’]
如果手頭暫時沒有可用的詞典,不妨看看本庫內置資源中的領域詞典是否適合你的需要。
*現在本庫能夠也用一些基本策略來處理復雜的實體消歧任務(比如一詞多義【“老師"是指"A老師"還是"B老師”?】、候選詞重疊【xx市長/江yy?、xx市長/江yy?】)。
具體可見linking_strategy()
命名實體識別
找到一句句子中的人名,地名,機構名等命名實體。使用了 pyhanLP 的接口實現。
ht0 = HarvestText() sent = "上海上港足球隊的武磊是中國最好的前鋒。" print(ht0.named_entity_recognition(sent)) {'上海上港足球隊': '機構名', '武磊': '人名', '中國': '地名'}
依存句法分析
分析語句中各個詞語(包括鏈接到的實體)的主謂賓語修飾等語法關系,并以此提取可能的事件三元組。使用了 pyhanLP 的接口實現。
ht0 = HarvestText() para = "上港的武磊武球王是中國最好的前鋒。" entity_mention_dict = {'武磊': ['武磊', '武球王'], "上海上港":["上港"]} entity_type_dict = {'武磊': '球員', "上海上港":"球隊"} ht0.add_entities(entity_mention_dict, entity_type_dict) for arc in ht0.dependency_parse(para):print(arc) print(ht0.triple_extraction(para)) [0, '上港', '球隊', '定中關系', 3] [1, '的', 'u', '右附加關系', 0] [2, '武磊', '球員', '定中關系', 3] [3, '武球王', '球員', '主謂關系', 4] [4, '是', 'v', '核心關系', -1] [5, '中國', 'ns', '定中關系', 8] [6, '最好', 'd', '定中關系', 8] [7, '的', 'u', '右附加關系', 6] [8, '前鋒', 'n', '動賓關系', 4] [9, '。', 'w', '標點符號', 4] print(ht0.triple_extraction(para)) [['上港武磊武球王', '是', '中國最好前鋒']]
字符拼音糾錯
把語句中有可能是已知實體的錯誤拼寫(誤差一個字符或拼音)的詞語鏈接到對應實體。
def entity_error_check():ht0 = HarvestText()typed_words = {"人名":["武磊"]}ht0.add_typed_words(typed_words)sent1 = "武磊和吳力只差一個拼音"print(sent1)print(ht0.entity_linking(sent1, pinyin_recheck=True))sent2 = "武磊和吳磊只差一個字"print(sent2)print(ht0.entity_linking(sent2, char_recheck=True))sent3 = "吳磊和吳力都可能是武磊的代稱"print(sent3)print(ht0.get_linking_mention_candidates(sent3, pinyin_recheck=True, char_recheck=True)) entity_error_check() 武磊和吳力只差一個拼音 [([0, 2], ('武磊', '#人名#')), [(3, 5), ('武磊', '#人名#')]] 武磊和吳磊只差一個字 [([0, 2], ('武磊', '#人名#')), [(3, 5), ('武磊', '#人名#')]] 吳磊和吳力都可能是武磊的代稱 ('吳磊和吳力都可能是武磊的代稱', defaultdict(<class 'list'>, {(0, 2): {'武磊'}, (3, 5): {'武磊'}}))
情感分析
本庫采用情感詞典方法進行情感分析,通過提供少量標準的褒貶義詞語(“種子詞”),從語料中自動學習其他詞語的情感傾向,形成情感詞典。對句中情感詞的加總平均則用于判斷句子的情感傾向:
print("\nsentiment dictionary") sents = ["武磊威武,中超第一射手!","武磊強,中超最第一本土球員!","郜林不行,只會抱怨的球員注定上限了","郜林看來不行,已經到上限了"] sent_dict = ht.build_sent_dict(sents,min_times=1,pos_seeds=["第一"],neg_seeds=["不行"]) print("%s:%f" % ("威武",sent_dict["威武"])) print("%s:%f" % ("球員",sent_dict["球員"])) print("%s:%f" % ("上限",sent_dict["上限"]))sentiment dictionary
威武:1.000000
球員:0.000000
上限:-1.000000
0.600000:武球王威武,中超最強球員!
如果沒想好選擇哪些詞語作為“種子詞”,本庫中也內置了一個通用情感詞典內置資源,可以從中挑選。
信息檢索
可以從文檔列表中查找出包含對應實體(及其別稱)的文檔,以及統計包含某實體的文檔數。使用倒排索引的數據結構完成快速檢索。
docs = ["武磊威武,中超第一射手!","郜林看來不行,已經到上限了。","武球王威武,中超最強前鋒!","武磊和郜林,誰是中國最好的前鋒?"] inv_index = ht.build_index(docs) print(ht.get_entity_counts(docs, inv_index)) # 獲得文檔中所有實體的出現次數 # {'武磊': 3, '郜林': 2, '前鋒': 2}print(ht.search_entity("武磊", docs, inv_index)) # 單實體查找 # ['武磊威武,中超第一射手!', '武球王威武,中超最強前鋒!', '武磊和郜林,誰是中國最好的前鋒?']print(ht.search_entity("武磊 郜林", docs, inv_index)) # 多實體共現 # ['武磊和郜林,誰是中國最好的前鋒?']# 誰是最被人們熱議的前鋒?用這里的接口可以很簡便地回答這個問題 subdocs = ht.search_entity("#球員# 前鋒", docs, inv_index) print(subdocs) # 實體、實體類型混合查找 # ['武球王威武,中超最強前鋒!', '武磊和郜林,誰是中國最好的前鋒?'] inv_index2 = ht.build_index(subdocs) print(ht.get_entity_counts(subdocs, inv_index2, used_type=["球員"])) # 可以限定類型 # {'武磊': 2, '郜林': 1}
關系網絡
(使用networkx實現)
利用詞共現關系,建立其實體間圖結構的網絡關系(返回networkx.Graph類型)。可以用來建立人物之間的社交網絡等。
獲得以一個詞語為中心的詞語網絡,下面以三國第一章為例,探索主人公劉備的遭遇(下為主要代碼,例子見build_word_ego_graph())。
entity_mention_dict, entity_type_dict = get_sanguo_entity_dict() ht0.add_entities(entity_mention_dict, entity_type_dict) sanguo1 = get_sanguo()[0] stopwords = get_baidu_stopwords() docs = ht0.cut_sentences(sanguo1) G = ht0.build_word_ego_graph(docs,"劉備",min_freq=3,other_min_freq=2,stopwords=stopwords)劉關張之情誼,劉備投奔的靠山,以及劉備討賊之經歷盡在于此。
文本摘要
(使用networkx實現)
使用Textrank算法,得到從文檔集合中抽取代表句作為摘要信息:
內置資源
現在本庫內集成了一些資源,方便使用和建立demo。
資源包括:
- 褒貶義詞典 清華大學 李軍 整理自http://nlp.csai.tsinghua.edu.cn/site2/index.php/13-sms
- 百度停用詞詞典 來自網絡:https://wenku.baidu.com/view/98c46383e53a580216fcfed9.html
- 領域詞典 來自清華THUNLP: http://thuocl.thunlp.org/ 全部類型['IT', '動物', '醫藥', '歷史人名', '地名', '成語', '法律', '財經', '食物']
此外,還提供了一個特殊資源——《三國演義》,包括:
- 三國演義文言文文本
- 三國演義人名、州名、勢力知識庫
大家可以探索從其中能夠得到什么有趣發現?。
def load_resources():from harvesttext.resources import get_qh_sent_dict,get_baidu_stopwords,get_sanguo,get_sanguo_entity_dictsdict = get_qh_sent_dict() # {"pos":[積極詞...],"neg":[消極詞...]}print("pos_words:",list(sdict["pos"])[10:15])print("neg_words:",list(sdict["neg"])[5:10])stopwords = get_baidu_stopwords()print("stopwords:", list(stopwords)[5:10])docs = get_sanguo() # 文本列表,每個元素為一章的文本print("三國演義最后一章末16字:\n",docs[-1][-16:])entity_mention_dict, entity_type_dict = get_sanguo_entity_dict()print("劉備 指稱:",entity_mention_dict["劉備"])print("劉備 類別:",entity_type_dict["劉備"])print("蜀 類別:", entity_type_dict["蜀"])print("益州 類別:", entity_type_dict["益州"]) load_resources() pos_words: ['宰相肚里好撐船', '查實', '忠實', '名手', '聰明'] neg_words: ['散漫', '讒言', '迂執', '腸肥腦滿', '出賣'] stopwords: ['apart', '左右', '結果', 'probably', 'think'] 三國演義最后一章末16字:鼎足三分已成夢,后人憑吊空牢騷。 劉備 指稱: ['劉備', '劉玄德', '玄德'] 劉備 類別: 人名 蜀 類別: 勢力 益州 類別: 州名加載清華領域詞典,并使用停用詞。
def using_typed_words():from harvesttext.resources import get_qh_typed_words,get_baidu_stopwordsht0 = HarvestText()typed_words, stopwords = get_qh_typed_words(), get_baidu_stopwords()ht0.add_typed_words(typed_words)sentence = "THUOCL是自然語言處理的一套中文詞庫,詞表來自主流網站的社會標簽、搜索熱詞、輸入法詞庫等。"print(sentence)print(ht0.posseg(sentence,stopwords=stopwords)) using_typed_words() THUOCL是自然語言處理的一套中文詞庫,詞表來自主流網站的社會標簽、搜索熱詞、輸入法詞庫等。 [('THUOCL', 'eng'), ('自然語言處理', 'IT'), ('一套', 'm'), ('中文', 'nz'), ('詞庫', 'n'), ('詞表', 'n'), ('來自', 'v'), ('主流', 'b'), ('網站', 'n'), ('社會', 'n'), ('標簽', '財經'), ('搜索', 'v'), ('熱詞', 'n'), ('輸入法', 'IT'), ('詞庫', 'n')]一些詞語被賦予特殊類型IT,而“是”等詞語被篩出。
新詞發現
從比較大量的文本中利用一些統計指標發現新詞。(可選)通過提供一些種子詞語來確定怎樣程度質量的詞語可以被發現。(即至少所有的種子詞會被發現,在滿足一定的基礎要求的前提下。)
para = "上港的武磊和恒大的郜林,誰是中國最好的前鋒?那當然是武磊武球王了,他是射手榜第一,原來是弱點的單刀也有了進步" #返回關于新詞質量的一系列信息,允許手工改進篩選(pd.DataFrame型) new_words_info = ht.word_discover(para) #new_words_info = ht.word_discover(para, threshold_seeds=["武磊"]) new_words = new_words_info.index.tolist() print(new_words)[“武磊”]
具體的方法和指標含義,參考:http://www.matrix67.com/blog/archives/5044
發現的新詞很多都可能是文本中的特殊關鍵詞,故可以把找到的新詞登錄,使后續的分詞優先分出這些詞。
def new_word_register():new_words = ["落葉球","666"]ht.add_new_words(new_words) # 作為廣義上的"新詞"登錄ht.add_new_entity("落葉球", mention0="落葉球", type0="術語") # 作為特定類型登錄print(ht.seg("這個落葉球踢得真是666", return_sent=True))for word, flag in ht.posseg("這個落葉球踢得真是666"):print("%s:%s" % (word, flag), end=" ")這個 落葉球 踢 得 真是 666
這個:r 落葉球:術語 踢:v 得:ud 真是:d 666:新詞
也可以使用一些特殊的規則來找到所需的關鍵詞,并直接賦予類型,比如全英文,或者有著特定的前后綴等。
# find_with_rules() from harvesttext.match_patterns import UpperFirst, AllEnglish, Contains, StartsWith, EndsWith text0 = "我喜歡Python,因為requests庫很適合爬蟲" ht0 = HarvestText()found_entities = ht0.find_entity_with_rule(text0, rulesets=[AllEnglish()], type0="英文名") print(found_entities) print(ht0.posseg(text0)) {'Python', 'requests'} [('我', 'r'), ('喜歡', 'v'), ('Python', '英文名'), (',', 'x'), ('因為', 'c'), ('requests', '英文名'), ('庫', 'n'), ('很', 'd'), ('適合', 'v'), ('爬蟲', 'n')]
存取消除
可以本地保存模型再讀取復用,也可以消除當前模型的記錄。
from harvesttext import loadHT,saveHT para = "上港的武磊和恒大的郜林,誰是中國最好的前鋒?那當然是武磊武球王了,他是射手榜第一,原來是弱點的單刀也有了進步" saveHT(ht,"ht_model1") ht2 = loadHT("ht_model1")# 消除記錄 ht2.clear() print("cut with cleared model") print(ht2.seg(para))
簡易問答系統
具體實現及例子在naiveKGQA.py中,下面給出部分示意:
QA = NaiveKGQA(SVOs, entity_type_dict=entity_type_dict) questions = ["你好","孫中山干了什么事?","誰發動了什么?","清政府簽訂了哪些條約?","英國與鴉片戰爭的關系是什么?","誰復辟了帝制?"] for question0 in questions:print("問:"+question0)print("答:"+QA.answer(question0)) 問:孫中山干了什么事? 答:就任臨時大總統、發動護法運動、讓位于袁世凱 問:誰發動了什么? 答:英法聯軍侵略中國、國民黨人二次革命、英國鴉片戰爭、日本侵略朝鮮、孫中山護法運動、法國侵略越南、英國侵略中國西藏戰爭、慈禧太后戊戌政變 問:清政府簽訂了哪些條約? 答:北京條約、天津條約 問:英國與鴉片戰爭的關系是什么? 答:發動 問:誰復辟了帝制? 答:袁世凱More
本庫正在開發中,關于現有功能的改善和更多功能的添加可能會陸續到來。歡迎在issues里提供意見建議。覺得好用的話,也不妨來個Star~
感謝以下repo帶來的啟發:
snownlp
pyhanLP
funNLP
ChineseWordSegmentation
EventTriplesExtraction
總結
以上是生活随笔為你收集整理的HarvestText的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机组成原理学习 笔记三
- 下一篇: 全球与中国云浏览器隔离市场深度研究分析报