本人的作品,在Github上开源,欢迎大家使用:https://github.com/blmoistawinde/HarvestText

HarvestText

Sow with little data seed, harvest much from a text field.

播撒几多种子词,收获万千领域实

用途

HarvestText是一个专注无(弱)监督方法,能够整合领域知识(如类型,别名)对特定领域文本进行简单高效地处理和分析的库。

具体功能如下:

目录:

  • 基本处理

    • 精细分词分句

      • 可包含指定词和类别的分词。充分考虑省略号,双引号等特殊标点的分句。
    • 实体链接
      • 把别名,缩写与他们的标准名联系起来。
    • 命名实体识别
      • 找到一句句子中的人名,地名,机构名等命名实体。
    • 依存句法分析
      • 分析语句中各个词语(包括链接到的实体)的主谓宾语修饰等语法关系,
    • 内置资源
      • 通用停用词,通用情感词,IT、财经、饮食、法律等领域词典。可直接用于以上任务。
    • 信息检索
      • 统计特定实体出现的位置,次数等。
    • 新词发现
      • 利用统计规律(或规则)发现语料中可能会被传统分词遗漏的特殊词汇。也便于从文本中快速筛选出关键词。
    • 字符拼音纠错
      • 把语句中有可能是已知实体的错误拼写(误差一个字符或拼音)的词语链接到对应实体。
    • 存取消除
      • 可以本地保存模型再读取复用,也可以消除当前模型的记录。
  • 高层应用
    • 情感分析

      • 给出少量种子词(通用的褒贬义词语),得到语料中各个词语和语段的褒贬度。
    • 关系网络
      • 利用共现关系,获得关键词之间的网络。或者以一个给定词语为中心,探索与其相关的词语网络。
    • 文本摘要
      • 基于Textrank算法,得到一系列句子中的代表性句子。
    • 事实抽取
      • 利用句法分析,提取可能表示事件的三元组。
    • 简易问答系统
      • 从三元组中建立知识图谱并应用于问答,可以定制一些问题模板。效果有待提升,仅作为示例。

使用案例:

  • 《三国演义》中的社交网络(实体分词,文本摘要,关系网络等)
  • 2018中超舆情展示系统(实体分词,情感分析,新词发现[辅助绰号识别]等)
  • 近代史纲要信息抽取及问答系统(命名实体识别,依存句法分析,简易问答系统)

用法

首先安装,
使用pip

pip install harvesttext

或进入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

print("\nsentence sentiment")
sent = "武球王威武,中超最强球员!"
print("%f:%s" % (ht.analyse_sent(sent),sent))

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类型)。可以用来建立人物之间的社交网络等。

# 在现有实体库的基础上随时新增,比如从新词发现中得到的漏网之鱼
ht.add_new_entity("颜骏凌", "颜骏凌", "球员")
docs = ["武磊和颜骏凌是队友","武磊和郜林都是国内顶尖前锋"]
G = ht.build_entity_graph(docs)
print(dict(G.edges.items()))
G = ht.build_entity_graph(docs, used_types=["球员"])
print(dict(G.edges.items()))

