【LangChain】Подключение для передачи данных

обзор

Многим LLMприложениям требуются специфичные для пользователя данные, которые не являются частью обучающего набора модели. LangChain предоставляет вам строительные блоки для загрузки, преобразования, хранения и запроса данных посредством:

  • Загрузчики документов: загружайте документы из разных источников.
  • Преобразователи документов: разделяйте документы, конвертируйте документы в формат вопросов и ответов, удаляйте лишние документы и т. д.
  • Модели внедрения текста: получите неструктурированный текст и преобразуйте его в список чисел с плавающей запятой.
  • Хранилища векторов: хранение и поиск встроенных данных.
  • Ретриверы: запросите ваши данные

Вставьте сюда описание изображения

Загрузчики документов (загрузка документов)

Используйте загрузчик документов для загрузки данных из источника документа. Документ — это фрагмент текста и связанные с ним метаданные. Например, существуют загрузчики документов, которые могут загружать простой .txt 文件текстовый контент с любой веб-страницы, или даже скрипты, загружающие видео с YouTube.

Загрузчик документов предоставляет метод «загрузки» для загрузки данных в виде документа из настроенного источника. У них также есть возможность реализовать «отложенную загрузку», чтобы данные загружались в память лениво.

Загрузить файл

Самый простой загрузчик читает файл как текст и помещает его все в один документ.

from langchain.document_loaders import TextLoader

loader = TextLoader("./index.md")
loader.load()

результат:

[
    Document(page_content='---\nsidebar_position: 0\n---\n# Document loaders\n\nUse document loaders to load data from a source as `Document`\'s. A `Document` is a piece of text\nand associated metadata. For example, there are document loaders for loading a simple `.txt` file, for loading the text\ncontents of any web page, or even for loading a transcript of a YouTube video.\n\nEvery document loader exposes two methods:\n1. "Load": load documents from the configured source\n2. "Load and split": load documents from the configured source and split them using the passed in text splitter\n\nThey optionally implement:\n\n3. "Lazy load": load documents into memory lazily\n', metadata={
    
    'source': '../docs/docs_skeleton/docs/modules/data_connection/document_loaders/index.md'})
]

1. Загрузите файл CSV.

Файл значений, разделенных запятыми (CSV), представляет собой текстовый файл с разделителями, в котором используются значения, разделенные запятыми. Каждая строка файла представляет собой запись данных. Каждая запись состоит из одного или нескольких полей, разделенных запятыми.

Загрузка данных CSV: каждая строка представляет собой документ.

from langchain.document_loaders.csv_loader import CSVLoader

loader = CSVLoader(file_path='./example_data/mlb_teams_2012.csv')
data = loader.load()
print(data)

результат:

    [Document(page_content='Team: Nationals\n"Payroll (millions)": 81.34\n"Wins": 98', lookup_str='', metadata={
    
    'source': './example_data/mlb_teams_2012.csv', 'row': 0}, lookup_index=0), Document(page_content='Team: Reds\n"Payroll (millions)": 82.20\n"Wins": 97', lookup_str='', metadata={
    
    'source': './example_data/mlb_teams_2012.csv', 'row': 1}, lookup_index=0), Document(page_content='Team: Yankees\n"Payroll (millions)": 197.96\n"Wins": 95', lookup_str='', metadata={
    
    'source': './example_data/mlb_teams_2012.csv', 'row': 2}, lookup_index=0), Document(page_content='Team: Giants\n"Payroll (millions)": 117.62\n"Wins": 94', lookup_str='', metadata={
    
    'source': './example_data/mlb_teams_2012.csv', 'row': 3}, lookup_index=0)]

Пользовательский анализ и загрузка CSV

Дополнительную информацию о том, какие параметры csv поддерживаются, см. в документации модуля csv .

# 注意csv_args参数
loader = CSVLoader(file_path='./example_data/mlb_teams_2012.csv', csv_args={
    
    
    'delimiter': ',',
    'quotechar': '"',
    'fieldnames': ['MLB Team', 'Payroll in millions', 'Wins']
})

data = loader.load()
print(data)

результат:

