LINUX.ORG.RU

Распарсить текст и заполнить словарь в Python.

 , , , ,


0

1

Всем привет.

Поделитесь, пожалуйста, опытом и укажите где почитать про парсинг текста. Ищу подходящий для моей задачи API / Framework.

У меня есть задача парсить текст, который пользователь пишет в свободной форме и вычленять из этого текста информацию, заполняя анкету в виде Python-словаря. keys словаря постоянны и заданы изначально.

Например, входящий текст такой:

Мария Ивановна живёт в доме №5 по ул. Джона Доу, и сегодня она пойдёт в бассейн
 в 22 часа, чтобы поиграть в шахматы.

API должен его распарсить в такой словарь:

{
'person_first_name' : 'Мария',
'person_middle_name' : 'Ивановна',
'person_last_name' : '',
'person_adress' : 'ул. Джона Доу',
'appointment_place' : 'бассейе',
'appointment_date_time' : UNIXTime,
'appointment_job' : 'поиграть в шахматы'
}

ChatGPT не предлагайте, он пишет что он для этого не создан:

"While ChatGPT can provide responses and generate text, it doesn't have built-in capabilities for structured information extraction. To extract specific information from the text, you would typically use NLP techniques such as named entity recognition (NER), part-of-speech tagging, or dependency parsing."

ChatGPT:

Вы можете использовать регулярные выражения в Python для распарсивания данного текста. Вот пример кода, который решает вашу задачу:

import re
from datetime import datetime

text = "Мария Ивановна живёт в доме №5 по ул. Джона Доу, и сегодня она пойдёт в бассейн в 22 часа, чтобы поиграть в шахматы."

# Используем регулярные выражения для извлечения информации из текста
name_match = re.search(r'(\w+)\s(\w+)?\s?(\w+)?', text)
address_match = re.search(r'по\sул\.\s([\w\s]+),', text)
time_match = re.search(r'в\s(\d+)\sчаса', text)
job_match = re.search(r'чтобы\s(.+)', text)

# Создаем словарь с извлеченными данными
parsed_data = {
    'person_first_name': name_match.group(1),
    'person_middle_name': name_match.group(2) if name_match.group(2) else '',
    'person_last_name': name_match.group(3) if name_match.group(3) else '',
    'person_address': address_match.group(1),
    'appointment_place': 'бассейн',
    'appointment_date_time': datetime.now().timestamp() if time_match else '',
    'appointment_job': job_match.group(1)
}

print(parsed_data)

{
  'person_first_name': 'Мария',
  'person_middle_name': 'Ивановна',
  'person_last_name': '',
  'person_address': 'ул. Джона Доу',
  'appointment_place': 'бассейн',
  'appointment_date_time': 1663761097.234567,  # Фактическое значение времени
  'appointment_job': 'поиграть в шахматы'
}

vvn_black ★★★★★
()
Ответ на: комментарий от CrX

Без нейросетки никак.

Теоретически, без нейросетки можно распарить, где какая словоформа и где какой член предложения. Кто - Марьванна. Куда - в бассейн. Но работать это будет паршиво. Допустим, она год назад въехала в дом по улице Джона Доу, а вечером ее ждут в бассейне Каспаров и Карпов.

Vidrele ★★
()
Ответ на: комментарий от Vidrele

Да конечно будет паршиво. В свободной форме может быть что угодно, например «Бассейн будет финальной точкой маршрута Марьванны», или ещё как. Да, натянутый пример, но их разных можно сотни придумать. Текст в свободной форме парсить алгоритмически тот ещё геморрой, и всё равно в результате будет сбоить.

CrX ★★★
()
Ответ на: комментарий от CrX

В 22-00 поиграть в бассейне в шахматы ни одна нейронка не осилит.

Распарсить текст и заполнить словарь в Python

Может быть ТС нужен просто словарь встречающихся слов?

https://habr.com/ru/articles/239081/ Парсим на Python: Pyparsing для новичков

--------------------------------------------------
Схожу сегодня в 03-00 в магазин, куплю коробку спичек.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 4)

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

