Embedding(エンベディング)とは、情報をコンパクトな数値ベクトル(多くの場合は高次元ベクトル)に変換する技術を指します。主に機械学習や自然言語処理の分野で使用され、文章や単語、画像、その他のデータを数値の形で表現することで、コンピュータがそれらを処理しやすくする。ベクトルとかは高校とか大学でもやって気がするけど苦手な分野なので正直難しそうという印象しかない。
Embeddingのフロー
データ収集と前処理 語彙の作成 単語の数値化 モデルに渡してEmbeddingベクトルを生成 Embeddingベクトルの利用
こんな流れになる。ベクトルデータ自体はどこかに保存するのでそこで出てくるのがベクトルデータベースというやつ。ベクトル検索 SQLite 拡張のsqlite-vecとかPostgreSQLの拡張のpgvectorというのがある。
Embeddingのモデル
Embeddingのモデルとは、単語や文章、画像などのデータを数値ベクトルに変換するためのアルゴリズムやニューラルネットワークモデルを指します。このモデルは、データ間の意味的・特徴的な関係を捉えるために、ベクトル空間にデータを配置することを目指します。ここでは、特に自然言語処理における代表的なEmbeddingモデルをいくつか見てみます。
Word2Vec
Word2Vecは、自然言語処理で広く使われる単語埋め込みモデルです。Googleによって開発され、2つの主要なアーキテクチャ(CBOWとSkip-Gram)を使用して単語の埋め込みベクトルを学習します。
BERT
Googleが開発したトランスフォーマーベースのモデルで、双方向のコンテキスト情報を利用して文脈に基づく単語の埋め込みを学習します。BERTは文全体の意味や単語の前後関係を理解するため、より高度な言語理解が可能とのこと。
(Transformerとは、主に自然言語処理(NLP)において利用される強力なニューラルネットワークアーキテクチャです。2017年にGoogleによって発表された論文「Attention is All You Need」で初めて紹介され、その後、多くのNLPモデルやタスクにおいて基盤となる技術となっている。)
触ってみる
BERTとpgvectorを使ってベクトルデータ化してデータに突っ込んでみるというのをやってみます
# pgvectorをインストール psql -c "CREATE EXTENSION IF NOT EXISTS vector;"
pipでライブラリを持ってくる
$ pip install transformers torch psycopg2 numpy
BERTで文をベクトル化する
from transformers import BertTokenizer, BertModel import torch import numpy as np # BERTモデルとトークナイザーをロード tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') model = BertModel.from_pretrained('bert-base-uncased') def encode_text(text): # テキストをトークナイズし、BERTでベクトル化 inputs = tokenizer(text, return_tensors="pt") with torch.no_grad(): outputs = model(**inputs) # 文全体のベクトルとして[CLS]トークンのベクトルを取得 cls_embedding = outputs.last_hidden_state[0][0].numpy() return cls_embedding # サンプルの文をベクトル化 text = "I love natural language processing" vector = encode_text(text) print(f"Vector for the text: {vector}")
ベクトルを保存
import psycopg2 import numpy as np conn = psycopg2.connect( dbname="your_db_name", user="your_username", password="your_password", host="your_host", port="your_port" ) cur = conn.cursor() cur.execute(""" CREATE TABLE IF NOT EXISTS text_embeddings ( id SERIAL PRIMARY KEY, text TEXT, embedding VECTOR(768) ); """) conn.commit() def insert_embedding(text, vector): # ベクトルをPostgreSQLに挿入 cur.execute("INSERT INTO text_embeddings (text, embedding) VALUES (%s, %s)", (text, vector.tolist())) conn.commit() # サンプルの文とベクトルを挿入 insert_embedding(text, vector) # 挿入結果の確認 cur.execute("SELECT * FROM text_embeddings;") rows = cur.fetchall() for row in rows: print(row) cur.close() conn.close()
検索もできる
def search_similar_vectors(vector, top_k=5): cur = conn.cursor() cur.execute(""" SELECT text, embedding FROM text_embeddings ORDER BY embedding <-> %s LIMIT %s; """, (vector.tolist(), top_k)) results = cur.fetchall() cur.close() return results # 検索実行 similar_texts = search_similar_vectors(vector) print(f"Similar texts: {similar_texts}")