0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AI要素⑤ 埋め込み(Embedding)

Last updated at Posted at 2025-09-28

AIの要素技術について記述します。word2vec は、単語を意味や文脈の特徴を反映した数値のベクトルに変換します。
 

word2vec

データセット(コーパス)と、CBOW または Skip-gram のアルゴリズムを使用して、モデルを作成する
モデルを使用して、入力した単語に意味が近い単語を検索できる
モデルを使用して、単語の引き算ができる(「王様」-「男」+「女」=「女王」)

- CBOW(Continuous Bag-of-Words)

周囲の単語から対象の単語を予測

- スキップグラム

対象の単語から周囲の単語を予測

サンプルプログラム

analogies_text8.py

処理内容(skip-gram)
語彙 = ["the", "of", "and", "to", "a", ..., "king", ..., "man", ..., "woman", ..., "queen", ...]
入力した単語をワンホット表現する。各単語は長さ V のベクトルに変換される
入力埋め込み行列 (V × d) との掛け算で低次元ベクトルに変換する
出力埋め込み行列でスコア化(logits)
ソフトマックス関数で、出力確率を正規化

学習は、誤差逆伝播を使用して、入力埋め込み行列と出力埋め込み行列を更新
 

ライブラリ追加
pip install gensim
analogies_text8.py
import gensim
import gensim.downloader as api
from gensim.models import Word2Vec
import numpy as np
import random

# 再現性のためのシード
SEED = 42
np.random.seed(SEED)
random.seed(SEED)

def main():
    # text8 の全文を一度リスト化(1700万語ほど)
    print("text8 をダウンロード中...")
    raw = list(api.load("text8"))

    if len(raw) == 0:
        raise ValueError("text8 の読み込みに失敗しました。")

    if isinstance(raw[0], str):
        # ただの単語列 → 200語ごとに擬似文に分割
        sentences = [raw[i:i+200] for i in range(0, len(raw), 200)]
    elif isinstance(raw[0], list) and (len(raw[0]) > 0 and isinstance(raw[0][0], str)):
        # すでに文ごとの list[list[str]]
        sentences = raw
    else:
        raise TypeError("想定外のデータ構造です。先頭要素の型を確認してください。")

    # Word2Vec モデルの学習
    print("Word2Vec を学習中...")
    model = Word2Vec(
        sentences=sentences,
        vector_size=200,
        window=5,
        min_count=5,
        sg=1,          # skip-gram
        negative=10,
        epochs=5,
        workers=4,
        seed=SEED
    )

    kv = model.wv

    # 語彙確認
    words = ["king", "man", "woman", "queen"]
    missing = [w for w in words if w not in kv.key_to_index]
    if missing:
        print("語彙に見つからなかった単語:", missing)
        print("min_count を下げる / epochs を増やす / vector_size を上げる などを試してください。")
        return

    # アナロジー: king - man + woman ≈ ?
    result = kv.most_similar(positive=["king", "woman"], negative=["man"], topn=10)
    print("\nAnalogy: king - man + woman ≈ ?")
    for rank, (word, score) in enumerate(result, 1):
        print(f"{rank:2d}. {word:>10s} (cos={score:.4f})")

    # queen とのコサイン類似度
    target_vec = kv["king"] - kv["man"] + kv["woman"]
    cos_sim_queen = np.dot(target_vec, kv["queen"]) / (
        np.linalg.norm(target_vec) * np.linalg.norm(kv["queen"])
    )
    print(f"\ncosine(king - man + woman, queen) = {cos_sim_queen:.4f}")

if __name__ == "__main__":
    main()

結果
text8 をダウンロード中...
Word2Vec を学習中...

Analogy: king - man + woman ≈ ?
 1.      queen (cos=0.6207)
 2.   daughter (cos=0.5205)
 3.   isabella (cos=0.5111)
 4.    consort (cos=0.5101)
 5.    matilda (cos=0.4994)
 6. montferrat (cos=0.4934)
 7.    infanta (cos=0.4928)
 8.      anjou (cos=0.4897)
 9.    dowager (cos=0.4889)
10.  melisende (cos=0.4871)

cosine(king - man + woman, queen) = 0.6515

 

画像や音声の場合

画像:VGG、ResNet
音声:LSTM、GRU

文書や段落の場合(doc2vec)

doc2vec は、 word2vec の拡張版で、「文書や段落をベクトルに変換する」ための手法
他には、「系列を系列に変換」する BERT や text-embedding-3 がある

系列モデル

RNN
時系列データを扱う
逐次処理型

LSTM
RNN の、過去に遡るにつれて情報が消えていってしまう問題に対応
「大事なことをメモ帳に残す」仕組みを持っていて、長い間でも覚えていられる
時系列データを扱うデファクトスタンダード
逐次処理型

トランスフォーマー
2017年に登場したモデル("Attention is All You Need" 論文)
Source-Target Attention、Self-Attention(Multi-Head Attention)
クエリ、キー、バリュー
BERT や text-embedding-3 の基盤
「全単語を並列に処理」できる

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?