BigQuery로 코사인 거리와 유클리드 거리 계산

5482 단어 BQBigQuery
BigQuery Advent Calendar 2020 의 6일째의 기사입니다.

아래와 같은 테이블 데이터에서 각 아이템끼리의 코사인 거리나 유클리드 거리를 빨리 BigQuery로 계산하는 방법을 설명합니다. (셀프 조인 같은 방법을 하고 있어 BigQuery적으로 좋은 방법이 아닐지도 모릅니다.


이번 데이터는, 각 아이템에 3개의 속성치가 붙어 있고, 그것을 원래와 닮은 것을 아이템을 추출하고 싶은 경우를 생각합니다. 또, 각 아이템의 속성은 향후 늘어나는 것도 상정해, 그 경우에서도 대응할 수 있는 쿼리를 생각합니다.
WITH
  item_vectors AS (
  SELECT
    item_id,
    ARRAY_AGG(attribute_value
    ORDER BY
      attribute_index) AS attribute_values
  FROM
    `xxx-yyy-zzz.sandbox.items`
  GROUP BY
    item_id )
SELECT
  item_vectors1.item_id,
  item_vectors2.item_id,
  (
  SELECT
    1-SUM(value1 * value2)/ SQRT(SUM(value1 * value1))/ SQRT(SUM(value2 * value2))
  FROM
    UNNEST(item_vectors1.attribute_values) AS value1
  WITH
  OFFSET
    pos1
  JOIN
    UNNEST(item_vectors2.attribute_values) AS value2
  WITH
  OFFSET
    pos2
  ON
    pos1 = pos2 ) AS cosine_distance,
  (
  SELECT
    SQRT( SUM((value1 - value2)*(value1 - value2)))
  FROM
    UNNEST(item_vectors1.attribute_values) AS value1
  WITH
  OFFSET
    pos1
  JOIN
    UNNEST(item_vectors2.attribute_values) AS value2
  WITH
  OFFSET
    pos2
  ON
    pos1 = pos2 ) AS euclidean_distance
FROM
  item_vectors item_vectors1
JOIN
  item_vectors item_vectors2
ON
  item_vectors1.item_id != item_vectors2.item_id
ORDER BY
  item_vectors1.item_id,
  item_vectors2.item_id


우선은, 각 아이템 마다 집약해, 속성치를 Array로서 가집니다. 그 후, 셀프 조인하여 아이템×아이템의 유사도를 계산해 갑니다.

코사인 거리와 유클리드 계산에는 UNNEST와 OFFSET을 이용하여 계산을 간단하게 할 수 있습니다.

좋은 웹페이지 즐겨찾기