一、基本信息

1.1 功能目录

:::success 🎯 从业以来,处理过的小场景,大部分来自GitHub的大神,结合自己的理解和项目需求进行修改,争取不做gitclone 工程师,涉及内容包括但不限于: 中英文敏感词、暴恐词表、繁简体转换、英文模拟中文发音、😍🤪 :::

二、项目简记

2.1 敏感词检测

AC树

2.2 车牌抽取

基于规则抽取车牌号实体 https://github.com/PyUnit/pyunit-plate

2.3 时间抽取

用于句子中时间词的抽取和转换, 主要基于Time_NLP做了部分优化 https://github.com/xiaoxiong74/Time-Extractor
一般处理文本,例如新闻,对于包含多个时间,需要有一定的策略判断。

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import re
  4. from flask.globals import g
  5. import time
  6. from timing.TimeNormalizer import TimeNormalizer # 引入包
  7. tn = TimeNormalizer()
  8. TARGET_REGULAR = "[u'报'|u'报道']"
  9. '''利用标点符号,将文章进行短句切分处理'''
  10. def seg_short_content(content):
  11. return [sentence for sentence in re.split(r'[,,??!!。;;\n\r\t ]', content) if sentence]
  12. '''选择最早的规范的时间'''
  13. def selectEarliestTime(tu_arr):
  14. res = []
  15. # restime = tu_arr[0].time.format("YYYY-MM-DD HH:mm")
  16. # timegap = time.time()-tu_arr[0].time.timestamp
  17. for tu in tu_arr[1:]:
  18. # print("deng,", tu.time.format("YYYY-MM-DD HH:mm"))
  19. if tu.time.timestamp == 0:
  20. continue
  21. if not re.findall("\d+", tu.exp_time): # 去掉早上、目前等模糊时间
  22. continue
  23. rtime = sorted(res, key=lambda tu: tu.time.format("YYYY-MM-DD HH:mm"))
  24. # print("sort for ealiest time: ", rtime)
  25. for rt in rtime:
  26. if rt.norm_tunit[3] != -1: #如果时间有小时,那么就提前
  27. rtime.lappend(rt)
  28. if not rtime:
  29. return selectIntegralTime(tu_arr)
  30. return rtime[0].time.format("YYYY-MM-DD HH:mm")
  31. '''选择描述最为完整的时间'''
  32. def selectIntegralTime(tu_arr):
  33. res = []
  34. best_count = 0
  35. for tu in tu_arr:
  36. if tu.time.timestamp != 0:
  37. tmp_count = 0
  38. for i in range(0, 6): # 年、月、日、时、分、秒
  39. if tu.norm_tunit[i] != -1:
  40. tmp_count += 1
  41. if tmp_count > best_count:
  42. res = [tu.time.format("YYYY-MM-DD HH:mm")]
  43. best_count = tmp_count
  44. elif tmp_count == best_count:
  45. res.append(tu.time.format("YYYY-MM-DD HH:mm"))
  46. if not res:
  47. return tu_arr[0].time.format("YYYY-MM-DD HH:mm")
  48. rtime = sorted(res) # 填充的槽值相同,则选择最早的时间
  49. return rtime[0]
  50. '''选择离主干句子最近的时间'''
  51. def selectNearestTime(tu_arr, text, titles):
  52. if not titles:
  53. return tu_arr[0].time.format("YYYY-MM-DD HH:mm")
  54. rt = ""
  55. best_dist = len(text)
  56. s_title = text.find(titles[0][0])
  57. t_title = s_title + len(titles[0][0])
  58. print(titles[0][0], s_title, t_title)
  59. for tu in tu_arr:
  60. if tu.time.timestamp == 0:
  61. continue
  62. s_time = text.find(tu.exp_time)
  63. t_time = s_time + len(tu.exp_time)
  64. if s_time >= s_title and t_time <= t_title:
  65. return tu.time.format("YYYY-MM-DD HH:mm")
  66. if not re.findall("\d+", tu.exp_time) or tu.norm_tunit[3] == -1: # 需要明确是几时
  67. continue
  68. if s_time >= t_title:
  69. tmp = abs(s_time - t_title)
  70. if t_time <= s_title:
  71. tmp = abs(s_time - t_title)
  72. if tmp < best_dist:
  73. best_dist = tmp
  74. print(tu.exp_time, s_time, t_time, best_dist)
  75. rt = tu.time.format("YYYY-MM-DD HH:mm")
  76. print(rt, best_dist)
  77. if not rt:
  78. rt = tu_arr[0].time.format("YYYY-MM-DD HH:mm")
  79. return rt
  80. '''正则去掉报道时间'''
  81. def delReportTime(text):
  82. rtime = []
  83. subsents = seg_short_content(text)
  84. if subsents:
  85. if re.findall(TARGET_REGULAR + "+$", "".join(subsents[0])) != []:
  86. rtime = tn.parse(target=subsents[0])
  87. if rtime:
  88. subsents.pop(0)
  89. if not rtime and len(subsents) > 1:
  90. if re.findall(TARGET_REGULAR + "+$", "".join(subsents[1])) != []:
  91. rtime = tn.parse(target=subsents[0] + "," + subsents[1])
  92. if rtime:
  93. subsents.pop(1)
  94. subsents.pop(0)
  95. try:
  96. text = ",".join(subsents)
  97. if rtime:
  98. rt = tn.parse(target=text, timeBase=rtime[-1].time.format('YYYY-MM-DD HH:mm:ss'))
  99. if not rt:
  100. rt = rtime
  101. else:
  102. rt = tn.parse(target=text)
  103. except:
  104. print("Error:时间格式不符合规范!")
  105. rt = []
  106. return rt
  107. '''根据标题选择时间'''
  108. def getTimewithTitle(text, titles):
  109. res = tn.parse(target=text)
  110. if len(res) == 0:
  111. rtime = ""
  112. elif len(res) == 1:
  113. rtime = res[0].time.format("YYYY-MM-DD HH:mm")
  114. else:
  115. rtime = selectNearestTime(res, text, titles) # 选择离标题最近的时间
  116. return rtime
  117. def getTime4resp(text):
  118. text = text.replace(" ", ",") # [2021/2/2 22:30] 替换时间的空格
  119. # text=re.sub("[a-zA-Z]+://[^\s]*[.com|.cn|.html]","",text)
  120. res = tn.parse(target=text) # 不去报道时间
  121. # res = delReportTime(text) # 去掉报道时间
  122. if len(res) == 0:
  123. rtime = ""
  124. elif len(res) == 1:
  125. rtime = res[0].time.format("YYYY-MM-DD HH:mm")
  126. else:
  127. # rtime = selectIntegralTime(res) # 选择最完整的时间
  128. rtime = selectEarliestTime(res) # 选择最早的符合规范的时间
  129. return rtime

