Select AI for Synthetic Data Generationを試してみた

# はじめに
Oracle Autonomous DatabaseにはSelect AIという自然言語でSQLを実行できる機能があります。
詳しくはこちらをご覧ください。

https://qiita.com/tdaimon/items/9a1ca2ebcd5020d49437

そんなSelect AIにSynthetic Data Generationが実装されました。
### Synthetic Data Generationとは
Synthetic Data Generationは、実際のデータの特徴や構造を模倣した人工的なテストデータを生成するプロセスです。日本語では合成データ生成とも言います。主な特徴と利点は以下の通りです。
#### 主な特徴
- アルゴリズムやモデルを使用して、実データに基づいた人工的なデータセットを作成する
- 実データの統計的特性や構造を維持しつつ、個人情報などの機密データは含まない
- 機械学習モデルの訓練やソフトウェアのテストなどに活用できる
#### 主な利点
- プライバシー保護: 個人情報を含まないデータを生成できる
- コスト削減: 実データの収集よりも効率的にデータを作成できる
- データ拡張: 既存のデータセットを補完・拡張できる
- テストデータ作成: 新システムのテストに必要なデータを生成できる

今回は以下のブログを参考に、ある表に対してテストデータを作成 (生成)してみます。

https://blogs.oracle.com/database/post/announcing-select-ai-for-synthetic-data-generation-dbi

# テストデータの作成
### 事前準備
まずはOCI (Oracle Cloud Infrastructure)上にAutonomous Databaseを作成し実行ユーザーを作成します。
手順はこちらの「Autonomous Databaseの作成」、「ユーザー作成」を参考にしてください。

https://qiita.com/tdaimon/items/9a1ca2ebcd5020d49437

今回はSELECTAIというユーザーでSelect AI for Synthetic Data Generationを試します。

はじめに、ADMINユーザでデータベースに接続し必要な権限をSELECTAIユーザに付与します。
```
sqlplus ADMIN/xxxxxxxxxx@xxxxxxxx

grant execute on DBMS_CLOUD to SELECTAI;
grant execute on DBMS_CLOUD_AI to SELECTAI;
```

SELECTAIユーザでデータベースに接続します。
```
sqlplus SELECTAI/xxxxxxxxxx@xxxxxxxx
```

### 表の作成
テストデータを作成するにあたって、データを格納するための表を作成します。
今回はDirector表、Movie表、Actor表、Movie_Actor表を作成します。
```
CREATE TABLE SELECTAI.Director (
    director_id     INT PRIMARY KEY,
    name            VARCHAR(100)
);

CREATE TABLE SELECTAI.Movie (
    movie_id        INT PRIMARY KEY,
    title           VARCHAR(100),
    release_date    DATE,
    genre           VARCHAR(50),
    director_id     INT,
    FOREIGN KEY (director_id) REFERENCES SELECTAI.Director(director_id)
);

CREATE TABLE SELECTAI.Actor (
    actor_id        INT PRIMARY KEY,
    name            VARCHAR(100)
);

CREATE TABLE SELECTAI.Movie_Actor (
    movie_id        INT,
    actor_id        INT,
    PRIMARY KEY (movie_id, actor_id),
    FOREIGN KEY (movie_id) REFERENCES SELECTAI.Movie(movie_id),
    FOREIGN KEY (actor_id) REFERENCES SELECTAI.Actor(actor_id)
);
```

### 各種プロシージャを用いた設定
※今回はOCI Generative AI Serviceを使用します。

クレデンシャルを作成します。
```
BEGIN                                                                       
  DBMS_CLOUD.create_credential( 
    credential_name => 'GENAI_CRED', 
    user_ocid       => 'ocid1.user.oc1..XXXXXXXXXXXXXXXXXXXX',
    tenancy_ocid    => 'ocid1.tenancy.oc1..XXXXXXXXXXXXXXXXX',
    private_key     => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
    fingerprint     => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 
  ); 
END;
/ 
```
プロファイルを作成します。
 ```
BEGIN  
  DBMS_CLOUD_AI.create_profile(  
      profile_name => 'GENAI',  
      attributes   =>'{"provider":        "oci", 
                       "credential_name": "GENAI_CRED", 
                       "object_list":     [{"owner": "SELECTAI"}]}');  
END;  
/
```
属性を設定します。
```
BEGIN  
  DBMS_CLOUD_AI.set_attribute( 
      'GENAI', 'oci_compartment_id', 'ocid1.compartment.oc1..XXXXXXXX');
END;  
/
```

## データの作成
まずはDirector表のデータを作成します。
ここではrecord_countに5を指定することで、5行分のテストデータを作成します。
```
BEGIN
    DBMS_CLOUD_AI.generate_synthetic_data(
        profile_name => 'GENAI',
        object_name  => 'Director',
        owner_name   => 'SELECTAI',
        record_count => 5 );
END;
/
```
作成されたデータを確認します。
```
SQL> SELECT * FROM SELECTAI.Director;

"DIRECTOR_ID","NAME"
1,"John Smith"
2,"Emily Johnson"
3,"Michael Brown"
4,"Sarah Lee"
5,"David Kim"
```
5行分のデータが作成されたことを確認できました。
Select AIを使ってDirectorの数を聞いてみます。
```
SQL> SELECT AI how many directors are there;

"NUMBER_OF_DIRECTORS"
5
```
想定していた通りの回答が返ってきました。

次は複数の表 (Director表、Movie表、Actor表、Movie_Actor表)に対してデータを作成してみます。

:::note info
Movie表のデータを作成するにあたって、"all movies released in 2009"という指示をしています。
:::

```
BEGIN
  DBMS_CLOUD_AI.generate_synthetic_data(
    profile_name => 'GENAI',
    object_list => '[{"owner": "SELECTAI", "name": "Director","record_count":5},
                     {"owner": "SELECTAI", "name": "Movie_Actor","record_count":5},
                     {"owner": "SELECTAI", "name": "Actor","record_count":10},
                     {"owner": "SELECTAI", "name": "Movie","record_count":5,"user_prompt":"all movies released in 2009"}]' );
END;
/
```
作成されたデータを確認するためMovie表を見てみます。
```
SQL> select * from SELECTAI.Movie;

"MOVIE_ID","TITLE","RELEASE_DATE","GENRE","DIRECTOR_ID"
1,"The Hangover","01-JAN-09","Comedy",5
2,"Inglourious Basterds","20-AUG-09","Action",10
3,"Up in the Air","04-SEP-09","Drama",6
4,"The Blind Side","20-NOV-09","Biography",9
5,"Avatar","18-DEC-09","Science Fiction",1
```
RELEASE_DATEが2009年になっていることが確認できます。

最後にSelect AIを使ってActorの数を聞いてみます。
```
SQL> SELECT AI how many actors are there;

"Number of Actors"
10
```
想定していた通りの回答が返ってきました。

# まとめ
Select AI for Synthetic Data Generationを使ってテストデータを作成 (生成)してみました。
社内検索用途でSelect AIを試してみたいけどプライバシーの観点で実際のデータを使って試せないといった際には、実データを模したデータを作成しSelect AIを試してみてはいかがでしょうか。

# 参考
https://blogs.oracle.com/database/post/announcing-select-ai-for-synthetic-data-generation-dbi

https://qiita.com/tdaimon/items/9a1ca2ebcd5020d49437