中文文本分析, Text-Analysis
Text-Analysis包括analysis-word 词语分析和analysis-classify 文本分类数据分析等, 支持python3读写word的docx格式(包括字体/颜色/高亮)、读pdf等。
analysis-word 词语分析
介绍
analysis_word可用于无监督分析多文件语料(HTML/PDF/DOCX/DOC/TXT/MD), 支持docx高亮抽取-读写、新词发现、中文分词、TFIDF、词向量、词语聚类、句子聚类等功能。
地址
github地址: https://github.com/yongzhuo/Text-Analysis
详情
各个文件(夹)详情
- keywords/keywords_common.txt 通用词, 可自己加, 用于高亮成其他颜色
- keywords/keywords_field.txt 已有领域词, 可自己加, 用于高亮成其他颜色
- keywords/keywords_newword.txt 新词发现, 自动生成, 用于高亮成其他颜色
- w00_transfer_file_to_txt.py 将目录下文件(支持HTML/PDF/DOCX/DOC/TXT/MD)提取为TXT文件
- w01_find_newword_txt.py 新词发现, 生成每个文件对应的"xlsx"文件、和一个汇总的xlsx文件, 存储到"新词发现"目录
- w02_cut_word_to_txt.py 中文分词, 生成每个文件对应的".切词.txt"文件、和一个汇总的"汇总大文本.md"文件, 存储到"中文分词"目录
- w03_transfer_to_doc.py 中文分词docx, 生成每个文件对应的".切词.docx"文件, 方便高亮和查看, 存储到"中文分词docx"目录
- w04_tfidf_xlsx.py TFIDF, 生成"汇总TFIDF.xlsx"文件, 包括tf/idf/tf-idf等列, 存储到"TFIDF"目录
- w05_train_w2v.py 词向量, 训练w2v词向量, 生成"w2v.vec"文件, 存储到"词向量"目录
- w06_cluster_w2v.py 词语聚类, w2v词向量作为距离, 支持K-MEANS/DBSCAN算法, 生成"xlsx"文件, 存储到"词语聚类"目录
- w07_cluster_sen.py 句子聚类, w2v词向量/TFIDF作为距离, 支持K-MEANS/DBSCAN算法, 生成"xlsx"文件, 存储到"句子聚类"目录
- w08_extract_highligt_doc.py 抽取高亮, 抽取原docx文件中标注的高亮词语/句子等, 生成"汇总高亮文本.md"文件, 存储到"高亮语料"目录
- w100_main.py 主函数
- word_discovery.py 新词发现代码
快速使用
python w100_main.py
使用方式
简单样例
1. 必选, 配置文件所在目录,
- 1.1 可以选择在text_analysis/word_analysis/w100_main.py文件中配置地址, 包括 原始语料文件目录(需要存在文件) 和 分析结果文件目录
- 1.2 也可以将文件(支持HTML/PDF/DOCX/DOC/TXT/MD)置于目录text_analysis/data/corpus/原始语料下
- 1.1、1.2任选一种方式就好
2. 可选, 配置通用词/专业词等
- keywords/keywords_common.txt 通用词, 可自己加, 用于高亮成其他颜色
- keywords/keywords_field.txt 已有领域词, 可自己加, 用于高亮成其他颜色
3. 必选, 运行主函数, 例如 python w100_main.py
部分代码
python3读取word文档的docx格式(分段,包括文本和表格数据等)
def docx_read(path):
"""读取word文档的段落数据text/table, docx
read corpus from docx
Args:
path: String, path/origin text, eg. "叉尾斗鱼介绍.docx"
Returns:
passages: List<tuple>, 文章段落
"""
def iter_tables(block_item_container):
"""Recursively generate all tables in `block_item_container`."""
for t in block_item_container.tables:
yield t
for row in t.rows:
for cell in row.cells:
yield from iter_tables(cell)
passages = []
try:
import docx
docx_temp = docx.Document(path)
# 文本
for p in docx_temp.paragraphs:
if p.text.strip():
passages.append(p.text.strip()+"\n")
# 表格
for t in iter_tables(docx_temp):
table = t
df = [["" for i in range(len(table.columns))] for j in range(len(table.rows))]
for i, row in enumerate(table.rows):
for j, cell in enumerate(row.cells):
if cell.text:
df[i][j] = cell.text.replace("\n", "")
df = [" ".join(dfi).strip() + "\n" for dfi in df]
passages += df
except Exception as e:
logger.info(str(e))
return passages
python3读取PDF(分段)
def pdf_read(path):
"""读取pdf文档的段落数据text/table, docx
read corpus from docx
Args:
path: String, path/origin text, eg. "叉尾斗鱼介绍.pdf"
Returns:
passages: List<tuple>, 文章段落
"""
passages = []
try:
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfpage import PDFPage
from pdfminer.layout import LAParams
from io import StringIO
output_string = StringIO()
with open(path, "rb") as prb:
parser = PDFParser(prb)
doc = PDFDocument(parser)
rsrcmgr = PDFResourceManager()
device = TextConverter(rsrcmgr, output_string, laparams=LAParams())
interpreter = PDFPageInterpreter(rsrcmgr, device)
for page in PDFPage.create_pages(doc):
interpreter.process_page(page)
passages = output_string.getvalue()
except Exception as e:
logger.info(str(e))
return passages
python3读取高亮的docx
def docx_extract_color(path, highligt_colors=["YELLOW"]):
"""抽取docx文档中高亮的text, 没有table
docx extract color
Args:
path: String, path/origin text, eg. "叉尾斗鱼介绍.docx"
highligt_colors: List, enum/highligt colors, eg. ["YELLOW", "RED"]
Returns:
passages: List<tuple>, 文章段落
"""
passages = []
try:
from docx.enum.text import WD_COLOR_INDEX
import docx
wd_colors_dict = {wcim.name:wcim.value for wcim in WD_COLOR_INDEX.__members__[2:]}
wd_colors_select = [wd_colors_dict.get(hc.upper(), "") for hc in highligt_colors
if wd_colors_dict.get(hc.upper(), "")]
"""
# AUTO = 'default'
BLACK = 'black'
BLUE = 'blue'
BRIGHTGREEN = 'green'
DARKBLUE = 'darkBlue'
DARKRED = 'darkRed'
DARKYELLOW = 'darkYellow'
GRAY25 = 'lightGray'
GRAY50 = 'darkGray'
GREEN = 'darkGreen'
PINK = 'magenta'
RED = 'red'
TEAL = 'darkCyan'
TURQUOISE = 'cyan'
VOILET = 'darkMagenta'
WHITE = 'white'
YELLOW = 'yellow'
"""
document = docx.Document(path)
for paragraph in document.paragraphs:
for run in paragraph.runs:
if run.font.highlight_color and run.font.highlight_color in wd_colors_select:
passages.append(run.text.strip()+"\n")
elif not highligt_colors and not run.font.highlight_color:
passages.append(run.text.strip()+"\n")
except Exception as e:
logger.info(str(e))
return passages
写入高亮的docx
def write_txt_to_docx(path_out, texts, keywords_field=None, keywords_common=None, keywords_newword=None):
"""将txt写入docx文档
write txt to docx
Args:
path_out: String, path_out/origin text, eg. "切词.docx"
texts: List, text, eg. ["你/是/谁/呀"]
keywords_field: List, text, eg. ["金融社保卡"]
keywords_common: List, text, eg. ["北京"]
Returns:
None
"""
from docx.shared import Inches, RGBColor, Pt
from docx.enum.text import WD_COLOR_INDEX
from docx import Document
from tqdm import tqdm
import re
def extract_string(text, regx="###"):
"""抽取string中间的特定字符串
extract string
Args:
text: String, path_in_dicr/origin text, eg. "dir_txt"
regx: String, path_save_dir/save text, eg. "dir_txt_cut"
Returns:
text_ext: List<str>
"""
pattern = r"{}(.*?){}".format(regx, regx)
text_ext = re.findall(pattern, text)
return text_ext
document = Document()
count = 0
for passage in tqdm(texts):
if not passage.strip():
continue
count += 1
if count % 2 == 0:
document.add_paragraph("\n")
document.add_paragraph(passage.replace("/", ""))
document.add_paragraph("【")
words = passage.split("/")
"""
AUTO = 'default'
BLACK = 'black'
BLUE = 'blue'
BRIGHTGREEN = 'green'
DARKBLUE = 'darkBlue'
DARKRED = 'darkRed'
DARKYELLOW = 'darkYellow'
GRAY25 = 'lightGray'
GRAY50 = 'darkGray'
GREEN = 'darkGreen'
PINK = 'magenta'
RED = 'red'
TEAL = 'darkCyan'
TURQUOISE = 'cyan'
VOILET = 'darkMagenta'
WHITE = 'white'
YELLOW = 'yellow'
"""
par = document.paragraphs[-1]
for w in words:
par.add_run(text="/")
par.add_run(text=w)
run = par.runs[-1]
# run.font.style = "宋体" # 文字大小
run.font.size = Pt(10) # 文字大小
if len(w) == 1:
run.font.highlight_color = WD_COLOR_INDEX.DARK_YELLOW
elif w in keywords_newword:
run.font.highlight_color = WD_COLOR_INDEX.BRIGHTGREEN
elif w in keywords_field:
run.font.highlight_color = WD_COLOR_INDEX.YELLOW
elif w in keywords_common:
run.font.highlight_color = WD_COLOR_INDEX.GREEN
else:
run.font.highlight_color = None # WD_COLOR_INDEX.RED
document.save(path_out)
参考
This library is inspired by and references following frameworks and papers.
- python-docx: https://github.com/python-openxml/python-docx
- pdfminer.six: https://github.com/pdfminer/pdfminer.six
- scikit-learn: https://github.com/scikit-learn/scikit-learn
- tqdm: https://github.com/tqdm/tqdm
Reference
For citing this work, you can refer to the present GitHub project. For example, with BibTeX:
@software{Text-Analysis,
url = {https://github.com/yongzhuo/Text-Analysis},
author = {Yongzhuo Mo},
title = {Text-Analysis},
year = {2021}
可进行的数据探索
一、纯粹NLP任务场景
-
1.0 通用组件(标注语料/未标注语料都可以)
- 文本长度分布: 最长, 最短, 中位数, 均值, 90%, 95%, 绘制曲线/箱型图;
- 标签分布: 样本sample个数分布, 标签(以及同义词)在文本的频次分布统计;
- 新词发现: 计算tf/idf/tfidf/左右熵/凝固度等, 生成一个xlsx文件;
- 关键词/关键句: textrank等关键词抽取, 按照词频排序;
- 共现分析/频繁项挖掘(很耗时): 句子共现/关联规则;
- 聚类: k-means距离聚类, DBSCN密度聚类等;
- 情感/否定分析(词典/模型等): 正负或者多个, 给出预测数据, 可基于情感词典, 或者是训练好的模型;
- 依存分析: 依存句法分析, 可以统计句式; 最新的AMR任务;
-
1.1 文本分类任务
- tfidf + lr跑完baseline, 探查任务难度;
-
1.2 实体任务
- 1.2.1 实体识别
- 各实体分布统计
- 实体长度分布统计
- 1.2.2 实体链指
- key-value频次长度统计
- 1.2.3 实体消歧
- 1.2.1 实体识别
-
1.3 关系任务
- 1.3.1 实体关系联合抽取
- 各实体分布统计
- 实体长度分布统计
- 关系标签label长度分布
- 关系标签label的类别分布
- 1.3.2 关系预测
- 类似于文本分类任务, 不过要加上的是实体长度/分布统计
- 1.3.1 实体关系联合抽取
-
1.4 文本相似度任务
- 1.4.1 句子相似度
- 两句子长度, 类别数
- 1.4.2 词语相似度
- topk
- 1.4.1 句子相似度
-
1.5 文本摘要
- 1.5.1 抽取式
- 是摘要的句子, 0/1, 或者是排序
- 1.5.2 生成式
- auto模式
- 1.5.1 抽取式
希望对你有所帮助!