В этой статье мы узнаем, что такое Spacy и как мы можем использовать Apache Spark для масштабного запуска Spacy.

В связи с постоянно растущим спросом на варианты использования машинного обучения в повседневном бизнесе потребность в различных типах алгоритмов машинного обучения в различных областях растет с постоянно растущим объемом данных.

Что такое Spacy

Spacy - это промышленная библиотека обработки естественного языка для обработки текстовых данных для машинного обучения, предоставляющая множество опций для предварительной обработки, токенизации, определения границ, разрешения именованных сущностей, предварительно обученных векторов слов и подготовки текста для глубокого обучения и т. Д. Spacy также есть некоторые векторы построения, например, для word2vec. Вы можете найти более подробную информацию о моделях здесь также на разных языках.

Apache Spark - это распределенная универсальная среда кластерных вычислений с открытым исходным кодом. Spark предоставляет интерфейс для программирования целых кластеров с неявным параллелизмом данных и отказоустойчивостью.

Как запустить Spacy Similarity на Spark:

ПРИМЕЧАНИЕ. Подробные инструкции по установке spacy можно найти здесь. (я использую версию Spacy 2.1.8)

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

Давайте посмотрим на подобие api от spacy.

Я использую модель en_core_web_lg для этой статьи, которая представляет собой векторы перчаток, обученные на Common Crawl с 685k ключами, 685k уникальными векторами (300 измерений).

import spacy
import en_core_web_lg
nlp = en_core_web_lg.load()
doc1 = nlp("i love my pet dog")
doc2 = nlp("Maggie is my lovable pet dog !")
print("output:" , doc1.similarity(doc2))

выход: 0,9822815156578484

Это означает, что два вышеупомянутых документа / предложения похожи на 98,22%.

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

Идея состоит в том, чтобы запустить подобие () как искровую UDF (определяемую пользователем функцию) параллельно для нескольких исполнителей. Ниже приведены некоторые важные факторы, которые необходимо настроить для запуска и масштабирования пространства на искре:

Весь мой код объединен в класс MySpacyClassObject. Чтобы не загружать en_core_web_lg снова и снова для каждого вычисления подобия, я сохранил en_core_web_lg в глобальной переменной для каждого исполнителя. Это ускорит вычисление, поскольку en_core_web_lg (~ 789 МБ) уже загружено в память исполнителя.

@staticmethod
def get_spacy():

    if "nlp" not in globals():
        globals()["nlp"] = en_core_web_lg.load()

    return globals()["nlp"]

Создать Spark UDF:

def text_similarity(dsc1, dsc2):
    '''
    Load spacy and calculate similarity measure
    '''
    if (dsc1 is None or dsc2 is None):
        return float(-1)
    if ((len(str(dsc1)) < 1 or str(dsc1) == "") or (len(str(dsc2)) < 1 or str(dsc2) == "")):
        return float(-1)

    nlp_glob = MySpacyClassObject.get_spacy()

    return float(nlp_glob(dsc1).similarity(nlp_glob(dsc2)))
#define your udf 
text_similarity_UDF = udf(lambda arr: MySpacyClassObject.text_similarity(arr[0], arr[1]), FloatType())

Как использовать UDF:

#You can read data from any data source per your need to create #spark data frame to use UDF. I am reading table from hive which #already has two columns with textual data for similarity
text_similarity_DF = spark.read.table(
    "your_schema.table_name").repartition(500)
text_similarity_with_measure = text_similarity_UDF \
    .withColumn("similarity",
                text_similarity_UDF(array(text_similarity_DF['text1'],
                                   text_similarity_DF['text2']))) \
    .select(text_similarity_DF['text1']
            , "similarity"
            , text_similarity_DF['text2'])
#Persist dataframe text_similarity_with_measure back in hive
text_similarity_with_measure.write.mode('overwrite').saveAsTable(your_output_tabble_name)

Важное соображение и проблемы для повышения производительности:

1 . Сериализация: версия Spacy 2. * поддерживает сериализацию. Убедитесь, что вы используете версию ›2.

2. Убедитесь, что en_core_web_lg (или какая-либо другая модель, которую вы используете) доступна для каждого исполнителя, чтобы вы могли читать и загружать модель для повышения производительности. Другой способ - вы можете позволить своей программе Spark загрузить ее только один раз и продолжать использовать ее повторно (см. Статический метод get_spacy () выше).

3. Убедитесь, что у каждого исполнителя установлен и доступен для использования spacy.