はじめに
2つのベクトル間の距離を計算することができるvector_distance()ですが、第3引数で距離メトリックを指定することができ、距離メトリックにより結果が変わります。(デフォルトはコサイン距離)
同じデータをサンプルに違いを見ていきます。
使用するデータ
高次元ベクトルだとイメージしづらいため、下記のような2次元ベクトル (A~J) を使用します。

SQL> create table testtab(label char(1),vec vector);
Table TESTTAB created.
SQL> insert into testtab values('A','[ -8, 3]'),
2 ('B','[ 5, -2]'),
3 ('C','[ 10, 0]'),
4 ('D','[ -1, 5]'),
5 ('E','[ 7, -5]'),
6 ('F','[ -4, 1]'),
7 ('G','[ 0, -3]'),
8 ('H','[ 9, 4]'),
9 ('I','[ -10, -1]'),
10* ('J','[ 3, 2]');
10 rows inserted.
SQL> commit;
Commit complete.
SQL> select * from testtab order by 1;
LABEL VEC
________ ________________________
A [-8.0E+000,3.0E+000]
B [5.0E+000,-2.0E+000]
C [1.0E+001,0]
D [-1.0E+000,5.0E+000]
E [7.0E+000,-5.0E+000]
F [-4.0E+000,1.0E+000]
G [0,-3.0E+000]
H [9.0E+000,4.0E+000]
I [-1.0E+001,-1.0E+000]
J [3.0E+000,2.0E+000]
10 rows selected.
SQL>
ユークリッド距離 (Euclidean Distance)
第3引数にeuclideanを指定することで、ユークリッド距離を計算できます。
もっともイメージしやすい距離で、2点間の直線距離です。
短縮演算子 (<->) と別名関数 (l2_distance) が存在します。
SQL> SELECT
2 label,
3 vector_distance(
4 vector('[-6,-3]'),
5 vec,
6 euclidean
7 ) AS "Distance from P"
8 FROM
9 testtab
10 ORDER BY
11 vector_distance(
12 vector('[-6,-3]'),
13 vec,
14 euclidean
15* );
LABEL Distance from P
________ _____________________
I 4.47213595499958
F 4.47213595499958
G 6.0
A 6.324555320336759
D 9.433981132056603
J 10.295630140987
B 11.045361017187261
E 13.152946437965905
C 16.278820596099706
H 16.55294535724685
10 rows selected.
SQL>
SQL>
SQL> SELECT
2 label,
3 vector('[-6,-3]') <-> vec AS "Distance from P"
4 FROM
5 testtab
6 ORDER BY
7* vector('[-6,-3]') <-> vec;
LABEL Distance from P
________ _____________________
I 4.47213595499958
F 4.47213595499958
G 6.0
A 6.324555320336759
D 9.433981132056603
J 10.295630140987
B 11.045361017187261
E 13.152946437965905
C 16.278820596099706
H 16.55294535724685
10 rows selected.
SQL> SELECT
2 label,
3 l2_distance(
4 vector('[-6,-3]'),
5 vec
6 ) AS "Distance from P"
7 FROM
8 testtab
9 ORDER BY
10 l2_distance(
11 vector('[-6,-3]'),
12 vec
13* );
LABEL Distance from P
________ _____________________
I 4.47213595499958
F 4.47213595499958
G 6.0
A 6.324555320336759
D 9.433981132056603
J 10.295630140987
B 11.045361017187261
E 13.152946437965905
C 16.278820596099706
H 16.55294535724685
10 rows selected.
SQL>
二乗ユークリッド距離 (Squared Euclidean)
第3引数にeuclidean_squaredを指定することで、二乗ユークリッド距離を計算できます。
前述のユークリッド距離の計算から、最後の平方根 (ルート) を省略したものです。
ルートを省略した分、計算高速化を見込むことができます。
短縮演算子、別名関数は存在しません。
SQL> SELECT
2 label,
3 vector_distance(
4 vector('[-6,-3]'),
5 vec,
6 euclidean_squared
7 ) AS "Distance from P"
8 FROM
9 testtab
10 ORDER BY
11 vector_distance(
12 vector('[-6,-3]'),
13 vec,
14 euclidean_squared
15* );
LABEL Distance from P
________ __________________
I 20.0
F 20.0
G 36.0
A 40.0
D 89.0
J 106.0
B 122.0
E 173.0
C 265.0
H 274.0
10 rows selected.
SQL>
マンハッタン距離 (Manhattan Distance)
第3引数にmanhattanを指定することで、マンハッタン距離を計算できます。
単純な直線距離ではなく、マス目に沿って動くように距離を測ります。
ニューヨーク/マンハッタンが碁盤の目のような構造となっていることが由来のようです。(別名シティブロック距離、タクシー距離)
短縮演算子は存在しませんが、別名関数 (l1_distance) は存在します。
SQL> SELECT
2 label,
3 vector_distance(
4 vector('[-6,-3]'),
5 vec,
6 manhattan
7 ) AS "Distance from P"
8 FROM
9 testtab
10 ORDER BY
11 vector_distance(
12 vector('[-6,-3]'),
13 vec,
14 manhattan
15* );
LABEL Distance from P
________ __________________
I 6.0
F 6.0
G 6.0
A 8.0
B 12.0
D 13.0
J 14.0
E 15.0
C 19.0
H 22.0
10 rows selected.
SQL> SELECT
2 label,
3 l1_distance(
4 vector('[-6,-3]'),
5 vec
6 ) AS "Distance from P"
7 FROM
8 testtab
9 ORDER BY
10 l1_distance(
11 vector('[-6,-3]'),
12 vec
13* );
LABEL Distance from P
________ __________________
I 6.0
F 6.0
G 6.0
A 8.0
B 12.0
D 13.0
J 14.0
E 15.0
C 19.0
H 22.0
10 rows selected.
SQL>
コサイン距離 (Cosine Distance)
第3引数にcosineを指定することで、コサイン距離を計算できます。
コサイン距離は、2つのベクトルが向いている方向の相違度を表し、1-コサイン類似度 で求められます。
A (-8, 3) と P (-6, -3) を例に計算すると下記の通りです。
1 - \frac{(-8) \times (-6) + 3 \times (-3)}{\sqrt{(-8)^2 + 3^2} \times \sqrt{(-6)^2 + (-3)^2}} = 1 - \frac{39}{\sqrt{73} \times \sqrt{45}} \approx 1 - 0.68 = 0.32
短縮演算子 (<=>) と別名関数 (cosine_distance) が存在します。
SQL> SELECT
2 label,
3 vector_distance(
4 vector('[-6,-3]'),
5 vec,
6 cosine
7 ) AS "Distance from P"
8 FROM
9 testtab
10 ORDER BY
11 vector_distance(
12 vector('[-6,-3]'),
13 vec,
14 cosine
15* );
LABEL Distance from P
________ ______________________
I 0.06551226507103192
F 0.24074339763470343
A 0.3195489006327221
G 0.5527864045000421
D 1.2631174057921088
E 1.4678877204190326
B 1.6643638388299198
C 1.8944271909999157
J 1.9922778767136677
H 1.9989685402102997
10 rows selected.
SQL> SELECT
2 label,
3 vector('[-6,-3]') <=> vec AS "Distance from P"
4 FROM
5 testtab
6 ORDER BY
7* vector('[-6,-3]') <=> vec;
LABEL Distance from P
________ ______________________
I 0.06551226507103192
F 0.24074339763470343
A 0.3195489006327221
G 0.5527864045000421
D 1.2631174057921088
E 1.4678877204190326
B 1.6643638388299198
C 1.8944271909999157
J 1.9922778767136677
H 1.9989685402102997
10 rows selected.
SQL> SELECT
2 label,
3 cosine_distance(
4 vector('[-6,-3]'),
5 vec
6 ) AS "Distance from P"
7 FROM
8 testtab
9 ORDER BY
10 cosine_distance(
11 vector('[-6,-3]'),
12 vec
13* );
LABEL Distance from P
________ ______________________
I 0.06551226507103192
F 0.24074339763470343
A 0.3195489006327221
G 0.5527864045000421
D 1.2631174057921088
E 1.4678877204190326
B 1.6643638388299198
C 1.8944271909999157
J 1.9922778767136677
H 1.9989685402102997
10 rows selected.
SQL>
否定ドット積 (Negative Dot Product)
第3引数にdotを指定することで、否定ドット積を計算できます。
コサイン距離とコサイン類似度は、ベクトルのドット積 (内積) をノルムで除算して正規化していますが、この除算を行わない事でノルムが考慮されます。
短縮演算子 (<#>) と別名関数 (-1 * inner_product) が存在します。
SQL> SELECT
2 label,
3 vector_distance(
4 vector('[-6,-3]'),
5 vec,
6 dot
7 ) AS "Distance from P"
8 FROM
9 testtab
10 ORDER BY
11 vector_distance(
12 vector('[-6,-3]'),
13 vec,
14 dot
15* );
LABEL Distance from P
________ __________________
I -63.0
A -39.0
F -21.0
G -9.0
D 9.0
B 24.0
J 24.0
E 27.0
C 60.0
H 66.0
10 rows selected.
SQL> SELECT
2 label,
3 vector('[-6,-3]') <#> vec AS "Distance from P"
4 FROM
5 testtab
6 ORDER BY
7* vector('[-6,-3]') <#> vec;
LABEL Distance from P
________ __________________
I -63.0
A -39.0
F -21.0
G -9.0
D 9.0
B 24.0
J 24.0
E 27.0
C 60.0
H 66.0
10 rows selected.
SQL> SELECT
2 label,
3 -1 * inner_product(
4 vector('[-6,-3]'),
5 vec
6 ) AS "Distance from P"
7 FROM
8 testtab
9 ORDER BY
10 -1 * inner_product(
11 vector('[-6,-3]'),
12 vec
13* );
LABEL Distance from P
________ __________________
I -63.0
A -39.0
F -21.0
G -9.0
D 9.0
B 24.0
J 24.0
E 27.0
C 60.0
H 66.0
10 rows selected.
SQL>
ハミング距離 (Hamming Distance)
第3引数にhammingを指定することで、ハミング距離を計算できます。
ハミング距離は、対応する要素ごとに値が異なる要素の数です。
P (-6, -3) と G (0, -3) を例に考えると、1つ目の要素が -6 と 0 で異なる為、ハミング距離は 1 です。
P (-6, -3) と B (5, -2) を例に考えると、1つ目の要素も 2つ目の要素も異なる為、ハミング距離は 2 です。
短縮演算子は存在しませんが、別名関数 (hamming_distance) は存在します。
SQL> SELECT
2 label,
3 vector_distance(
4 vector('[-6,-3]'),
5 vec,
6 hamming
7 ) AS "Distance from P"
8 FROM
9 testtab
10 ORDER BY
11 vector_distance(
12 vector('[-6,-3]'),
13 vec,
14 hamming
15* );
LABEL Distance from P
________ __________________
G 1.0
B 2.0
C 2.0
D 2.0
J 2.0
F 2.0
H 2.0
I 2.0
A 2.0
E 2.0
10 rows selected.
SQL> SELECT
2 label,
3 hamming_distance(
4 vector('[-6,-3]'),
5 vec
6 ) AS "Distance from P"
7 FROM
8 testtab
9 ORDER BY
10 hamming_distance(
11 vector('[-6,-3]'),
12 vec
13* );
LABEL Distance from P
________ __________________
G 1.0
B 2.0
C 2.0
D 2.0
J 2.0
F 2.0
H 2.0
I 2.0
A 2.0
E 2.0
10 rows selected.
SQL>
ジャッカード距離 (Jaccard Distance)
第3引数にjaccardを指定することでジャッカード距離を計算できますが、入力としてバイナリ形式のベクトルが必要なため、ここではエラーとなります。
ORA-51837: VECTOR_DISTANCE() with Jaccard metric or JACCARD_DISTANCE() requires
BINARY format input vectors: encountered dimension formats (FLOAT32, FLOAT32)
ORA-51837: JaccardメトリックによるVECTOR_DISTANCE()またはJACCARD_DISTANCE()の使用にはBINARY形式の入力ベクトルが必要ですが、(FLOAT32, FLOAT32)形式の次元が指定されました。
SQL> SELECT
2 label,
3 vector_distance(
4 vector('[-6,-3]'),
5 vec,
6 jaccard
7 ) AS "Distance from P"
8 FROM
9 testtab
10 ORDER BY
11 vector_distance(
12 vector('[-6,-3]'),
13 vec,
14 jaccard
15* );
Error starting at line : 1 in command -
SELECT
label,
vector_distance(
vector('[-6,-3]'),
vec,
jaccard
) AS "Distance from P"
FROM
testtab
ORDER BY
vector_distance(
vector('[-6,-3]'),
vec,
jaccard
)
Error report -
ORA-12801: error signaled in parallel query server P003, instance 4
ORA-51837: VECTOR_DISTANCE() with Jaccard metric or JACCARD_DISTANCE() requires
BINARY format input vectors: encountered dimension formats (FLOAT32, FLOAT32)
https://docs.oracle.com/error-help/db/ora-12801/
More Details :
https://docs.oracle.com/error-help/db/ora-12801/
https://docs.oracle.com/error-help/db/ora-51837/
SQL>
バイナリ形式のベクトルを使用するには、CREATE TABLE時に指定する必要があります。
The possible dimension formats are:
INT8 (8-bit integers)
FLOAT32 (32-bit IEEE floating-point numbers)
FLOAT64 (64-bit IEEE floating-point numbers)
BINARY (packed UINT8 bytes where each dimension is a single bit)
まとめ
各距離メトリックを指定する際のパラメータや短縮演算子の有無は下記の通りです。
| 距離メトリック | パラメータ (vector_distance) | 短縮演算子 | 別名関数 |
|---|---|---|---|
| ユークリッド距離 | EUCLIDEAN | <-> | L2_DISTANCE |
| 二乗ユークリッド距離 | EUCLIDEAN_SQUARED | ||
| マンハッタン距離 | MANHATTAN | L1_DISTANCE | |
| コサイン距離 | COSINE | <=> | COSINE_DISTANCE |
| 否定ドット積 | DOT | <#> | -1*INNER_PRODUCT |
| ハミング距離 | HAMMING | HAMMING_DISTANCE | |
| ジャッカード距離 | JACCARD | JACCARD_DISTANCE |
各距離メトリックの計算結果は下記の通りとなりました。
どの距離メトリックを使えば良いかは、使用するモデルの FAQ や README を確認しましょう。
| 順位 | (二乗) ユークリッド距離 | マンハッタン距離 | コサイン距離 | 否定ドット積 | ハミング距離 |
|---|---|---|---|---|---|
| 1 | I | I | I | I | G |
| 2 | F | F | F | A | B |
| 3 | G | G | A | F | C |
| 4 | A | A | G | G | D |
| 5 | D | B | D | D | J |
| 6 | J | D | E | B | F |
| 7 | B | J | B | J | H |
| 8 | E | E | C | E | I |
| 9 | C | C | J | C | A |
| 10 | H | H | H | H | E |
Which distance function should I use?
We recommend cosine similarity. The choice of distance function typically doesn’t matter much.
ご参考:


