Лемматизация навсегда с Spacy

Я пытаюсь лемматизировать регистры чата в фрейме данных, используя spacy. Мой код:

nlp = spacy.load("es_core_news_sm")
df["text_lemma"] = df["text"].apply(lambda row: " ".join([w.lemma_ for w in nlp(row)]))

У меня около 600 000 строк, и выполнение приложения занимает более двух часов. Есть ли более быстрый пакет/способ лемматизации? (Мне нужно решение, которое работает для испанского)

Я только пытался использовать пакет spacy

Используйте nlp.pipe, API для массовых аннотаций.

erip 24.01.2023 00:30

Пожалуйста, ознакомьтесь с часто задаваемыми вопросами о скорости spaCy — использование nlp.pipe, как упоминалось в других ответах, является одним из важных шагов. Если все, что вам нужно, это лемматизатор, вам следует отключить неиспользуемые компоненты, такие как синтаксический анализатор и NER. github.com/explosion/spaCy/discussions/8402

polm23 24.01.2023 05:51
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Замедление скорости обработки связано с многочисленными вызовами конвейера spaCy через nlp(). Более быстрый способ обработки больших текстов — вместо этого обрабатывать их как поток с помощью команды nlp.pipe(). Когда я протестировал это на 5000 строк фиктивного текста, он предложил увеличение скорости примерно в 3,874 раза (~ 9,759 с против ~ 2,519 с) по сравнению с исходным методом. При необходимости есть способы улучшить это, см. этот контрольный список для оптимизации spaCy, которую я сделал.

Решение

# Assume dataframe (df) already contains column "text" with text

# Load spaCy pipeline
nlp = spacy.load("es_core_news_sm")

# Process large text as a stream via `nlp.pipe()` and iterate over the results, extracting lemmas
lemma_text_list = []
for doc in nlp.pipe(df["text"]):
    lemma_text_list.append(" ".join(token.lemma_ for token in doc))
df["text_lemma"] = lemma_text_list

Полный код для тестирования таймингов

import spacy
import pandas as pd
import time

# Random Spanish sentences
rand_es_sentences = [
    "Tus drafts influirán en la puntuación de las cartas según tu número de puntos DCI.",
    "Información facilitada por la División de Conferencias de la OMI en los cuestionarios enviados por la DCI.",
    "Oleg me ha dicho que tenías que decirme algo.",
    "Era como tú, muy buena con los ordenadores.",
    "Mas David tomó la fortaleza de Sion, que es la ciudad de David."]

# Duplicate sentences specified number of times
es_text = [sent for i in range(1000) for sent in rand_es_sentences]
# Create data-frame
df = pd.DataFrame({"text": es_text})
# Load spaCy pipeline
nlp = spacy.load("es_core_news_sm")


# Original method (very slow due to multiple calls to `nlp()`)
t0 = time.time()
df["text_lemma_1"] = df["text"].apply(lambda row: " ".join([w.lemma_ for w in nlp(row)]))
t1 = time.time()
print("Total time: {}".format(t1-t0))  # ~9.759 seconds on 5000 rows


# Faster method processing rows as stream via `nlp.pipe()`
t0 = time.time()
lemma_text_list = []
for doc in nlp.pipe(df["text"]):
    lemma_text_list.append(" ".join(token.lemma_ for token in doc))
df["text_lemma_2"] = lemma_text_list
t1 = time.time()
print("Total time: {}".format(t1-t0))  # ~2.519 seconds on 5000 rows

Вызов list не очень хорош, потому что вы материализуете всю трубу. Просто используйте объект генератора.

erip 24.01.2023 00:31

@erip Согласен, я обновил код и ценю ваш вклад. Отмечу, что документация spaCy использует оба, и могут быть случаи, когда кому-то требуется функциональность, предлагаемая списком, вместо прямой работы с объектом-генератором. Также не было никаких заметных изменений во времени обработки по сравнению с моим кратким тестированием.

Kyle F Hartzenberg 24.01.2023 13:32

Спасибо! Эти решения очень помогли

Laura R 25.01.2023 16:29

Другие вопросы по теме