У меня есть таблица id_vectors
, которая содержит id
и соответствующие им coordinates
.Каждое из coordinates
представляет собой повторяющиеся поля с 512 элементами внутри него.
Я ищу парное косинусное сходство между всеми этими векторами, например, если у меня три ids
1,2 и 3, тогда яищу таблицу, где у меня есть косинусное сходство между ними (на основе расчета с использованием 512 координат), как показано ниже:
id1 id2 similarity
1 2 0.5
1 3 0.1
2 3 0.99
Теперь в моей таблице у меня 424 970 уникальных ID
и соответствующие им 512-мерные координаты,Это означает, что в основном мне нужно создать (424970 * 424969/2) уникальную пару идентификаторов и вычислить их сходство.
Сначала я попытался выполнить следующий запрос, используя ссылку отсюда :
#standardSQL
with pairwise as
(SELECT t1.id as id_1, t1.coords as coord1, t2.id as id_2, t2.coords as coord2
FROM `project.dataset.id_vectors` t1
inner join `project.dataset.id_vectors` t2
on t1.id < t2.id)
SELECT id_1, id_2, (
SELECT
SUM(value1 * value2)/
SQRT(SUM(value1 * value1))/
SQRT(SUM(value2 * value2))
FROM UNNEST(coord1) value1 WITH OFFSET pos1
JOIN UNNEST(coord2) value2 WITH OFFSET pos2
ON pos1 = pos2
) cosine_similarity
FROM pairwise
Но после 6 часов работы я обнаружил следующее сообщение об ошибке Query exceeded resource limits. 2.2127481953201417E7 CPU seconds were used, and this query must use less than 428000.0 CPU seconds.
Тогда я подумал, а не использовать промежуточную таблицу pairwise
, почему бы мне не попытаться создатьсначала в этой таблице затем вычислим косинусное подобие.
Итак, я попробовал следующий запрос:
SELECT t1.id as id_1, t1.coords as coord1, t2.id as id_2, t2.coords as coord2
FROM `project.dataset.id_vectors` t1
inner join `project.dataset.id_vectors` t2
on t1.id < t2.id
Но на этот раз запрос не мог быть выполнен, и я обнаружил следующее сообщение: Error: Quota exceeded: Your project exceeded quota for total shuffle size limit. For more information, see https://cloud.google.com/bigquery/troubleshooting-errors
.
Затем япопытался создать таблицу еще меньшего размера, просто создав пары комбинаций идентификаторов и убрав из нее координаты, используя следующий запрос:
SELECT t1.id as id_1, t2.id as id_2
FROM `project.dataset.id_vectors` t1
inner join `project.dataset.id_vectors` t2
on t1.id < t2.id
И снова мой запрос заканчивается сообщением об ошибке Query exceeded resource limits. 610104.3843576935 CPU seconds were used, and this query must use less than 3000.0 CPU seconds. (error code: billingTierLimitExceeded)
Я полностью понимаю, что это огромный запрос, и моя остановка - моя квота выставления счетов.
Я спрашиваю, есть ли способ выполнить запрос более разумным способом?чтобы я не превышал ни resourceLimit
, shuffleSizeLimit
, ни billingTierLimit
?