获得以一个词语为中心的词语网络,下面以三国第一章为例,探索主人公刘备的遭遇(下为主要代码,例子见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算法,得到从文档集合中抽取代表句作为摘要信息:

print("\nText summarization")
docs = ["武磊威武,中超第一射手!","郜林看来不行,已经到上限了。","武球王威武,中超最强前锋!","武磊和郜林,谁是中国最好的前锋?"]
for doc in ht.get_summary(docs, topK=2):print(doc)
# 武球王威武,中超最强前锋!
# 武磊威武,中超第一射手!

内置资源

现在本库内集成了一些资源,方便使用和建立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相关推荐

  1. 【中文情感分析】SO-PMI算法(HarvestText库的修正以及解析)

    简述 在最近的RA过程中,需要使用一个库,同时对其的原理需要理解.然后就研究了一些,发现了几个有趣的,其中一个HarvestText中文情感分析. 我研究了他的源码后,再结合理论知识发现了这个库在情感 ...

  2. 全能NLP工具HarvestText

    向AI转型的程序员都关注了这个号???????????? 人工智能大数据与深度学习  公众号:datayx 用途 HarvestText是一个专注无(弱)监督方法,能够整合领域知识(如类型,别名)对特 ...

  3. G.1用python进行精细中文分句(基于正则表达式),HarvestText:文本挖掘和预处理工具

    NLP专栏简介:数据增强.智能标注.意图识别算法|多分类算法.文本信息抽取.多模态信息抽取.可解释性分析.性能调优.模型压缩算法等 专栏详细介绍:[NLP专栏简介:数据增强.智能标注.意图识别算法|多 ...

  4. NLP自然语言处理工具小结

    20220331 https://zhuanlan.zhihu.com/p/79202151 BM25 https://github.com/v1shwa/document-similarity wo ...

  5. 《三国演义》社交网络数据分析:最重要的一号人物竟是……

    导读:一直以来对自然语言处理和社交网络分析都很感兴趣,前者能帮助我们从文本中获得很多发现,而后者能够让我们对人们和各个事物之间普遍存在的网络般的联系有更多认识.当二者结合,又会有怎样的魔力呢? 作为一 ...

  6. 准备考试?python也能帮你划重点,上考场

    作者介绍:blmoistawinde, 西南某高校学森一枚,喜欢有意思的数据挖掘分析.希望给世界带来些清新空气~ 个人博客地址:https://blog.csdn.net/blmoistawinde. ...

  7. 用python进行精细中文分句(基于正则表达式)

    中文分句,乍一看是一个挺简单的工作,一般我们只要找到一个[.!?]这类的典型断句符断开就可以了吗.       对于简单的文本这个做法是已经可行了(比如我看到这篇文章里有个简洁的实现方法:自然语言处理 ...

  8. Python正则表达式清洗微博文本特殊符号(网址, @, 表情符等)

    在做文本分类的实验时,找到一个微博的情感分析语料,但是其中保留了很多微博中的特殊符号,对于算法的训练来说不太有利. 从上面的图中可以看到,微博里主要有几种特殊格式: 网页 @用户名(包括转发路径上的其 ...

  9. python 关键词抽取工具

    前言 依任务需要,对多种关键词抽取工具进行比较,测试.调研.特此记录相关调用方法及最终评测结果. 1.jieba Github地址:https://github.com/fxsjy/jieba/ 安装 ...

最新文章

  1. SAP MM MIGO界面里的'Delivery completed'标记
  2. 电子科技大学沙河计算机就业,电子科技大学沙河的几个软件工程有什么区别?...
  3. 【深度学习】使用 Pytorch 进行多类图像分类
  4. Android 国际化
  5. Android activity启动模式
  6. Java笔记12-函数式接口
  7. SpringCloud 如何搭建Eureka注册中心
  8. android timepicker分割线颜色,Android修改DatePicker字体颜色及分割线颜色详细介绍
  9. VisualSVN https 钩子失效 关闭服务器信任
  10. 工作流引擎厂商有哪些_国内主要工作流厂商分析
  11. windows下mysql忘记密码重置
  12. 6个裂变获客增长方法
  13. 小迪渗透代码审计(柒)
  14. 网易交互设计师微专业C2  设计需求分析与方案选择
  15. 评量子论的两本科普书籍
  16. 分享一个VS写的PDF打印控件
  17. 移动开发唱衰,iOS开发者如何涅槃重生?
  18. 流量来了,去努力保护好你的系统
  19. 基于GLSL的聚光灯效果的绘制
  20. 新西兰正式提高购房首付比例

热门文章

  1. 固态硬盘基础知识,了解一下
  2. [译]ng指令中的compile与link函数解析 转
  3. 安装vue脚手架出现的问题 npm ERR! code EEXIST。。。
  4. 新浪微博PC客户端(DotNet WinForm C# 版,C#调用新浪微博API代码,源码下载)—— 初探 (第二部分内置链接)
  5. 用计算机0和1表达难舍之情,表达不舍之情的说说
  6. 安科瑞三相电流互感器的规格参数(安科瑞-卓宋兰)
  7. 还在搞三层架构?了解下 DDD 分层架构的三种模式吧
  8. 阿里云对象存储OSS存储照片
  9. ffmpeg命令行太多了_ffmpeg每帧请求的位数过多
  10. 写代码写到70岁,是一种什么样的体验?