Oracle DB 23ai RU23.6 でリレーショナル表のベクトル化機能が追加されました。
リレーショナル表に対して特徴量の次元削減に使う主成分分析 (PCA) のSVDアルゴリズムを適用し、構造化データをベクトル化します。
これにより、リレーショナル表に対してベクトル検索ができるようになります。
今回はサンプルデータを使って本機能を試してみました。
なおマニュアルとしては以下をご参照ください。
目次
環境情報
OCI Compute上に導入したOracle Database 23ai freeを使いました。
本検証を実施した時点でfree版は RU23.7 となっていたため、当該機能を試せました。
事前準備
準備作業は対応する他の記事をご参照ください。
23ai freeインストール
検証用DBユーザ作成
検証実施
データとしてはサンプルデータの ORDERS表 という注文履歴データを使いました。
SQL> desc ORDERS
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
ORDER_STATUS VARCHAR2(50)
UNITS NUMBER
DISCNT_VALUE NUMBER
COST_FIXED NUMBER
COST_VARIABLE NUMBER
REVENUE NUMBER
TIME_BILL_DT VARCHAR2(50)
TIME_PAID_DT VARCHAR2(50)
CUST_NAME VARCHAR2(100)
CUST_BIRTH_DT VARCHAR2(50)
CUST_CRDT_RATE NUMBER
CUST_GENDER VARCHAR2(1)
CUST_SEGMENT VARCHAR2(50)
CUST_MARITAL_STATUS VARCHAR2(50)
CUST_TYPE VARCHAR2(50)
ADDRESS1 NUMBER
ADDRESS2 VARCHAR2(50)
POSTAL_CODE VARCHAR2(50)
CITY VARCHAR2(50)
STATE_PROV VARCHAR2(50)
REGION VARCHAR2(50)
COUNTRY_CODE VARCHAR2(50)
COUNTRY_NAME VARCHAR2(100)
AREA VARCHAR2(50)
CHANNEL_NAME VARCHAR2(100)
PROD_BRAND VARCHAR2(50)
PROD_LOB VARCHAR2(50)
PROD_TYPE VARCHAR2(50)
PRODUCT VARCHAR2(50)
PROD_ITEM_DSC VARCHAR2(255)
SVD実行用の設定テーブルを作成します。
今回は5次元のベクトルデータを生成するよう設定しています。
SQL> CREATE TABLE mod_sett(
setting_name VARCHAR2(30),
setting_value VARCHAR2(30)
);
Table created.
SQL> BEGIN
INSERT INTO mod_sett (setting_name, setting_value) VALUES
(dbms_data_mining.algo_name, dbms_data_mining.algo_singular_value_decomp);
INSERT INTO mod_sett (setting_name, setting_value) VALUES
(dbms_data_mining.prep_auto, dbms_data_mining.prep_auto_on);
INSERT INTO mod_sett (setting_name, setting_value) VALUES
(dbms_data_mining.svds_scoring_mode, dbms_data_mining.svds_scoring_pca);
INSERT INTO mod_sett (setting_name, setting_value) VALUES
(dbms_data_mining.feat_num_features, 5);
commit;
END;
/
PL/SQL procedure successfully completed.
SVDを実行し、ORDERS表をベクトルするためのモデル pcamod を作成します。
SQL> BEGIN
DBMS_DATA_MINING.CREATE_MODEL(
model_name => 'pcamod',
mining_function => dbms_data_mining.feature_extraction,
data_table_name => 'ORDERS',
case_id_column_name => 'id',
settings_table_name => 'mod_sett');
END;
/
PL/SQL procedure successfully completed.
ベクトル検索を試します。
リレーショナルデータから生成した5次元のベクトルデータが確認できます。
SQL> set pagesize 1000
SQL> set linesize 1000
SQL> SET LONG 5000000
SQL> SET LONGCHUNKSIZE 5000000
SQL> SELECT id, vector_embedding(pcamod USING *) embedding
FROM ORDERS
WHERE id=300;
ID EMBEDDING
---------- -------------------------------------------------------------------------------------------------
300 [-1.1117018381556996E+004,2.735229658215892E+003,4.8564465888778941E+003,-1.4082735718521124E+003
,-8.7060448303797571E+001]
ORDERS表の各行をベクトル化した結果を保持するため、ORDERS表をベクトル化するために作成したモデル pcamod により新規に ORDERS_PCA 表を作成します。
SQL> CREATE TABLE ORDERS_PCA AS
(SELECT id, vector_embedding(pcamod USING *) embedding
FROM ORDERS);
Table created.
ORDERS_PCA表に近傍パーティション・ベクトル索引を作成
SQL> CREATE VECTOR INDEX my_ivf_idx ON orders_pca(embedding)
ORGANIZATION NEIGHBOR PARTITIONS
DISTANCE COSINE WITH TARGET ACCURACY 95;
Index created.
ORDERS表の12行目について、SVDによって抽出された影響のある列5個を確認
SQL> SELECT feature_details(pcamod, 5 USING *) features
FROM ORDERS
WHERE id=12;
FEATURES
----------------------------------------------------------------------------
<Details algorithm="Singular Value Decomposition" feature="5">
<Attribute name="COST_VARIABLE" actualValue="965.3" weight=".004" rank="1"/>
<Attribute name="UNITS" actualValue="9" weight="0" rank="2"/>
<Attribute name="REVENUE" actualValue="982.22" weight="0" rank="3"/>
<Attribute name="DISCNT_VALUE" actualValue="18.4" weight="-.001" rank="4"/>
<Attribute name="COST_FIXED" actualValue="173.05" weight="-.004" rank="5"/>
</Details>
ベクトル検索して12行目と類似度の高い3件を抽出し、12行目に影響のある列について値を確認
-- 12行目の値を確認
SELECT id, REVENUE, UNITS, DISCNT_VALUE , COST_FIXED, COST_VARIABLE
FROM ORDERS WHERE id = 12;
ID REVENUE UNITS DISCNT_VALUE COST_FIXED COST_VARIABLE
---------- ---------- ---------- ------------ ---------- -------------
12 218.72 9 9.29 109.72 251.8
-- 12行目と類似度の高い上位3件を確認
SELECT p.id id, o.REVENUE REVENUE, o.UNITS UNITS, o.DISCNT_VALUE DISCNT_VALUE,
o.COST_FIXED COST_FIXED, o.COST_VARIABLE COST_VARIABLE
FROM ORDERS o, ORDERS_PCA p
WHERE p.id <> 12 AND p.id=o.id
ORDER BY VECTOR_DISTANCE(embedding, (select embedding from ORDERS_PCA where id=12), COSINE)
FETCH FIRST 3 ROWS ONLY;
ID REVENUE UNITS DISCNT_VALUE COST_FIXED COST_VARIABLE
---------- ---------- ---------- ------------ ---------- -------------
3701 164.62 4 0 65.21 204.36
2139 125.5 13 1.54 20.18 142.72
4861 189.26 9 2.31 18.84 206.05
本当に類似しているデータなのか確認するため、12行目のデータに影響のある列について、値のばらつきを確認します。
-- REVENUE列の平均、標準偏差、最小値、最大値を確認
SELECT avg(REVENUE) avg, stddev(REVENUE) std, min(REVENUE) min, max(REVENUE) max
FROM ORDERS;
AVG STD MIN MAX
---------- ---------- ---------- ----------
970.527869 1096.17191 1.21 8397.66
-- COST_FIXED列の平均、標準偏差、最小値、最大値を確認
SELECT avg(COST_FIXED) avg, stddev(COST_FIXED) std, min(COST_FIXED) min, max(COST_FIXED) max
FROM ORDERS;
AVG STD MIN MAX
---------- ---------- ---------- ----------
260.807286 650.811544 .13 11832.6
-- COST_VARIABLE列の平均、標準偏差、最小値、最大値を確認
SELECT avg(COST_VARIABLE) avg, stddev(COST_VARIABLE) std, min(COST_VARIABLE) min, max(COST_VARIABLE) max
FROM ORDERS;
AVG STD MIN MAX
---------- ---------- ---------- ----------
711.255792 1788.83884 0 32969.66
いずれの列も値のばらつきに対して、12行目の値に近しいことが分かります。
ベクトル検索によって類似した行を抽出できたようです。
まとめ
RU23.6の新機能を使ってリレーショナル表からベクトルデータを生成し、ベクトル検索できました。
一方でこの機能を活かすには、少しだけ特徴量エンジニアリングが必要そうに思えました。
例えばIDなど、その値自体に意味が含まれていない列はベクトル検索に使って欲しくないため、事前に取り除いておく、といったことが考えられます。