NLP学习笔记 01 分词、词性标注和关键词提取

1.1 准确分词 level1

中文自动分词的方法主要有三种

  • 规则分词
  • 统计分词
  • 混合分词(规则 + 统计)

调包时如何提高分词准确性:

  • 加载自定义词典
  • 使用正则表达式

使用jieba自定义词典 + 正则表达式准确分词

在代码的同级目录下创建词典(txt文件):
在这里插入图片描述

创建输入文本 text.txt:

恶性肿瘤的分期越高,患者预后越差。通过对肿瘤不同恶性程度的划分,TNM分期在预测预后方面不断完善。
但是有国外研究发现,部分结肠癌的预后并不能完全按照一般的分期阶梯进行预测。
TNM分期不太能明确地区分||期和III期结肠癌患者的预后ii期,特别是在接受辅助化疗的患者中,他们的5年总生存期在50.1%-9.8%。
此外已知影响结肠癌生存的患者或疾病特征,包括年龄、性别、原发疾病位置、肿瘤分级、阳性淋巴结数目(LNs)、接受检查的
LNs数目、淋巴管和周围神经浸润、肠道梗阻或穿孔、以及辅助治疗(氟尿嘧啶单药或联合奥沙利铂),并未直接纳入TNM分期系统。
在多变量模型中,分子标记的微卫星不稳定性(MSI)和BRAF或KRAS基因突变联合详细的临床病理学诠释可以多大程度改善预后评估
目前尚不清楚。近期,发表在Annals of oncology杂志上的一项回顾性研究,在TNM分期系统基础上联合汇集的标志物对II期和III期
结肠癌总生存期进行预测。
研究人员将缺失随机数据插补后,利用3期辅助化疗试验(n=3016)—N0147(NCT00079274)和PETACC3(NCT00026273)—产生的患者亚组
聚集构建了一个5年总生存期多变量Cox模型,随后在剩余的临床试验样本(n=1499)中进行内部验证,并且还在不同人群队列中外部分析,
包括接受化疗(n=949)或者未接受化疗(n=1080)的结肠癌患者,以及没有治疗注释患者。
研究分析发现:
在根据临床试验队列和观察性研究做出的多变量模型中,TMN分期,MSI和BRAFV600E基因突变状态仍然是独立预后因素。
单纯TNM模型的一致性指数(Concordance-indices)为0.61-0.68,而增加分子标记物、临床病理特征和所有协变量后的
一致性指数分别增加至0.63-0.71、0.65-0.73和0.66-0.74。
在有完整注释的验证队列中,单独TNM的综合时间依赖AUC值为0.64,纳入临床病理特征联合或不联合分子标记物的AUC增加为0.67。
在接受辅助化疗的患者队列中,通过TNM、临床病理特征和分子标记物的方差(R2)相对比例平均值分别为65%、25%和10%。
因此,将MSI、BRAFV600E和KRAS基因突变状态纳入TNM分期系统的总生存期模型可以提高精确预测II期和III期结肠癌患者的能力,
而且包括临床病理特征的多变量模型中会增加预测准确性,特别是需要接受化疗的患者。

代码:

# -*- coding=utf8 -*-
import jieba
import re

jieba.load_userdict("dict.txt")


# 合并两个list
def merge_two_list(a, b):
    c = []
    len_a, len_b = len(a), len(b)
    minlen = min(len_a, len_b)
    for i in range(minlen):
        c.append(a[i])
        c.append(b[i])

    if len_a > len_b:
        for i in range(minlen, len_a):
            c.append(a[i])
    else:
        for i in range(minlen, len_b):
            c.append(b[i])
    return c