2.4 地址抽取

PyUnit-Address https://github.com/PyUnit/pyunit-address

  1. pip install pyunit-address

2.5 标题抽取/摘要生成/文章缩减

TextRank算法可以用来从文本中提取关键词和摘要(重要的句子)。TextRank4ZH是针对中文文本的TextRank算法的python算法实现。https://github.com/letiantian/TextRank4ZH

2.6 中文纠错

包含n-gram以及双向lstm语言模型 https://github.com/zedom1/error-detection
pycorrector https://github.com/shibing624/pycorrector
中文文本纠错任务,常见错误类型包括:

  • 谐音字词,如 配副眼睛-配副眼镜
  • 混淆音字词,如 流浪织女-牛郎织女
  • 字词顺序颠倒,如 伍迪艾伦-艾伦伍迪
  • 字词补全,如 爱有天意-假如爱有天意
  • 形似字错误,如 高梁-高粱
  • 中文拼音全拼,如 xingfu-幸福
  • 中文拼音缩写,如 sz-深圳
  • 语法错误,如 想象难以-难以想象

    2.7 繁简转换

    python https://github.com/Tim9Liu9/py_change_code
    SimpleChinese2 https://github.com/chenmingxiang110/SimpleChinese2

  • 文字预处理

  • 繁体简体转换
  • 拼音文字转换
  • 姓名生成

    三、工具记录

    3.1 paddleNLP

    https://github.com/PaddlePaddle/PaddleNLP
    PaddleNLP是飞桨自然语言处理开发库,具备易用的文本领域API,多场景的应用示例、和高性能分布式训练三大特点,旨在提升开发者在文本领域的开发效率,并提供丰富的NLP应用示例。
    以python 作为镜像,安装PaddleNLP 的docker 镜像将近1.8G。
    在命名实体识别方面,该工具非常好。 ```python from paddlenlp import Taskflow

中文分词

seg = Taskflow(“word_segmentation”) seg(“第十四届全运会在西安举办”)

[‘第十四届’, ‘全运会’, ‘在’, ‘西安’, ‘举办’]

词性标注

tag = Taskflow(“pos_tagging”) tag(“第十四届全运会在西安举办”)

[(‘第十四届’, ‘m’), (‘全运会’, ‘nz’), (‘在’, ‘p’), (‘西安’, ‘LOC’), (‘举办’, ‘v’)]

命名实体识别

ner = Taskflow(“ner”) ner(“《孤女》是2010年九州出版社出版的小说,作者是余兼羽”)

[(‘《’, ‘w’), (‘孤女’, ‘作品类实体’), (‘》’, ‘w’), (‘是’, ‘肯定词’), (‘2010年’, ‘时间类’), (‘九州出版社’, ‘组织机构类’), (‘出版’, ‘场景事件’), (‘的’, ‘助词’), (‘小说’, ‘作品类概念’), (‘,’, ‘w’), (‘作者’, ‘人物类概念’), (‘是’, ‘肯定词’), (‘余兼羽’, ‘人物类实体’)]

句法分析

ddp = Taskflow(“dependency_parsing”) ddp(“9月9日上午纳达尔在亚瑟·阿什球场击败俄罗斯球员梅德韦杰夫”)

[{‘word’: [‘9月9日’, ‘上午’, ‘纳达尔’, ‘在’, ‘亚瑟·阿什球场’, ‘击败’, ‘俄罗斯’, ‘球员’, ‘梅德韦杰夫’], ‘head’: [2, 6, 6, 5, 6, 0, 8, 9, 6], ‘deprel’: [‘ATT’, ‘ADV’, ‘SBV’, ‘MT’, ‘ADV’, ‘HED’, ‘ATT’, ‘ATT’, ‘VOB’]}]

情感分析

senta = Taskflow(“sentiment_analysis”) senta(“这个产品用起来真的很流畅,我非常喜欢”)

[{‘text’: ‘这个产品用起来真的很流畅,我非常喜欢’, ‘label’: ‘positive’, ‘score’: 0.9938690066337585}]

  1. <a name="eJwA0"></a>
  2. ## 3.3 synonyms
  3. [https://github.com/chatopera/Synonyms](https://github.com/chatopera/Synonyms)<br />提取关键词
  4. ```python
  5. import synonyms
  6. print("人脸: ", synonyms.nearby("人脸"))
  7. print("识别: ", synonyms.nearby("识别"))
  8. print("NOT_EXIST: ", synonyms.nearby("NOT_EXIST"))
  9. synonyms.nearby(人脸, 10) = (
  10. ["图片", "图像", "通过观察", "数字图像", "几何图形", "脸部", "图象", "放大镜", "面孔", "Mii"],
  11. [0.597284, 0.580373, 0.568486, 0.535674, 0.531835, 0.530
  12. 095, 0.525344, 0.524009, 0.523101, 0.516046])

