Точка продукта одной строки против всех строк в таблице MySQL с несколькими столбцами

Фон:

У меня есть таблица строк ~ 400 000, которая выглядит следующим образом:

+---------+--------+------+-------+------+-----+--------+
|   ID    |  WORD  | COL0 | COL1  | COL2 | ... | COL500 |
+---------|--------+------+-------+------+-----+--------+
|    0    | DOG    | -0.73| 0.77  | 0.15 |     | -0.55  |
|    1    | CAT    | 0.41 | -0.57 | 0.61 |     | 0.00   |
|    2    | HOUSE  | 0.40 | 0.32  | -0.23|     | 0.52   |
|   ...   |        |      |       |      |     |        |
| 400000  | LOVE   | 0.51 | 0.59  | 0.01 |     | -0.10  |
+---------+--------+------+-------+------+-----+--------+

каждый col# представляет размерность вектора 500 дим.


Проблема:

Учитывая конкретный WORD значение (они уникальны), я хочу найти 100 WORDs, которые наиболее похожи на него на основе точечного произведения (поэтому идентичный WORD вектор будет иметь скалярное произведение 1). Так что для WORD «АВТОМОБИЛЬ» я мог бы получить:

+--------+------+
|  WORD  |  DOT |
+--------+------+
| CAR    |  1   |
| TRUCK  | 0.89 |
| SEDAN  | 0.86 |
| VEHICLE| 0.81 |
|  ...   |  ... |
| BIKE   | 0.62 |
+--------+------+

Поэтому (повторюсь) мне нужно получить скалярное произведение ‘CAR’ с каждым другим словом и отсортировать его по убыванию, и ограничить его до 100 результатов.


Потенциальные решения:

Этот вопрос очень похож и полезен, но я не совсем понимаю, как его применять («сад» называется таблицей ??).
Точка продукта в таблице SQL с множеством столбцов

2

Решение

В связанном ответе SO «сад» — это таблица: это стол t, но псевдоним garden, но ограничено одной строкой (строка для строки со словом «САД»).

И для вашего конкретного вопроса, вам нужно добавить ‘ORDER BY DOT DESC LIMIT 100 ‘до конца запроса.

Возможно, переименование делает это понятнее?

select allwords.*,
(allwords.col0 * word_of_interest.col0 +
allwords.col1 * word_of_interest.col1 + . . .
allwords.col500 * word_of_interest.col500
) as DOT
from allwords
cross join
(select allwords.*
from allwords
where `WORD` = '$THE_WORD_I_WANT_EG_CAR'
) as `word_of_interest`
order by `DOT` DESC LIMIT 100;

Как говорит другой ответ, я бы ожидал, что это будет довольно медленно. Если ваши векторные значения COLn довольно статичны, я бы подумал о том, чтобы предварительно рассчитать их и сохранить эти результаты в отдельной таблице, которую вы запросите.

1

Другие решения

Других решений пока нет …