if __name__ == "__main__":
    # open the input file which contains a short passage and the output file which will store the output
    fp = open("text.txt", "r", encoding="utf8")
    fout = open("result_cut.txt", "w", encoding="utf8")

    # “?:”表示非获取匹配,匹配冒号后的内容但不获取匹配结果,不进行存储供以后使用。
    # u/U:表示unicode字符串
    # r/R:非转义的原始字符串
    regex1 = u'(?:[^\u4e00-\u9fa5()*&……%¥$,,。.@! !]){1,5}期'  # 匹配“ii期”形式的字符串
    regex2 = r'(?:[0-9]{1,3}[.]?[0-9]{1,3})%'  # 匹配“30.00%”形式的字符串; “[.]?”表示非贪婪匹配

    p1 = re.compile(regex1)
    p2 = re.compile(regex2)

    for line in fp.readlines():
        # 思路:先使用正则表达式找出目标字符串,储存到变量result1中,然后将line中匹配的字符串
        # 替换为"FLAG1",使用jieba / hanlp分词,最后将分词结果和result1 合并在一起
        result1 = p1.findall(line)  # 返回一个list
        if result1:
            regex_re1 = result1
            line = p1.sub("FLAG1", line)  # 使用 "FLAG1"替换line中匹配的子串

        result2 = p2.findall(line)
        if result2:
            line = p2.sub("FLAG2", line)

        # 使用jieba分词
        words = jieba.cut(line)  # 返回的是一个生成器

        # 将jieba分词结果串成字符串
        result = " ".join(words)

        if "FLAG1" in result:
            result = result.split("FLAG1")  # result又变回list类型,注意这里是用FLAG1作为分隔符,所以最后能保证分词后的顺序和原文顺序一样
            result = merge_two_list(result, result1)  # 此为自定义函数
            result = "".join(result)
        if "FLAG2" in result:
            result = result.split("FLAG2")
            result = merge_two_list(result, result2)
            result = "".join(result)
            # print(result)
            
        fout.write(result)
    fout.close()

输出的txt文件的内容为:

恶性肿瘤 的 分期 越高 , 患者 预后 越差 。 通过 对 肿瘤 不同 恶性 程度 的 划分 , TNM 分期 在 预测 预后 方面 不断完善 。 
但是 有 国外 研究 发现 , 部分 结肠癌 的 预后 并 不能 完全 按照 一般 的 分期 阶梯 进行 预测 。 
TNM 分期 不太能 明确 地区 分 ||期 和 III期 结肠癌 患者 的 预后 ii期 , 特别 是 在 接受 辅助 化疗 的 患者 中 , 他们 的 5 年 总 生存期 在 50.1% - 9.8% 。 
此外 已知 影响 结肠癌 生存 的 患者 或 疾病 特征 , 包括 年龄 、 性别 、 原发 疾病 位置 、 肿瘤 分级 、 阳性 淋巴结 数目 ( LNs ) 、 接受 检查 的 
LNs 数目 、 淋巴管 和 周围神经 浸润 、 肠道 梗阻 或 穿孔 、 以及 辅助 治疗 ( 氟尿嘧啶单药 或 联合 奥沙利铂 ) , 并未 直接 纳入 TNM 分期 系统 。 
在 多 变量 模型 中 , 分子 标记 的 微卫星 不稳定性 ( MSI ) 和 BRAF 或 KRAS 基因突变 联合 详细 的 临床 病理学 诠释 可以 多 大程度 改善 预后 评估 
目前 尚 不 清楚 。 近期 , 发表 在 Annals   of   oncology 杂志 上 的 一项 回顾性 研究 , 在 TNM 分期 系统 基础 上 联合 汇集 的 标志物 对 II期 和 III期 
结肠癌 总 生存期 进行 预测 。 
研究 人员 将 缺失 随机 数据 插补后 , 利用 3期 辅助 化疗 试验 ( n = 3016 ) — N0147 ( NCT00079274 ) 和 PETACC3 ( NCT00026273 ) — 产生 的 患者 亚组 
聚集 构建 了 一个 5 年 总 生存期 多 变量 Cox 模型 , 随后 在 剩余 的 临床试验 样本 ( n = 1499 ) 中 进行 内部 验证 , 并且 还 在 不同 人群 队列 中 外部 分析 , 
包括 接受 化疗 ( n = 949 ) 或者 未 接受 化疗 ( n = 1080 ) 的 结肠癌 患者 , 以及 没有 治疗 注释 患者 。 
研究 分析 发现 : 
在 根据 临床试验 队列 和 观察 性 研究 做出 的 多 变量 模型 中 , TMN 分期 , MSI 和 BRAFV600E 基因突变 状态 仍然 是 独立 预后 因素 。 
单纯 TNM 模型 的 一致性 指数 ( Concordance - indices ) 为 0.61 - 0.68 , 而 增加 分子 标记 物 、 临床 病理 特征 和 所有 协 变量 后 的 
一致性 指数 分别 增加 至 0.63 - 0.71 、 0.65 - 0.73 和 0.66 - 0.74 。 
在 有 完整 注释 的 验证 队列 中 , 单独 TNM 的 综合 时间 依赖 AUC 值为 0.64 , 纳入 临床 病理 特征 联合 或 不 联合 分子 标记 物 的 AUC 增加 为 0.67 。 
在 接受 辅助 化疗 的 患者 队列 中 , 通过 TNM 、 临床 病理 特征 和 分子 标记 物 的 方差 ( R2 ) 相对 比例 平均值 分别 为 65% 、 25% 和 10% 。 
因此 , 将 MSI 、 BRAFV600E 和 KRAS 基因突变 状态 纳入 TNM 分期 系统 的 总 生存期 模型 可以 提高 精确 预测 II期 和 III期 结肠癌 患者 的 能力 , 
而且 包括 临床 病理 特征 的 多 变量 模型 中 会 增加 预测 准确性 , 特别 是 需要 接受 化疗 的 患者 。