句子相似度,领域数据亲测效果不佳

  1. sen1 = "发生历史性变革"
  2. sen2 = "发生历史性变革"
  3. r = synonyms.compare(sen1, sen2, seg=True)
  4. 旗帜引领方向 vs 道路决定命运: 0.429
  5. 旗帜引领方向 vs 旗帜指引道路: 0.93
  6. 发生历史性变革 vs 发生历史性变革: 1.0

打印近义词 ```python synonyms.display(“飞机”) ‘飞机’近义词:

  1. 飞机:1.0
  2. 直升机:0.8423391
  3. 客机:0.8393003
  4. 滑翔机:0.7872388
  5. 军用飞机:0.7832081
  6. 水上飞机:0.77857226
  7. 运输机:0.7724742
  8. 航机:0.7664748
  9. 航空器:0.76592904
  10. 民航机:0.74209654
  1. 获得词向量,该向量为 numpy array,当该词语是未登录词时,抛出 KeyError 异常。
  2. ```python
  3. >>> synonyms.v("飞机")
  4. array([-2.412167 , 2.2628384 , -7.0214124 , 3.9381874 , 0.8219283 ,
  5. -3.2809453 , 3.8747153 , -5.217062 , -2.2786229 , -1.2572327 ],
  6. dtype=float32)

中文分词

  1. synonyms.seg("中文近义词工具包")
  2. >>>(['中文', '近义词', '工具包'], ['nz', 'n', 'n'])

提取关键词

  1. keywords = synonyms.keywords("9月15日以来,台积电、高通、三星等华为的重要合作伙伴,只要没有美国的相关许可证,都无法供应芯片给华为,而中芯国际等国产芯片企业,也因采用美国技术,而无法供货给华为。目前华为部分型号的手机产品出现货少的现象,若该形势持续下去,华为手机业务将遭受重创。")


英文状态下,输入 :::success 之后按下回车键,可以输入绿色的提示区块~

:::success 👍 :::

输入 :::danger 之后按下回车键。可输入红色的提示区块,其他可以点击了解更多

:::danger 💪

:::

四、项目致谢