[Document(page_content='Team: Nationals\n"Payroll (millions)": 81.34\n"Wins": 98', lookup_str='', metadata={
    
    'source': './example_data/mlb_teams_2012.csv', 'row': 0}, lookup_index=0), Document(page_content='Team: Reds\n"Payroll (millions)": 82.20\n"Wins": 97', lookup_str='', metadata={
    
    'source': './example_data/mlb_teams_2012.csv', 'row': 1}, lookup_index=0), Document(page_content='Team: Yankees\n"Payroll (millions)": 197.96\n"Wins": 95', lookup_str='', metadata={
    
    'source': './example_data/mlb_teams_2012.csv', 'row': 2}, lookup_index=0), Document(page_content='Team: Giants\n"Payroll (millions)": 117.62\n"Wins": 94', lookup_str='', metadata={
    
    'source': './example_data/mlb_teams_2012.csv', 'row': 3}, lookup_index=0)]

Укажите столбец для идентификации источника документа

Используйте source_columnпараметр, чтобы указать источник, из которого создается документ для каждой строки. В противном случае используйте file_pathполе в качестве источника.

Это полезно при использовании CSV 文件документа, загруженного из цепочки, отвечающего на вопрос.sources

loader = CSVLoader(file_path='./example_data/mlb_teams_2012.csv', source_column="Team")

data = loader.load()
print(data)

результат:

[Document(page_content='Team: Nationals\n"Payroll (millions)": 81.34\n"Wins": 98', lookup_str='', metadata={
    
    'source': 'Nationals', 'row': 0}, lookup_index=0), Document(page_content='Team: Reds\n"Payroll (millions)": 82.20\n"Wins": 97', lookup_str='', metadata={
    
    'source': 'Reds', 'row': 1}, lookup_index=0), Document(page_content='Team: Yankees\n"Payroll (millions)": 197.96\n"Wins": 95', lookup_str='', metadata={
    
    'source': 'Yankees', 'row': 2}, lookup_index=0), Document(page_content='Team: Giants\n"Payroll (millions)": 117.62\n"Wins": 94', lookup_str='', metadata={
    
    'source': 'Giants', 'row': 3}, lookup_index=0)]

2. Каталог файлов

Как загрузить все документы в каталог. По умолчанию используется UnstructedLoader.

from langchain.document_loaders import DirectoryLoader

Мы можем использовать globэтот параметр, чтобы контролировать, какие файлы загружаются. Обратите внимание, что здесь не загружаются .rstфайлы или .htmlфайлы.

loader = DirectoryLoader('../', glob="**/*.md")
docs = loader.load()
len(docs)

Показать индикатор выполнения

По умолчанию индикатор выполнения не отображается. Чтобы отобразить индикатор выполнения, установите tqdm 库(т. е. выполните: pip install tqdm) и show_progressустановите параметры True.

# 注意show_progress参数
loader = DirectoryLoader('../', glob="**/*.md", show_progress=True)
docs = loader.load()

результат:

    Requirement already satisfied: tqdm in /Users/jon/.pyenv/versions/3.9.16/envs/microbiome-app/lib/python3.9/site-packages (4.65.0)

# 进度条
    0it [00:00, ?it/s]

Используйте многопоточность

По умолчанию загрузка происходит в потоке. Чтобы воспользоваться преимуществами нескольких потоков, use_multithreadingустановите флаг true.

# 使用多线程进行加载:use_multithreading=True
loader = DirectoryLoader('../', glob="**/*.md", use_multithreading=True)
docs = loader.load()

Изменить класс загрузчика

По умолчанию UnstructedLoader类загрузка осуществляется с помощью . Однако вы можете легко изменить тип загрузчика.

from langchain.document_loaders import TextLoader
# loader_cls指定加载器类
loader = DirectoryLoader('../', glob="**/*.md", loader_cls=TextLoader)
docs = loader.load()
len(docs)
# 结果
    1

Если вам нужно загрузить Python源代码файл, используйте PythonLoader.

from langchain.document_loaders import PythonLoader
# loader_cls指定python加载器类
loader = DirectoryLoader('../../../../../', glob="**/*.py", loader_cls=PythonLoader)
docs = loader.load()
len(docs)
# 结果
    691

Автоматическое определение кодировки файлов с помощью TextLoader

В этом примере мы увидим некоторые стратегии, которые полезны при использовании класса TextLoader для загрузки большого количества произвольных файлов из каталога.

