Skip to main content

ベクトル検索の使用法

ベクトル検索は、機械学習および人工知能を使用するシステムにとって基本となる概念です。ベクトル検索では、埋め込みモデルによって、テキストなどの非構造化データが、ベクトルと呼ばれる構造化データに変換されます。これにより、ユーザは、非構造化データ自体ではなく、それらのベクトルに対して演算を実行して、入力を処理し、応答を生成することができます。

InterSystems IRIS SQL では、ベクトルを圧縮された高性能の VECTOR 型で格納できるため、ベクトル化したデータを従来のリレーショナル・スキーマの一部として効率的に格納できます。

ベクトルと埋め込み

ベクトルは、埋め込みにおいて言語の意味論的意味を表すために使用できます。これらの埋め込みは、単語を高次元の幾何学的空間にマッピングする機械学習モデルである埋め込みモデルによって決定されます。最新の埋め込みベクトルは通常、数百から数千もの次元に及びます。同様の意味論的意味を持つ単語はその空間内の近い位置を占め、異なる意味論的意味を持つ語句は互いに離れた位置を占めます。こういった空間位置により、アプリケーションでは、埋め込みベクトルに対して演算を実行することによって、2 つの単語、さらには文の類似性をアルゴリズムで判定することが可能になります。

ベクトル検索では、ドット積など、2 つのベクトルの類似性を判定する演算を使用して、入力ベクトルとデータベースに格納されているベクトルとを比較します。検索が実行されるベクトルが埋め込みを表す場合、ベクトル検索によって、意味論的に入力に最も似ているテキストの部分をアルゴリズムで判定できます。このため、ベクトル検索は、情報の取得が含まれるタスクに最適です。

ベクトルの格納

多くのプラットフォームでリストなどのデータ構造を通じてベクトルがサポートされていますが、InterSystems IRIS® データ・プラットフォームでは、専用の VECTOR 型がサポートされています。この VECTOR 型では、チップレベルの最適化を利用して、複数の要素を一度に操作するものを含め、ベクトルに対して頻繁に実行される演算が効率的に実行されます。数値 VECTOR 型には、decimal (精度が最も高い)、double、および integer (精度が最も低い) の 3 つがあります。VECTOR は、標準の SQL データ型であるため、ベクトルを他のデータと共にリレーショナル・テーブルに格納して、SQL データベースを透過的にハイブリッドのベクトル・データベースに変換できます。

ベクトル・データは、INSERT 文を使用してテーブルに追加できます。また、%Library.Vector タイプのプロパティを使用し、ObjectScript を介してオブジェクトを作成して、そのプロパティにベクトルを格納することもできます。

多くの場合、InterSystems SQL のテーブルに保存されるベクトルは埋め込みを表し、手動で簡単に表したり、追加したりすることはできません。ほとんどのアプリケーションは大量の埋め込みベクトルを扱うため、これらの埋め込みをテーブルにロードするにはプログラムを使用することが重要です。以降のセクションでは、テキストを埋め込みに変換して、その埋め込みを VECTOR としてテーブルにロードする方法について説明します。

テキストの埋め込みへの変換

InterSystems IRIS で埋め込みをベクトルとして格納する前に、まずテキスト・ソースからそれらの埋め込みを作成する必要があります。一般には、4 つのステップでテキストを埋め込みに変換できます。

  1. テキストを一連の埋め込みに変換するために使用するパッケージをインポートします。

  2. 選択した埋め込みモデルの入力仕様に合わせて、テキストを事前に処理します。

  3. 選択したパッケージのワークフローを使用して、モデルをインスタン化し、テキストを埋め込みに変換します。

  4. 個々の埋め込みを文字列に変換します。このステップは、後で埋め込みを VECTOR に変換するために必要です。

組み込み Python を使用すると、(任意のパッケージを使用して) テキストを埋め込みに変換する Python コードと共に、それらの埋め込みをデータベースに直接挿入できる ObjectScript コードを実行できます。Python パッケージを InterSystems IRIS にインポートする方法の詳細は、"Python パッケージのインストールおよびインポート" を参照してください。

例 : 組み込み Python を使用した埋め込みの作成

以下の例では、組み込みの Python リストとして渡された文の入力リストを取得して、それらを sentence_transformers パッケージを使用して埋め込みに変換し、後でテーブルに挿入できるよう埋め込みのリストを返します。埋め込みの挿入の詳細は、"VECTOR 型データの挿入" を参照してください。この例では、入力文は埋め込みモデルの仕様に合うように、事前に処理されていることが前提となっています。

ClassMethod GetEmbeddingPy(sentences) [ Language = python ]
{
  import json
  
  // import the package
  import sentence_transformers

  // create the model and form the embeddings
  model = sentence_transformers.SentenceTransformer('all-MiniLM-L6-v2')
  embeddings = model.encode(sentences)

  // convert the embeddings to a string
  embeddings_list = [str(embedding.tolist()) for embedding in embeddings]
  return embeddings_list
}

