https://www.toutiao.com/article/7253039449725387316/
simplify_docx
在数据的世界里,文本数据是特别复杂的。它不像数字数据那样被分成整齐的行和列。作为一个副业,我正在开发自己的个人人工智能助手。其目的是利用我的笔记和文件中的数据来回答我的问题。重要的好处是,所有的数据处理都将在我的电脑上进行,确保没有文件被上传到云端,而且我的文件将保持隐私。
为了处理这种非结构化的数据,我发现unstructured的Python库非常有用。它是一个灵活的工具,可以处理各种文档格式,包括Markdown、、XML和HTML文档。
unstructured
从unstructured的开始
你可以通过以下方式轻松安装该库:
pip install unstructured
装载和分割文件
你想对你的文件做的第一件事是把它分割成更小的部分或章节。这个过程被称为分区,使其更容易分类和提取文本。
以下是你如何做的:
from unstructured.partition.auto import partition
elements = partition(filename="example-docs/note.md")
example-docs/note.md:
My test title
And here is a sample text.
当我们分割一个文档时,输出是一个文档元素对象的列表。这些元素对象代表了源文档的不同组成部分。unstructured库支持各种元素类型,包括Title, NarrativeText, 和ListItem。要访问元素类型,你可以使用category方法:
for element in elements:
print(f”{element.category}:”)
print(element)
print(“\n”)
Output:
Title
My test title
NarrativeText
And here is a sample text.
文档元素的列表可以用convert_to_dict函数转换为字典的列表:
from unstructured.staging.base import convert_to_dict
dict_data = convert_to_dict(elements)
Output:
[{'type': 'Title',
'coordinates': None,
'coordinate_system': None,
'layout_width': None,
'layout_height': None,
'element_id': 'a3114599252de55bea36c288aa9aa199',
'metadata': {'filename': 'sample-doc.md',
'filetype': 'text/markdown',
'page_number': 1},
'text': 'My test title'},
{'type': 'NarrativeText',
'coordinates': None,
'coordinate_system': None,
'layout_width': None,
'layout_height': None,
'element_id': '6e78562ede477550604528df644630e8',
'metadata': {'filename': 'sample-doc.md',
'filetype': 'text/markdown',
'page_number': 1},
'text': 'And here is a sample text.'}]
但由于我想把这些文本块存储在数据库中,并对数据进行一些探索性分析,所以我用
convert_to_dataframe函数把文本元素转换成pandas数据框架:
from unstructured.staging.base import convert_to_dataframe
df = convert_to_dataframe(elements)
获取元数据
unstructured库的一个整洁的特点是它如何跟踪它从文档中提取的元素的各种元数据。例如,你可能想知道哪些元素来自哪个页码。你可以像这样提取某个文档元素的元数据:
doc_metadata = elements[0].metadata.to_dict()
print(doc_metadata)
Output:
{‘filename’: ‘note.md’, ‘filetype’: ‘text/markdown’, ‘page_number’: 1}
当源文件中的信息可用时,所有文件类型都会返回以下元数据字段:filename、file_directory、date、filetype和page_number。
筹备Transformers
当你准备将你的文本送入转化器模型进行进一步处理时,你可以使用stage_for_transformers函数。这个函数通过将你的文本元素分割成适合模型注意力窗口的大块来准备。
在下面的例子中,我使用了一个叫做SentenceTransformers的库:
from sentence_transformers import SentenceTransformer
from unstructured.staging.huggingface import stage_for_transformers
model = SentenceTransformer("all-MiniLM-L6-v2")
chunked_elements = stage_for_transformers(elements, model.tokenizer)
And now I can load all the notes in a specific directory, so I can convert them to embedding vectors later:
all_elements = []
root_dir = '/corpus'
for directory, subdirectories, files in os.walk(root_dir):
for file in files:
full_path = os.path.join(directory, file)
all_elements += partition(filename=full_path)
unstructured的局限性
这个库也有一些问题和限制。
当加载和解析docx文件时,它不能正确地将子弹头识别为ListItem,大多数情况下将它们标记为NarrativeText或Title。这使得标题识别也不可靠,因为当你查看输出时,你无法确定每个标题实际上是一个标题还是一个被错误地标记为标题的列表项。(issue on github)当处理大型文档时,没有办法知道每个段落或标题的父类是什么。这可能是一个非常有用的功能,特别是在将数据反馈给LLM的时候。(issue on github)
替代品
在玩了unstructured之后,我试图看看是否有更好的替代品可以用python来阅读文档。虽然我需要加载各种格式的文件,但我缩小了搜索范围,首先找到阅读docx文件的替代品(因为这是你从Google Drive下载一大文件夹的文件时得到的格式)。以下是我找到的东西:
python-docx
它看起来很强大,但操作起来很复杂。
我试着加载和解析了几个docx文件。我遇到的最大问题是加载任何包含超链接的文本。由于某种未知的原因,超链接的文本在最后的输出中被返回为空。这使得它不能用于我的目的,因为链接文本提供了文本中的宝贵信息。
优点:它能够为标题提供标题级别的信息(如Heading 1、Heading 2等)。
docx2txt
它在hood下使用 python-docx。
只返回加载的文档的一个巨大的全文字符串。这就要求我把我的文档分割成有意义的小块,这可不是一件容易的事。
优点:它对超链接没有任何问题,而且输出的文本是可读的、有用的。
优点:它也非常容易使用。
simplify_docx
它在 python-docx 的基础上工作。
这个库基本上将python-docx的复杂输出转换为更容易使用的json输出。
它对超链接也有同样的问题,当段落中有一个链接时,会返回空文本。
所以我现在会继续使用unstructured。值得一提的是,使用LangChain或其他类似的工具可以更容易地完成这一点。然而,我建立这个个人AI助手的部分动机是学习之旅。通过使用unstructured加载文档和其他类似工具进行嵌入等,我对底层流程有了更深的了解,而不是使用LangChain这样的一站式解决方案。
我将在未来的文章中分享更多关于我在构建个人人工智能助手方面取得的进展,敬请关注。