path = '../../../../../tests/integration_tests/examples'
loader = DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader)

А. Поведение по умолчанию

loader.load()

результат:

<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace"><span style="color: #800000; text-decoration-color: #800000">╭─────────────────────────────── </span><span style="color: #800000; text-decoration-color: #800000; font-weight: bold">Traceback </span><span style="color: #bf7f7f; text-decoration-color: #bf7f7f; font-weight: bold">(most recent call last)</span><span style="color: #800000; text-decoration-color: #800000"> ────────────────────────────────╮</span>
<span style="color: #800000; text-decoration-color: #800000"></span> <span style="color: #bfbf7f; text-decoration-color: #bfbf7f">/data/source/langchain/langchain/document_loaders/</span><span style="color: #808000; text-decoration-color: #808000; font-weight: bold">text.py</span>:<span style="color: #0000ff; text-decoration-color: #0000ff">29</span> in <span style="color: #00ff00; text-decoration-color: #00ff00">load</span>                             <span style="color: #800000; text-decoration-color: #800000"></span>
<span style="color: #800000; text-decoration-color: #800000"></span>  
<span style="color: #ff0000; text-decoration-color: #ff0000; font-weight: bold">RuntimeError: </span>Error loading ..<span style="color: #800080; text-decoration-color: #800080">/../../../../tests/integration_tests/examples/</span><span style="color: #ff00ff; text-decoration-color: #ff00ff">example-non-utf8.txt</span>
</pre>

Опущено выше

В файле example-non-utf8.txt используется другая кодировка, и load()функция завершается с ошибкой, выдавая полезное сообщение, указывающее, какой файл не удалось декодировать.

При TextLoaderповедении по умолчанию любая неудачная загрузка документа приводит к сбою всего процесса загрузки и никакие документы не загружаются.

Б. Тихий провал

Мы можем silent_errorsпередать параметры, чтобы DirectoryLoaderпропустить файлы, которые не могут быть загружены, и продолжить процесс загрузки.

# 指定参数:silent_errors,跳过无法加载的文件
loader = DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader, silent_errors=True)
docs = loader.load()

результат:

    Error loading ../../../../../tests/integration_tests/examples/example-non-utf8.txt

Таким образом, когда мы загружаем несколько файлов:

doc_sources = [doc.metadata['source']  for doc in docs]
doc_sources

как результат:

    ['../../../../../tests/integration_tests/examples/whatsapp_chat.txt',
     '../../../../../tests/integration_tests/examples/example-utf8.txt']

C. Автоматическое определение кодировок

Мы также можем потребовать автоматическое определение кодировки файла перед сбоем , autodetect_encodingперейдя к классу-загрузчику .TextLoader

# 指定autodetect_encoding 参数,自动检测文件编码
text_loader_kwargs={
    
    'autodetect_encoding': True}
loader = DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader, loader_kwargs=text_loader_kwargs)
docs = loader.load()

doc_sources = [doc.metadata['source']  for doc in docs]
doc_sources

результат:

    ['../../../../../tests/integration_tests/examples/example-non-utf8.txt',
     '../../../../../tests/integration_tests/examples/whatsapp_chat.txt',
     '../../../../../tests/integration_tests/examples/example-utf8.txt']

3.HTML

Как загрузить HTML-документ в формат документа, который мы можем использовать в дальнейшем.

from langchain.document_loaders import UnstructuredHTMLLoader
loader = UnstructuredHTMLLoader("example_data/fake-content.html")
data = loader.load()
data

результат:

    [Document(page_content='My First Heading\n\nMy first paragraph.', lookup_str='', metadata={
    
    'source': 'example_data/fake-content.html'}, lookup_index=0)]

Загрузите HTML с помощью BeautifulSoup4

Мы также можем загрузить документ, BeautifulSoup4используя . Это позволит извлечь текст из и заголовок страницы в метаданные в качестве заголовка.BSHTMLLoaderHTMLHTMLpage_content

from langchain.document_loaders import BSHTMLLoader
loader = BSHTMLLoader("example_data/fake-content.html")
data = loader.load()
data

результат:

    [Document(page_content='\n\nTest Title\n\n\nMy First Heading\nMy first paragraph.\n\n\n', metadata={
    
    'source': 'example_data/fake-content.html', 'title': 'Test Title'})]