1.2 准确分词 level2

有时候,即使加载了自定义词典,程序也不一定会按照词典来切分,这时候就需要调整词频了
例子
首先创建词典 dict.txt:

台中

写代码代码:

import jieba
import re

# 对dict.txt中的每个词都调整词频
[jieba.suggest_freq(line.strip(), tune=True) for line in open("dict.txt",'r',encoding='utf8')]

if __name__=="__main__":
    string = "台中正确应该不会被切开。"
    
    words=jieba.cut(string)
    result = " ".join(words)
    print(result)

没有第五行代码时的输出:

台 中 正确 应该 不会 被 切开 。

有第五行代码:

台中 正确 应该 不会 被 切开 。

emmm 有筒子可能看不懂第五行代码,提供一个简单版本:

fp=open("dict.txt",'r',encoding='utf8')
for line in fp:
    line=line.strip()
    jieba.suggest_freq(line, tune=True)

1.3 词性标注

hanlp的分词结果包含词性,每个词性的意思请查阅:http://www.hankcs.com/nlp/part-of-speech-tagging.html#h2-8
例子:
注意第四行代码需要换成你自己的hanlp文件夹路径

import os, gc, re, sys
from jpype import *

root_path = "H:" + os.sep + "software" + os.sep + "hanlp"  
djclass_path = "-Djava.class.path=" + root_path + os.sep + "hanlp-1.7.0.jar;" + root_path
startJVM(getDefaultJVMPath(), djclass_path, "-Xms1g", "-Xmx1g")

Tokenizer = JClass('com.hankcs.hanlp.tokenizer.StandardTokenizer')

sentence = '浮世万千,吾爱有三。日,月与卿。日为朝,月为暮,卿为朝朝暮暮。'

result = Tokenizer.segment(sentence)
print(type(result))
print(type(result[0]))
print(result)

output:

<class 'jpype._jclass.java.util.ArrayList'>
<class 'jpype._jclass.com.hankcs.hanlp.seg.common.Term'>
[浮世/nz, 万千/m, ,/w, 吾爱/nz, 有/vyou, 三/m, 。/w, 日/b, ,/w, 月/n, 与/cc, 卿/ng, 。/w, 日/b, 为/p, 朝/tg, ,/w, 月/n, 为/p, 暮/tg, ,/w, 卿为/nr, 朝朝暮暮/nz, 。/w]

可以用[(word_pos_item.toString().split('/')[0], word_pos_item.toString().split('/')[1]) for word_pos_item in Tokenizer.segment(sentence)]来对分词结果进行转化,变成一个list,每个元素为一个tuple,tuple的一个元素为单词(字符串格式),第二个元素为词性(字符串格式)。

有了上面的词性标注,就可以根据词性进行特定的筛选了

1.4 关键词提取

比较常用的算法有:TF-IDF算法,Text-Rank算法,主题模型算法(包括LSA,LSI,LDA等)