Пользователь в свободной форме понапишет такого, что и человек не разберется, кто, с кем и где живет.

dmitry237 ★★★
()
Ответ на: комментарий от AntonI

Я:

Задача парсить текст, который пользователь пишет в свободной форме и вычленять из этого текста информацию, заполняя анкету в виде Python-словаря. keys словаря постоянны и заданы изначально.

Например, входящий текст такой:

Мария Ивановна живёт в доме №5 по ул. Джона Доу, и сегодня она пойдёт в бассейн в 22 часа, чтобы поиграть в шахматы.

ChatGPT:

Для решения данной задачи можно использовать регулярные выражения (regular expressions) в Python. Регулярные выражения позволяют искать и вычленять определенные шаблоны текста.

В вашем примере можно выделить следующие ключевые информационные элементы:

Имя: «Мария Ивановна» Адрес: «ул. Джона Доу, дом №5» Время похода в бассейн: «22 часа» Хобби: «шахматы»

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

Вот пример кода, решающего данную задачу:

import re

def parse_text(text):
    # Инициализация пустого словаря
    info_dict = {
        'name': None,
        'address': None,
        'time': None,
        'hobby': None
    }
    
    # Поиск имени
    name_match = re.search(r'(\b[А-ЯЁ][а-яё]+\b)\s+(\b[А-ЯЁ][а-яё]+\b)', text)
    if name_match:
        name = name_match.group()
        info_dict['name'] = name
    
    # Поиск адреса
    address_match = re.search(r'по ул\. (\b[А-ЯЁа-яё\s\d.,-]+)', text)
    if address_match:
        address = address_match.group(1)
        info_dict['address'] = address
    
    # Поиск времени
    time_match = re.search(r'(\d{1,2} часа)', text)
    if time_match:
        time = time_match.group()
        info_dict['time'] = time
    
    # Поиск хобби
    hobby_match = re.search(r'поиграть в (\b[А-ЯЁа-яё\s]+\b)', text)
    if hobby_match:
        hobby = hobby_match.group(1)
        info_dict['hobby'] = hobby
    
    return info_dict

# Пример использования
text = "Мария Ивановна живёт в доме №5 по ул. Джона Доу, и сегодня она пойдёт в бассейн в 22 часа, чтобы поиграть в шахматы."
info = parse_text(text)
print(info)
{
    'name': 'Мария Ивановна',
    'address': 'Джона Доу, дом №5',
    'time': '22 часа',
    'hobby': 'шахматы'
}

vvn_black ★★★★★
()
Ответ на: комментарий от AntonI

а нельзя просто этот чатЖПТ

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

vvn_black ★★★★★
()
Ответ на: комментарий от AntonI

В примере выше шаблоны не были заданы и неонка сама вытянула ключевые. Это новый промпт, который не связан с предыдущим примером, т.е. его она не учитывала.

Не знаю, чего там у ТС не получается использовать.

vvn_black ★★★★★
()

То что ты хочешь называется Named Entity Recognition. Собственно ChatGPT даже написал тебе об этом.

Есть обзор библиотек/фреймворков для этого, в том числе на питоне.

Сравниваем работу open source Python — библиотек для распознавания именованных сущностей

Инструменты для решения NER-задач для русского языка

P.S. Создавал тему зачем оно нужно Истории успеха для Named Entity Recognition (NER) - в общем, насколько понимаю, главная проблема в практическом использовании, что процент ошибок при распознавании все же великоват. Даже 2%-3% - немало на практике. Но может тебе подойдет.

praseodim ★★★★★
()
Последнее исправление: praseodim (всего исправлений: 1)
Ответ на: комментарий от AntonI

Думаю, что никогда. В этом плане мне она представляется даже не продвинутым гуглом, а продвинутым интерфейсом к SO, была такая консольная утилита (howdowit если не ошибаюсь в названии) с гениально простой идеей дёргать http-запросом поисковый запрос, парсить и отдавать либо ответ самый рейтинговый, либо помеченный как решение.

