Greenplum для Data Science: Развертывание моделей на Greenplum с помощью Python с помощью GreenplumPython
Введение
GreenplumPython позволяет специалистам по исследованию данных писать код на привычном и хорошо знакомом им языке Pythonic, выполнять преобразования данных и обучать модели ML гораздо быстрее и безопаснее на единой платформе Greenplum. Вызовы функций на фреймах переводятся GreenplumPython в SQL-запросы и автоматически отправляются в Greenplum. В результате вычисления происходят параллельно в кластере Greenplum.
Обзор набора данных
Набор данных состоит из 1967 новостей фондового рынка из англоязычных финансовых новостей, классифицированных по тональности. Поля данных:
- docid: идентификатор финансовых новостей
- original_news: текст финансовых новостей
- label: метка, соответствующая классу, в виде строки 'положительная' или 'отрицательная'.
- cleaned_text: очищенный текст original_news
sentiment_news = db.create_dataframe(table_name="sentiment_news", schema="ds_demo") sentiment_news[:5]
NLP — развертывание модели с помощью GreenplumPython
Импорт пакетов
Раньше для создания UDF в базе данных пользователю приходилось прописывать все зависимости в теле функции. Это часто приводило к использованию раздражающего кодового шаблона, особенно при импорте одних и тех же пакетов в разные функции.
GreenplumPython поддерживает ссылки на объекты вне UDF, включая функции и модули. Это позволяет преодолеть разрыв между UDF и обычной функцией Python.
Мы импортируем все пакеты, которые нужны нашим UDF:
import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression import pickle from typing import List
Функция обучения модели
Мы хотим создать функцию для обучения NLP-модели и вернуть обученную модель логистической регрессии и модель вектора подсчета.
Создаем тип
Для этого нам нужно сначала создать специальный класс sentiment_nlp_type для хранения результатов работы функции в виде двоичных файлов:
class sentiment_nlp_type:
model_logreg: bytes
model_bow: bytes
Создаем функцию
Мы можем написать функцию train, используя расширение PL/Python3, как показано ниже, указав возвращаемый тип.
@gp.create_column_function преобразует функцию Python в функцию, определяемую пользователем (UDF) в базе данных, и автоматически агрегирует входные столбцы для применения к столбцам.
NB: Созданные функции лишь временно сохраняются в базе данных и будут удалены по окончании сеанса.
@gp.create_column_function
def save_nlp_models(cleaned_text: List[str], label: List[str]) -> sentiment_nlp_type:
X_train = cleaned_text y_train = label vectorizer = CountVectorizer(min_df=4, stop_words="english")
X_train = vectorizer.fit_transform(X_train) # LOGISTIC REGRESSION
logreg = LogisticRegression() logreg.fit(X_train, y_train) # Save Logistic Regression model
model_logreg = pickle.dumps(logreg) # Save CountVectorizer
model_countvectorizer = pickle.dumps(vectorizer) return {'model_logreg': model_logreg,
'model_bow': model_countvectorizer}
Применяем функцию
Мы можем использовать эту функцию для обучения модели, которая обучается на основе датафрейма sentiment_news:
model_nlp = sentiment_news.apply(
lambda t: save_nlp_models(t["cleaned_text"], t["label"]),
expand=True
)
Функция составления прогноза
Точно так же, как мы создали функцию обучения, теперь создадим функцию составления прогноза с помощью @gp.create_function:
@gp.create_function
def predict_sentiment(cleaned_text: str, model_logreg: bytes, model_bow: bytes) -> str:
logreg = model_logreg vectorizer = model_bow texts = cleaned_text # Extract Logistic Regression model
model_logreg_bytes = pickle.loads(logreg) # Extract CountVectorizer
model_countvectorizer = pickle.loads(vectorizer) return list(
model_logreg_bytes.predict( model_countvectorizer.transform([texts]) ) )[0]
Развертывание модели
Процесс обучения завершен, теперь мы можем перейти к следующему шагу, а именно к развертыванию модели.
news = "Previously, the company anticipated its operating profit to improve over the same period."
Используем обученную выше model_nlp
model_nlp.apply(
lambda t: predict_sentiment(news, t["model_logreg"], t["model_bow"])
)
Используем модель ds_demo.saved_models
# Access to the model saved in the database
model_table = db.create_dataframe(table_name="saved_models", schema="ds_demo")
model_saved = model_table[lambda t: t["model_name"] == "nlp_sentiment_analysis_bow_logreg"]
# Call function predict
model_saved.apply(
lambda t: predict_sentiment(news, t["model_logreg"], t["model_bow"])
)
Используем предопределенные UDF, сохраненные в Greenplum
Вы также можете получить доступ к предопределенному UDF predict_sentiment в Greenplum, который был создан с помощью gp.function():
# Get pre-defined UDF
predict_function = gp.function("predict_sentiment")
# Call predict UDF
model_saved.apply( lambda t: predict_function(news, t["model_logreg"], t["model_bow"])
)
Прогнозирование нескольких записей из базы данных
Конечно, мы можем применить модель и к таблице новостей, хранящейся в базе данных со множеством записей!
Для этого нам нужно сначала объединить model_table и data_table воедино:
data_model_join = sentiment_news.cross_join(nlp_sentiment_analysis_bow_logreg) data_model_join[:1]
Теперь мы можем присвоить предсказанное значение нашему датафрейму:
data_model_join.assign(
pred=lambda t: predict_function(t["cleaned_text"], t["model_logreg"], t["model_bow"])
)[["cleaned_text", "label", "pred"]][:5]
Заключение
В этой статье мы показали Вам, как GreenplumPython может быть использован специалистами по исследованию данных для выполнения параллельных вычислений на Greenplum непосредственно из Python в неявном виде. Это весьма выгодно для специалистов по обработке данных, которым удобнее кодировать на Python. Кроме того, это обеспечивает большую гибкость в управлении развертыванием и использованием моделей на Greenplum. Если Вы хотите узнать о GreenplumPython подробнее, мы приглашаем Вас ознакомиться с официальной документацией.










