Как издеваться над космическими моделями/объектами Doc для модульных тестов?

Загрузка пространственных моделей замедляет выполнение моих модульных тестов. Есть ли способ имитировать пространственные модели или объекты Doc для ускорения модульных тестов?

Пример текущих медленных тестов

import spacy
nlp = spacy.load("en_core_web_sm")

def test_entities():
    text = u"Google is a company."
    doc = nlp(text)
    assert doc.ents[0].text == u"Google"

Основываясь на документах, мой подход

Создание Vocab и Doc вручную и установка сущностей в виде кортежей.

from spacy.vocab import Vocab
from spacy.tokens import Doc

def test()
    alphanum_words = u"Google Facebook are companies".split(" ")
    labels = [u"ORG"]
    words = alphanum_words + [u"."]
    spaces = len(words) * [True]
    spaces[-1] = False
    spaces[-2] = False
    vocab = Vocab(strings=(alphanum_words + labels))
    doc = Doc(vocab, words=words, spaces=spaces)

    def get_hash(text):
        return vocab.strings[text]

    entity_tuples = tuple([(get_hash(labels[0]), 0, 1)])
    doc.ents = entity_tuples
    assert doc.ents[0].text == u"Google"

Есть ли более чистое решение Pythonic для имитации пространственных объектов для модульных тестов для сущностей?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
11
0
1 126
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

На самом деле это отличный вопрос! Я бы сказал, что ваш инстинкт определенно прав: если все, что вам нужно, это объект Doc в заданном состоянии и с заданными аннотациями, всегда создавайте его вручную, где это возможно. И если вы не тестируете статистическую модель явно, не загружайте ее в свои модульные тесты. Это делает тесты медленными и вносит слишком много ненужной дисперсии. Это также очень соответствует философии модульного тестирования: вы хотите писать независимые тесты для одна вещь за раз (а не что-то одно плюс куча кода сторонних библиотек плюс статистическая модель).

Несколько общих советов и идей:

  • Если возможно, всегда создавайте Doc вручную. Избегайте загрузки моделей или Language подклассов.
  • Если вашему приложению или тесту специально не нужен doc.text, вы не устанавливаете придетсяspaces. Фактически, я не учитываю это примерно в 80% тестов, которые я пишу, потому что это действительно становится актуальным только тогда, когда вы снова собираете токены.
  • Если вам нужно создать много объектов Doc в своем наборе тестов, вы можете рассмотреть возможность использования служебной функции, подобной get_doc помощник, которую мы используем в наборе тестов spaCy. (Эта функция также показывает вам, как отдельные аннотации устанавливаются вручную, если вам это нужно.)
  • Используйте фикстуры (на уровне сеанса) для общих объектов, например Vocab. В зависимости от того, что вы тестируете, вы можете явно использовать словарь English. В наборе тестов spaCy мы делаем это, настроив en_vocab приспособление в файле conftest.py.
  • Вместо того, чтобы устанавливать doc.ents в список кортежей, вы также можете сделать его списком Span объектов. Это выглядит немного проще, его легче читать, а в spaCy v2.1+ вы также можете передать строку в качестве метки:
def test_entities(en_vocab):
    doc = Doc(en_vocab, words=["Hello", "world"])
    doc.ents = [Span(doc, 0, 1, label = "ORG")]
    assert doc.ents[0].text == "Hello"
  • Если вам нужно протестировать модель (например, в наборе тестов, который гарантирует, что ваши пользовательские модели загружаются и работают должным образом) или языковой класс, такой как English, поместите их в фикстуру на уровне сеанса. Это означает, что они будут загружаться только один раз за сеанс, а не один раз за тест. Языковые классы загружаются отложенно, и их загрузка также может занять некоторое время, в зависимости от содержащихся в них данных. Таким образом, вы хотите сделать это только один раз.
# Note: You probably don't have to do any of this, unless you're testing your
# own custom models or language classes.

@pytest.fixture(scope = "session")
def en_core_web_sm():
    return spacy.load("en_core_web_sm")

@pytest.fixture(scope = "session")
def en_lang_class():
    lang_cls = spacy.util.get_lang_class("en")
    return lang_cls()

def test(en_lang_class):
    doc = en_lang_class("Hello world")

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