4.JSON

Строки JSON — это формат файла, в котором каждая строка представляет собой допустимое значение JSON.

JSONLoaderjqПроанализируйте файл JSON , используя указанный синтаксис. Он использует пакет jq python . Ознакомьтесь с этим руководством для получения подробной документации по синтаксису jq.

# 注意,正常情况下,我们执行:pip install jq
#!pip install jq
from langchain.document_loaders import JSONLoader
import json
from pathlib import Path
from pprint import pprint
file_path='./example_data/facebook_chat.json'
# 读取并解析json文件
data = json.loads(Path(file_path).read_text())
# 美观打印
pprint(data)

результат:

{
    
    'image': {
    
    'creation_timestamp': 1675549016, 'uri': 'image_of_the_chat.jpg'},
 'is_still_participant': True,
 'joinable_mode': {
    
    'link': '', 'mode': 1},
 'magic_words': [],
 'messages': [{
    
    'content': 'Bye!',
               'sender_name': 'User 2',
               'timestamp_ms': 1675597571851},
              {
    
    'content': 'Hi! Im interested in your bag. Im offering $50. Let '
                          'me know if you are interested. Thanks!',
               'sender_name': 'User 1',
               'timestamp_ms': 1675549022673}],
 'participants': [{
    
    'name': 'User 1'}, {
    
    'name': 'User 2'}],
 'thread_path': 'inbox/User 1 and User 2 chat',
 'title': 'User 1 and User 2 chat'}

Использование JSONLoader

Предположим, мы заинтересованы в извлечении значения из поля содержимого в ключе сообщений данных JSON. Это можно JSONLoaderлегко сделать, как показано ниже.

# JSONLoader 加载
loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[].content')

data = loader.load()
pprint(data)

Строковый файл JSON

Если вы JSON Linesзагружаете документ из файла, передайте json_lines=Trueи укажите jq_schema, чтобы извлечь содержимое из одного объекта JSON в page_contentполе.

file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())

результат:

# 原始数据
    ('{"sender_name": "User 2", "timestamp_ms": 1675597571851, "content": "Bye!"}\n'
     '{"sender_name": "User 1", "timestamp_ms": 1675597435669, "content": "Oh no '
     'worries! Bye"}\n'
     '{"sender_name": "User 2", "timestamp_ms": 1675596277579, "content": "No Im '
     'sorry it was my mistake, the blue one is not for sale"}\n')

Использование JSONLoader:

loader = JSONLoader(
    file_path='./example_data/facebook_chat_messages.jsonl',
    # 指明需要提取的字段
    jq_schema='.content',
    json_lines=True)

data = loader.load()
pprint(data)