Я долго пользовался самописным ботом для таких простых запросов, ответы на которые постоянно забываешь, типа «как в js ставить подстроку в середину массива». Чтоб не лазить в документацию и поисковики.

vvn_black ★★★★★
()
Ответ на: комментарий от praseodim

Впечатляюще, но ты понимаешь, что не годится для других примеров ФИО и хобби?

Да, но можно же набор повторяющихся шаблонов выделить, остальные девиации разбирать руками. Т.е., каким то образом облегчить обработку массы ответов, наверное, можно.

vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

Для любых ФИО - это не реально. Нужны словари имен и фамилий с отчествами и других вариантов. Плюс морфология.

praseodim ★★★★★
()
Последнее исправление: praseodim (всего исправлений: 1)
Ответ на: комментарий от praseodim

То что ты хочешь называется Named Entity Recognition.

Я знаю, поэтому выставил соответсвующие тэги.

Больше скажу, я уже потестил natasha, DeepPavlov, pymorphy2 и rutermextract(RusVectōrēs). Везде результат меня не устроил. Возможно DeepPavlov можно будет подогнать с помощью тонкой настройки обучения, но я пока не умею.

little_fox
() автор топика

ChatGPT вполне себе может, надо задания правильно писать https://ibb.co/9ZNG7Lv

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

тут можно попробовать https://t.me/kun4sun_bot

theurs ★★
()
Последнее исправление: theurs (всего исправлений: 2)
Ответ на: комментарий от thegoldone

Получив задание типа «напиши историю о человеке, где он живёт и куда, когда и зачем пойдет», большинство людей все же примут простые и очевидные решения. Поэтому алгоритмический парсинг имеет право на жизнь как эксперимент. Но в продакшн - фу-фу-фу, конечно.

Vidrele ★★
()

Это что, доклады осведомителей в полицию? Просто заставить их писать отчёты в фиксированном формате, типа <субъект> <объект> <действие> <время> <обстоятельства>. Как говорил Броневой: «что это вас на эпитеты потянуло, Шольц? мы, сыщики должны оперировать фактами: он сказал, она сделала».

seiken ★★★★★
()
Последнее исправление: seiken (всего исправлений: 1)

Оперовский AI выдал на запрос "Распарси на блоки: «Мария Ивановна живёт в доме №5 по ул. Джона Доу, и сегодня она пойдёт в бассейн в 22 часа, чтобы поиграть в шахматы.»

Имя и фамилия: Мария Ивановна

Адрес проживания: дом №5 по ул. Джона Доу

Планы на сегодня: идти в бассейн

Время похода в бассейн: 22 часа

Цель похода в бассейн: поиграть в шахматы

One ★★★★★
()
20 ноября 2023 г.

Here is https://learn.deeplearning.ai/chatgpt-prompt-eng/lesson/5/inferring an example of similar task:

import openai
import os

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file

openai.api_key  = os.getenv('OPENAI_API_KEY')


def get_completion(prompt, model="gpt-3.5-turbo"):
    messages = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=0, # this is the degree of randomness of the model's output
    )
    return response.choices[0].message["content"]


lamp_review = """
Needed a nice lamp for my bedroom, and this one had \
additional storage and not too high of a price point. \
Got it fast.  The string to our lamp broke during the \
transit and the company happily sent over a new one. \
Came within a few days as well. It was easy to put \
together.  I had a missing part, so I contacted their \
support and they very quickly got me the missing piece! \
Lumina seems to me to be a great company that cares \
about their customers and products!!
"""

prompt = f"""
Identify the following items from the review text: 
- Sentiment (positive or negative)
- Is the reviewer expressing anger? (true or false)
- Item purchased by reviewer
- Company that made the item

The review is delimited with triple backticks. \
Format your response as a JSON object with \
"Sentiment", "Anger", "Item" and "Brand" as the keys.
If the information isn't present, use "unknown" \
as the value.
Make your response as short as possible.
Format the Anger value as a boolean.

Review text: '''{lamp_review}'''
"""
response = get_completion(prompt)
print(response)
LeNiN ★★
()