VECTOR 型データの挿入

埋め込みを表す文字列のリストを用意したら、INSERT 文を使用することによって、またはオブジェクトを作成してそのオブジェクトのプロパティとして埋め込みを格納することによって、それらの埋め込みを VECTOR としてテーブルに挿入できます。以下の例は、INSERT を使用してデータを挿入する方法を示しています。

この例では、埋め込みは一意の識別子と共にテーブルに格納されます。これらの例では、埋め込みベクトルが挿入される際、ソース・テキストは同じ一意の識別子と共に別のテーブルに格納されていることが前提となっています。一意の識別子の値を共有することで、JOIN を実行して、埋め込みベクトルをそれが表すテキストにリンクすることが可能になります。埋め込みとテキストを同じテーブルに格納する場合、一意の識別子は不要です。

埋め込みごとに、埋め込みを目的のテーブルに追加する INSERT 文を実行します。TO_VECTOR を使用して、埋め込みの文字列表現を VECTOR に変換します。

以下のコマンドでは、1 つの埋め込みが Sample.Embeddings という名前のテーブルに挿入されます。このテーブルには、2 つの列が含まれており、1 つが埋め込み自体用で、もう 1 つが、埋め込みをその派生元のテキストにリンクするために使用できる一意の識別子用です (このテキストは、同じ識別子と共に別のテーブルに暗黙的に格納されます)。(この例では、埋め込みと一意の識別子のプレースホルダとして ? が使用されています。これらは通常、文のパラメータとしてプログラムで指定されるためです。)

INSERT INTO Sample.Embeddings (Embedding, UID) 
   VALUES (TO_VECTOR(?,double), ?)

以下のコード・サンプルでは、このクエリを使用して、1 つの埋め込みをテーブルに挿入します。

 ClassMethod InsertEmbeddings(embedding As %String, uid As %Integer)
 {
   set sc=$$$OK
   try {
     set myquery = "INSERT INTO Sample.Embeddings (Embedding, UID)" 
                  _"VALUES (TO_VECTOR(?,double), ?)"
     set tStatement = ##class(%SQL.Statement).%New()
     $$$ThrowOnError(##class(%SQL.Statement).%Prepare())
 
     set rset = tStatement.%Execute(embedding, uid)
     if (rset.%SQLCODE < 0) {
       throw ##class(%Exception.SQL).CreateFromSQLCODE(rset.%SQLCODE,rset.%Message)
     }
   }
   catch e {
     set sc = e.AsStatus()
     return sc
   }
 }
 public void InsertEmbeddings(String embeddings, Integer uid) {
   try {
     // set connection parameters
     IRISDataSource ds = new IRISDataSource();
     ds.setServerName("127.0.0.1");
     ds.setPortNumber(51776);
     ds.setDatabaseName("USER");
     ds.setUser("_SYSTEM");
     ds.setPassword("SYS");
     IRISConnection conn = ds.GetConnection();
 
     String sql = "INSERT INTO Sample.Embeddings (Embedding, UID) " + 
                  "VALUES (TO_VECTOR(?,double), ?)";
     PreparedStatement pstmt = conn.prepareStatement(sql);
 
     pstmt.SetString(embedding);
     pstmt.SetInt(uid);
  
     pstmt.executeUpdate();
  
     pstmt.close();
   } catch (Exception ex) {
     System.out.println("caught exception: "
             + ex.GetClass().getName() + ": " + ex.GetMessage());
   }
 }
 def insertEmbeddings(embeddings, uid):
   // set the connection parameters
   conn_string = "localhost:1972/USER"
   username = "_system"
   password = "SYS"
   connection = iris.connect(conn_string, username, password)
   cursor = connection.cursor()
   
   try:
     sql = "INSERT INTO Sample.Embeddings (Embedding, UID) " +
           "VALUES (TO_VECTOR(?,double), ?)"
     params = [embeddings,uid]
     cursor.execute(sql,params))
     cursor.close()
   except Exception as ex:
     print(ex)
   finally:
     if cursor:
       cursor.close()
     if connection:
       connection.close()
   
 static void InsertEmbeddings(string emb, Integer uid)
 {
    // set the connection parameters
    String host = "127.0.0.1";
    String port = "51776";
    String username = "_SYSTEM";
    String password = "SYS";
    String namespace = "USER";

    IRISConnection conn = new IRISConnection();
    IRISConnect.ConnectionString = "Server = " + host
        + "; Port = " + port + "; Namespace = " + namespace
        + "; Password = " + password + "; User ID = " + username;

    conn.Open();

    String sql = "INSERT INTO Sample.Embeddings (Embedding, UID) " +
                 "VALUES (TO_VECTOR(?,double), ?)";
    IRISCommand cmd = new IRISCommand(sql, conn);
    cmd.ExecuteNonQuery();

    cmd.Dispose();
    conn.Close();
 }
FeedbackOpens in a new tab