Используйте встраивание документов в BigQuery для задач схожести документов и кластеризации
BigQuery предлагает возможность загружать SavedModel TensorFlow и выполнять прогнозы. Эта возможность - отличный способ добавить текстовое подобие и кластеризацию поверх вашего хранилища данных.
Затем скопируйте и вставьте запросы из моей записной книжки в GitHub. Вы можете опробовать запросы в консоли BigQuery или в блокноте AI Platform Jupyter.
Данные отчетов о шторме
В качестве примера я воспользуюсь набором данных, состоящим из отчетов о ветре, которые «разведчики штормов» позвонили в офисы Национальной метеорологической службы. Это общедоступный набор данных в BigQuery, и его можно запросить следующим образом:
SELECT EXTRACT(DAYOFYEAR from timestamp) AS julian_day, ST_GeogPoint(longitude, latitude) AS location, comments FROM `bigquery-public-data.noaa_preliminary_severe_storms.wind_reports` WHERE EXTRACT(YEAR from timestamp) = 2019 LIMIT 10
Результат выглядит так:
Допустим, мы хотим создать SQL-запрос для поиска комментариев, которые выглядят как «отключение линии электропередачи в доме».
Шаги:
- Загрузите модель машинного обучения, которая создает вложение (по сути, компактное числовое представление) некоторого текста.
- Используйте модель для встраивания нашего поискового запроса.
- Используйте модель для создания встраивания каждого комментария в таблицу отчетов о ветре.
- Ищите строки, в которых два вложения расположены близко друг к другу.
Загрузка модели встраивания текста в BigQuery
TensorFlow Hub имеет ряд моделей встраивания текста. Для достижения наилучших результатов вы должны использовать модель, которая была обучена на данных, аналогичных вашему набору данных, и которая имеет достаточное количество измерений, чтобы уловить нюансы вашего текста.
Для этой демонстрации я буду использовать вложение Swivel, которое было обучено в Новостях Google и имеет 20 измерений (то есть довольно грубо). Этого достаточно для того, что нам нужно сделать.
Слой встраивания Swivel уже доступен в формате TensorFlow SavedModel, поэтому нам просто нужно его загрузить, извлечь из tar-архива, сжатого gzip-файла и загрузить в Google Cloud Storage:
FILE=swivel.tar.gz wget --quiet -O tmp/swivel.tar.gz https://tfhub.dev/google/tf2-preview/gnews-swivel-20dim/1?tf-hub-format=compressed cd tmp tar xvfz swivel.tar.gz cd .. mv tmp swivel gsutil -m cp -R swivel gs://${BUCKET}/swivel
После того, как файлы модели находятся в GCS, мы можем загрузить их в BigQuery как модель машинного обучения:
CREATE OR REPLACE MODEL advdata.swivel_text_embed OPTIONS(model_type='tensorflow', model_path='gs://BUCKET/swivel/*')
Попробуйте встраивание модели в BigQuery
Чтобы опробовать модель в BigQuery, нам нужно знать ее схему ввода и вывода. Это будут имена слоев Keras при экспорте. Мы можем получить их, перейдя в консоль BigQuery и просмотрев вкладку «Схема» модели:
Давайте попробуем эту модель, получив вложение для знаменитой августовской речи, назвав входной текст предложениями и зная, что мы получим выходной столбец с именем output_0:
SELECT output_0 FROM ML.PREDICT(MODEL advdata.swivel_text_embed,( SELECT "Long years ago, we made a tryst with destiny; and now the time comes when we shall redeem our pledge, not wholly or in full measure, but very substantially." AS sentences))
В результате, как и ожидалось, 20 чисел, первые несколько из которых показаны ниже:
Поиск сходства документов
Определите функцию для вычисления евклидова квадрата расстояния между парой вложений:
CREATE TEMPORARY FUNCTION td(a ARRAY<FLOAT64>, b ARRAY<FLOAT64>, idx INT64) AS ( (a[OFFSET(idx)] - b[OFFSET(idx)]) * (a[OFFSET(idx)] - b[OFFSET(idx)]) ); CREATE TEMPORARY FUNCTION term_distance(a ARRAY<FLOAT64>, b ARRAY<FLOAT64>) AS (( SELECT SQRT(SUM( td(a, b, idx))) FROM UNNEST(GENERATE_ARRAY(0, 19)) idx ));
Затем вычислите вложение для нашего поискового запроса:
WITH search_term AS ( SELECT output_0 AS term_embedding FROM ML.PREDICT(MODEL advdata.swivel_text_embed,(SELECT "power line down on a home" AS sentences)) )
и вычислим расстояние между встраиванием каждого комментария и term_embedding поискового запроса (см. выше):
SELECT term_distance(term_embedding, output_0) AS termdist, comments FROM ML.PREDICT(MODEL advdata.swivel_text_embed,( SELECT comments, LOWER(comments) AS sentences FROM `bigquery-public-data.noaa_preliminary_severe_storms.wind_reports` WHERE EXTRACT(YEAR from timestamp) = 2019 )), search_term ORDER By termdist ASC LIMIT 10
Результат:
Помните, что мы искали «линия электропередачи дома». Обратите внимание, что два верхних результата - это «линия электропередачи на дом» - вложение текста помогло понять, что дом и дом похожи в этом контексте. Следующий набор лучших совпадений касается линий электропередач, самой уникальной пары слов в нашем поисковом запросе.
Кластеризация документов
Кластеризация документов включает использование вложений в качестве входных данных для алгоритма кластеризации, такого как K-Means. Мы можем сделать это в самом BigQuery, и, чтобы сделать вещи немного интереснее, мы будем использовать местоположение и день года в качестве дополнительных входных данных для алгоритма кластеризации.
CREATE OR REPLACE MODEL advdata.storm_reports_clustering OPTIONS(model_type='kmeans', NUM_CLUSTERS=10) AS SELECT arr_to_input_20(output_0) AS comments_embed, EXTRACT(DAYOFYEAR from timestamp) AS julian_day, longitude, latitude FROM ML.PREDICT(MODEL advdata.swivel_text_embed,( SELECT timestamp, longitude, latitude, LOWER(comments) AS sentences FROM `bigquery-public-data.noaa_preliminary_severe_storms.wind_reports` WHERE EXTRACT(YEAR from timestamp) = 2019 ))
Встраивание (output_0) представляет собой массив, но BigQuery ML в настоящее время требует именованных входов. Обходной путь - преобразовать массив в структуру:
CREATE TEMPORARY FUNCTION arr_to_input_20(arr ARRAY<FLOAT64>) RETURNS STRUCT<p1 FLOAT64, p2 FLOAT64, p3 FLOAT64, p4 FLOAT64, p5 FLOAT64, p6 FLOAT64, p7 FLOAT64, p8 FLOAT64, p9 FLOAT64, p10 FLOAT64, p11 FLOAT64, p12 FLOAT64, p13 FLOAT64, p14 FLOAT64, p15 FLOAT64, p16 FLOAT64, p17 FLOAT64, p18 FLOAT64, p19 FLOAT64, p20 FLOAT64> AS ( STRUCT( arr[OFFSET(0)] , arr[OFFSET(1)] , arr[OFFSET(2)] , arr[OFFSET(3)] , arr[OFFSET(4)] , arr[OFFSET(5)] , arr[OFFSET(6)] , arr[OFFSET(7)] , arr[OFFSET(8)] , arr[OFFSET(9)] , arr[OFFSET(10)] , arr[OFFSET(11)] , arr[OFFSET(12)] , arr[OFFSET(13)] , arr[OFFSET(14)] , arr[OFFSET(15)] , arr[OFFSET(16)] , arr[OFFSET(17)] , arr[OFFSET(18)] , arr[OFFSET(19)] ));
Полученные десять кластеров можно визуализировать в консоли BigQuery:
Как выглядят комментарии в кластере №1? Запрос:
SELECT sentences FROM ML.PREDICT(MODEL `ai-analytics-solutions.advdata.storm_reports_clustering`, ( SELECT sentences, arr_to_input_20(output_0) AS comments_embed, EXTRACT(DAYOFYEAR from timestamp) AS julian_day, longitude, latitude FROM ML.PREDICT(MODEL advdata.swivel_text_embed,( SELECT timestamp, longitude, latitude, LOWER(comments) AS sentences FROM `bigquery-public-data.noaa_preliminary_severe_storms.wind_reports` WHERE EXTRACT(YEAR from timestamp) = 2019 )))) WHERE centroid_id = 1
Результат показывает, что это в основном короткие неинформативные комментарии:
Как насчет кластера №3? Большинство этих отчетов, кажется, как-то связано с проверкой радаром !!!
Наслаждаться!
Ссылки
TensorFlow Hub имеет несколько моделей встраивания текста. Вам не обязательно использовать Swivel, хотя Swivel - хороший универсальный выбор.
Полные запросы находятся в моей записной книжке на GitHub. Вы можете опробовать запросы в консоли BigQuery или в блокноте AI Platform Jupyter.