可以使用jieba中的textrank函数:

def textrank(self, sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'), withFlag=False):
    """
    Extract keywords from sentence using TextRank algorithm.
    Parameter:
        - topK: return how many top keywords. `None` for all possible words.
        - withWeight: if True, return a list of (word, weight);
                      if False, return a list of words.
        - allowPOS: the allowed POS list eg. ['ns', 'n', 'vn', 'v'].
                    if the POS of w is not in this list, it will be filtered.
        - withFlag: if True, return a list of pair(word, weight) like posseg.cut
                    if False, return a list of words
    """

使用示例:

# -*- coding=utf8 -*-
from jieba import analyse

# 原始文本
text = '揭秘谢亚龙被带走:总局电话骗局 复制南杨轨迹体坛周报特约记者张锐北京报道\xa0 谢亚龙已经被' \
       '公安部门正式宣布“立案侦查”,但谢亚龙等人是哪一天被辽宁警方带走的?又是如何被带走的?外界' \
       '有着很多种版本。但来自内部的消息显示,谢亚龙等人被带走,其实是与南、杨被带走时如出一辙。' \
       '9月3日(周五)下午4点左右,谢亚龙在中体产业办公室里接到了一个电话。这个电话来自于国家体育总' \
       '局,要求他赶往总局参加一个会议,至于会议内容并没有说明。对下属打了一声招呼之后,谢亚龙便' \
       '出了门。到了总局之后,谢才了解到“会议的内容”——辽宁警方在等待着他。没有任何预兆,谢亚龙被' \
       '警方带到了沈阳。这样的方式,与年初南杨二人被带走如出一辙。当时,南杨也是接到总局领导的电' \
       '话,要求连夜去参加一个紧急会议,一到总局便被辽宁警方带走。换而言之,警方带走谢亚龙等人,' \
       '总局领导事先是知情的。而中体产业则并不知情,他们起初接到的信息谢亚龙仅仅只是去总局开会。' \
       '所以,中体产业没有在第一时间发出谢亚龙协助调查的通告,后来在证监会的要求下才被动发出。外' \
       '界一直猜测谢亚龙是协查还是自己有事,直到12日上午才有了答案,公安部网站“治安新闻”中出现《' \
       '警方证实谢亚龙等被立案侦查》一文:“在侦办涉嫌利用足球比赛贿赂、赌博系列案件中,公安、检察' \
       '机关多渠道获取对原中国足协副主席谢亚龙、原中国足协裁判委员会主任李冬生、原国家足球队领队' \
       '蔚少辉等人涉案的线索和举报。在国家体育总局的配合下,专案组已依法对谢亚龙、李冬生、蔚少辉' \
       '立案侦查。”当天中午央视新闻频道的新闻节目中,也报道了谢亚龙等人被立案侦查的消息。下午5点' \
       '左右,各门户网站刊发了中国足协的声明:“公安机关依法对谢亚龙、李冬生、蔚少辉立案侦查,这' \
       '是彻底整肃足坛、依法打击足球假、赌、黑治理行动的继续。足管中心坚决贯彻落实总局‘治理足球' \
       '假、赌、黑违法犯罪行为,坚决惩治腐败,整顿足坛,坚决支持配合公安部门依法打击足球假、赌、' \
       '黑违法犯罪行为,绝不姑息’的要求,做好自身工作。”距谢亚龙等人被警方带走,已经有10天。根据' \
       '相关的法律,第14天(也就是9月16日)将会是一个“坎”,因为如果问题严重,在证据确凿的情况下,' \
       '“立案侦查”将有可能演变为“正式逮捕”。'
print("\nkeywords by textrank:")  # 基于TextRank算法进行关键词抽取

keywords = analyse.textrank(text, topK=10, withWeight=True, allowPOS=('ns', 'n'))

# 输出抽取出的关键词
words = [keyword for keyword, w in keywords if w > 0.2]
print(' '.join(words) + "\n")

输出:

keywords by textrank:
总局 警方 立案侦查 依法 公安 电话 产业 辽宁 会议 中体

猜你喜欢

转载自blog.csdn.net/alexkx/article/details/85048952