результат:

    [Document(page_content='Bye!', metadata={
    
    'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
     Document(page_content='Oh no worries! Bye', metadata={
    
    'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
     Document(page_content='No Im sorry it was my mistake, the blue one is not for sale', metadata={
    
    'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]

Другой способ записи: установите jq_schema='.'и укажите content_key:

loader = JSONLoader(
    file_path='./example_data/facebook_chat_messages.jsonl',
    jq_schema='.',
    content_key='sender_name',
    json_lines=True)

data = loader.load()
pprint(data)

keyЭто необходимо для извлечения значения по текущему пути sender_nameследующим образом:

    [Document(page_content='User 2', metadata={
    
    'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
     Document(page_content='User 1', metadata={
    
    'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
     Document(page_content='User 2', metadata={
    
    'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]

Извлечение метаданных

Часто мы хотим JSONвключить метаданные, доступные в файле, в документ, который мы создаем на основе содержимого.

Ниже показано, как JSONLoaderизвлечь метаданные с помощью .

Важное примечание: в предыдущем примере, где метаданные не собирались, мы указали непосредственно в схеме значения, которые можно было page_contentиз нее .

.messages[].content

В текущем примере мы должны указать загрузчику перебрать messagesзаписи в поле. Поэтому jq_schemaдолжно быть:

.messages[]

Это позволяет нам передавать записи (dict) в функции, которые необходимо реализовать metadata_func. metadata_funcОтвечает за определение того, какая информация из записи должна быть включена в Documentметаданные, хранящиеся в конечном объекте.

content_keyКроме того, теперь мы должны явно указать, какое значение ключа нужно извлечь из параметра в загрузчике page_contentв поле.

# 定义元数据提取函数
def metadata_func(record: dict, metadata: dict) -> dict:

    metadata["sender_name"] = record.get("sender_name")
    metadata["timestamp_ms"] = record.get("timestamp_ms")

    return metadata

# metadata_func指定元数据提取函数,jq_schema指定提取的key路径,content_key指定需要提取的key
loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[]',
    content_key="content",
    metadata_func=metadata_func
)

data = loader.load()
pprint(data)

результат:

    [Document(page_content='Bye!', metadata={
    
    'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'User 2', 'timestamp_ms': 1675597571851}),
     Document(page_content='Oh no worries! Bye', metadata={
    
    'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'User 1', 'timestamp_ms': 1675597435669})]

Теперь вы увидите, что документ содержит метаданные, связанные с извлеченным нами содержимым.

метаданные_функ

metadata_funcПримите JSONLoaderметаданные по умолчанию, сгенерированные , как показано выше . Это позволяет пользователю полностью контролировать формат метаданных.

Например, метаданные по умолчанию содержат ключи sourceи seq_num. Однако данные JSON также могут содержать эти ключи. Затем пользователь может воспользоваться преимуществами metadata_funcпереименования ключей по умолчанию и использования JSONключей из данных.

# 定义元数据提取函数
def metadata_func(record: dict, metadata: dict) -> dict:

    metadata["sender_name"] = record.get("sender_name")
    metadata["timestamp_ms"] = record.get("timestamp_ms")

    if "source" in metadata:
        source = metadata["source"].split("/")
        source = source[source.index("langchain"):]
        metadata["source"] = "/".join(source)

    return metadata

# content_key用来指定page_content的值,jq_schema用来指定传入metadata_func的record
loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[]',
    content_key="content",
    metadata_func=metadata_func
)

data = loader.load()
pprint(data)

результат:

    [Document(page_content='Bye!', metadata={
    
    'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'User 2', 'timestamp_ms': 1675597571851}),
     Document(page_content='Oh no worries! Bye', metadata={
    
    'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'User 1', 'timestamp_ms': 1675597435669})]

Общие структуры JSON со схемой jq

В следующем списке представлены распространенные jq_schemaпримеры, которые можно использовать для извлечения содержимого из данных JSON на основе их структуры.

JSON        -> [{
    
    "text": ...}, {
    
    "text": ...}, {
    
    "text": ...}]
jq_schema   -> ".[].text"

JSON        -> {
    
    "key": [{
    
    "text": ...}, {
    
    "text": ...}, {
    
    "text": ...}]}
jq_schema   -> ".key[].text"

JSON        -> ["...", "...", "..."]
jq_schema   -> ".[]"

5. Уценка

Markdown — это легкий язык разметки для создания форматированного текста с помощью обычного текстового редактора.

В основном здесь объясняется, как Markdownзагружать документы в формат документа, который мы можем использовать в дальнейшем.

# !pip install unstructured > /dev/null
from langchain.document_loaders import UnstructuredMarkdownLoader
markdown_path = "../../../../../README.md"
loader = UnstructuredMarkdownLoader(markdown_path)
data = loader.load()
data
    [Document(page_content="ð\x9f¦\x9cï¸\x8fð\x9f”\x97 LangChain\n\nâ\x9a¡ Building applications with LLMs through composability â\x9a¡\n\nLooking for the JS/TS version? Check out LangChain.js. see here.", metadata={
    
    'source': '../../../../../README.md'})]

Сохранить элементы

Неструктурированный создает разные " elements" для разных блоков текста. По умолчанию мы группируем их вместе, но вы можете mode="elements"легко сохранить это разделение, указав .

loader = UnstructuredMarkdownLoader(markdown_path, mode="elements")
data = loader.load()
data[0]

результат:

    Document(page_content='ð\x9f¦\x9cï¸\x8fð\x9f”\x97 LangChain', metadata={
    
    'source': '../../../../../README.md', 'page_number': 1, 'category': 'Title'})

Этот раздел следует объяснить. По умолчанию файл уценки будет загружен в документ. Однако после указания mode="elements" он будет загружен в несколько документов в соответствии с тегами элементов в уценке.

6.PDF

В основном здесь объясняется, как загружать PDF-документы в формат документа, используемый в дальнейшем.

Использование PyPDF

Используйте pypdfдля PDFзагрузки в массив документов, где каждый документ содержит содержимое страницы и метаданные с номером страницы.

# 先安装pypdf
pip install pypdf
from langchain.document_loaders import PyPDFLoader

loader = PyPDFLoader("example_data/layout-parser-paper.pdf")
pages = loader.load_and_split()
pages[0]

результат:

Document(page_content='LayoutParser : A Uni\x0ced Toolkit for Deep\nLearning Based Document Image Analysis\nZejiang Shen1( \x00), Ruochen Zhang2, Melissa Dell3, Benjamin Charles Germain\nLee4, Jacob Carlson3, and Weining Li5\n1Allen Institute for AI', metadata={
    
    'source': 'example_data/layout-parser-paper.pdf', 'page': 0})

Преимущество этого метода в том, что документ можно получить по номерам страниц.
Мы хотим использовать OpenAIEmbeddings, поэтому нам нужно получить OpenAI APIключ.

import os
import getpass

os.environ['OPENAI_API_KEY'] = getpass.getpass('OpenAI API Key:')

from langchain.vectorstores import FAISS
from langchain.embeddings.openai import OpenAIEmbeddings
# embedding
faiss_index = FAISS.from_documents(pages, OpenAIEmbeddings())
docs = faiss_index.similarity_search("How will the community be engaged?", k=2)
for doc in docs:
    print(str(doc.metadata["page"]) + ":", doc.page_content[:300])

результат:

    9: 10 Z. Shen et al.
    Fig. 4: Illustration of (a) the original historical Japanese document with layout
    detection results and (b) a recreated version of the document image that achieves
    much better character recognition recall. The reorganization algorithm rearranges
    the tokens based on the their detect
    3: 4 Z. Shen et al.
    Efficient Data AnnotationC u s t o m i z e d  M o d e l  T r a i n i n gModel Cust omizationDI A Model HubDI A Pipeline SharingCommunity PlatformLa y out Detection ModelsDocument Images 
    T h e  C o r e  L a y o u t P a r s e r  L i b r a r yOCR ModuleSt or age & VisualizationLa y ou

Использование неструктурированного

from langchain.document_loaders import UnstructuredPDFLoader
loader = UnstructuredPDFLoader("example_data/layout-parser-paper.pdf")
data = loader.load()

Сохранить элементы

Неструктурированный создает разные " elements" для разных блоков текста. По умолчанию мы группируем их вместе, но вы можете mode="elements"легко сохранить это разделение, указав .

loader = UnstructuredPDFLoader("example_data/layout-parser-paper.pdf", mode="elements")
data = loader.load()
data[0]

результат:

Document(page_content='LayoutParser: A Unified Toolkit for Deep\nLearning Based Document Image Analysis\n document image analysis (DIA) tasks including document image classification [11,\narXiv:2103.15348v2  [cs.CV]  21 Jun 2021\n' lookup_str='', metadata={
    
    'file_path': 'example_data/layout-parser-paper.pdf', 'page_number': 1, 'total_pages': 16, 'format': 'PDF 1.5', 'title': '', 'author': '', 'subject': '', 'keywords': '', 'creator': 'LaTeX with hyperref', 'producer': 'pdfTeX-1.40.21', 'creationDate': 'D:20210622012710Z', 'modDate': 'D:20210622012710Z', 'trapped': '', 'encryption': None}, lookup_index=0)

Получение удаленных PDF-файлов с использованием неструктурированного

В основном объясняет, как 在线 pdfзагрузить формат документа, который мы можем использовать в дальнейшем. Его можно использовать на различных онлайн-сайтах в формате PDF, таких как https://open.umn.edu/opentextbooks/textbooks/ и https://arxiv.org/archive/ .

ПРИМЕЧАНИЕ. Все остальные загрузчики PDF-файлов также можно использовать для получения удаленных PDF-файлов, но OnlinePDFLoaderэто устаревшая функция UnstructedPDFLoader, предназначенная для использования исключительно с .

from langchain.document_loaders import OnlinePDFLoader
# 
loader = OnlinePDFLoader("https://arxiv.org/pdf/2302.03803.pdf")
data = loader.load()
print(data)

результат:

[Document(page_content='A WEAK ( k, k ) -LEFSCHETZ THEOREM FOR PROJECTIVE TORIC ORBIFOLDS\n\nWilliam D. MontoyaA. R. Cohomology of complete intersections in toric varieties. Pub-', lookup_str='', metadata={
    
    'source': '/var/folders/ph/hhm7_zyx4l13k3v8z02dwp1w0000gn/T/tmpgq0ckaja/online_file.pdf'}, lookup_index=0)]

Использование PDFMiner для генерации текста HTML (Использование PDFMiner для генерации текста HTML)

Это полезно для семантического разделения текста, поскольку выходной HTML-контент можно BeautifulSoupпроанализировать, чтобы получить более структурированную и подробную информацию о размере шрифта, номерах страниц, верхнем/нижнем колонтитуле PDF и т. д.

from langchain.document_loaders import PDFMinerPDFasHTMLLoader
loader = PDFMinerPDFasHTMLLoader("example_data/layout-parser-paper.pdf")
data = loader.load()[0]   # 整个 pdf 作为单个文档加载
from bs4 import BeautifulSoup
soup = BeautifulSoup(data.page_content,'html.parser')
content = soup.find_all('div')
import re
cur_fs = None
cur_text = ''
snippets = []   # first collect all snippets that have the same font size
for c in content:
    sp = c.find('span')
    if not sp:
        continue
    st = sp.get('style')
    if not st:
        continue
    fs = re.findall('font-size:(\d+)px',st)
    if not fs:
        continue
    fs = int(fs[0])
    if not cur_fs:
        cur_fs = fs
    if fs == cur_fs:
        cur_text += c.text
    else:
        snippets.append((cur_text,cur_fs))
        cur_fs = fs
        cur_text = c.text
snippets.append((cur_text,cur_fs))
# 注意:上面的逻辑非常简单。人们还可以添加更多策略,例如删除重复的片段(如
# PDF 中的页眉/页脚出现在多个页面上,因此如果我们发现重复,则可以安全地假设它是冗余信息)

Использование PyMuPDF

Это самый быстрый вариант анализа PDF-файла, он содержит подробные метаданные о PDF-файле и его страницах и возвращает один документ на страницу.

from langchain.document_loaders import PyMuPDFLoader
loader = PyMuPDFLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
data[0]
[Document(page_content='LayoutParser: A Unified Toolkit for Deep\nLearning Based Document Image Analysis\n\nWilliam D. MontoyaA. R. Cohomology of complete intersections in toric varieties. Pub-', lookup_str='', metadata={
    
    'source': '/var/folders/ph/hhm7_zyx4l13k3v8z02dwp1w0000gn/T/tmpgq0ckaja/online_file.pdf'}, lookup_index=0)]

Кроме того, вы можете передать любые параметры из документа в качестве аргументов ключевого слова в вызове загрузки PyMuPDFи передать их в get_text()вызов загрузки.

Каталог PyPDF

Загрузить PDF из каталога

from langchain.document_loaders import PyPDFDirectoryLoader
loader = PyPDFDirectoryLoader("example_data/")
docs = loader.load()

使用 pdfplumber(Использование pdfplumber)

Например PyMuPDF, выходной документ содержит подробные метаданные о PDF-файле и его страницах, при этом на каждую страницу возвращается один документ.

from langchain.document_loaders import PDFPlumberLoader
loader = PDFPlumberLoader("example_data/layout-parser-paper.pdf")
data = loader.load()
data[0]

результат:

[Document(page_content='LayoutParser: A Unified Toolkit for Deep\nLearning Based Document Image Analysis\n\nWilliam D. MontoyaA. R. Cohomology of complete intersections in toric varieties. Pub-', lookup_str='', metadata={
    
    'source': '/var/folders/ph/hhm7_zyx4l13k3v8z02dwp1w0000gn/T/tmpgq0ckaja/online_file.pdf'}, lookup_index=0)]

Справочный адрес:

https://python.langchain.com/docs/modules/data_connection/document_loaders/how_to/file_directory

рекомендация

отblog.csdn.net/u013066244/article/details/131740904
рекомендация