疎な埋め込みと密な埋め込み
スパース埋め込みとデンス埋め込み、その使用例、そしてこれらの埋め込みを使用したテキスト分類の例について学ぶ。
シリーズ全体を読む
- 自然言語処理の基礎:トークン、Nグラム、Bag-of-Wordsモデル
- 言語モデルのためのニューラルネットワークとエンベッディング入門
- 疎な埋め込みと密な埋め込み
- 長文のためのセンテンス・トランスフォーマー
- 独自のテキスト埋め込みモデルをトレーニングする
- 埋め込みモデルの評価
- クラス活性化マッピング(CAM):ディープラーニングモデルにおけるより良い解釈可能性
- CLIP物体検出:AIビジョンと言語理解の融合
- SPLADEを発見:スパースデータ処理に革命を起こす
- BERTopicの探求:ニューラル・トピック・モデリングの新時代
- データの合理化次元を減らす効果的な戦略
- All-Mpnet-Base-V2:AIによる文埋め込み機能の強化
- データ分析における時系列の埋め込み
- 学習型スパース検索による情報検索の強化
- BERT(Bidirectional Encoder Representations from Transformers)とは?
- ミクスチャー・オブ・エキスパート(MoE)とは?
#はじめに
前回の投稿](https://zilliz.com/learn/Neural-Networks-and-Embeddings-for-Language-Models)では、ニューラルネットワークを深く掘り下げ、Pythonでリカレント・ニューラル・ネットワーク(RNN)を実装した。この実装により、RNNがテキストや時系列などのシーケンシャルなデータをどのように処理するかを調べることができた。各タイムステップ/トークンtで隠れ状態をサンプリングすることで、その時点までに処理されたすべてのコンテンツのベクトル表現を得ることができる。この表現は、dense embedding として知られており、コンパクトで連続的なベクトル空間に入力をエンコードする浮動小数点数の固定長配列である。
密な埋め込みは、多くの自然言語処理(NLP)や機械学習タスクの基本的な構成要素となっており、単語やその他の離散的なエンティティ間の意味的関係を捉える強力な方法を提供しています。埋め込みベクトル](https://zilliz.com/learn/what-are-binary-vector-embedding)のすべての次元に0以外の値が含まれるため、情報量は豊富ですが、非常に大きな語彙やデータセットでは計算量が膨大になる可能性があるため、「高密度」と呼ばれています。
このブログポストでは、前の2つの記事で得た知識を基に、密な埋め込みと疎な埋め込みの両方の長所(と短所)を探ります。また、これらの埋め込みが実際の状況でどのように適用できるかを説明するために、実用的なテキスト分類の例を通して歩きます。スパース埋め込みは、密な埋め込みとは対照的に、ほとんどの値がゼロであり、メモリ効率は高くなりますが、特定のタスクでは表現力が低下する可能性があることに注意することが重要です。
期待に応えるために、この投稿はエンベッディングを徹底的に深く掘り下げることを意図したものではありません。その代わりに、エンベッディングとは何か、そしてどのように分類タスクに効果的に利用できるのかについて、簡単かつハイレベルな概要を説明します。次元削減、意味的類似性、密な表現と疎な表現のトレードオフなどの重要な概念に触れます。
また、この投稿を通して、密な埋め込みにはWord2Vec、GloVe、FastTextのような一般的な単語埋め込み技術を、疎な埋め込みにはワンホットエンコーディングやTF-IDFのような技術を簡単に紹介します。これらの手法は、機械学習や自然言語処理の様々な分野に革命をもたらし、テキストデータのより微妙な理解と処理を可能にしてきた。
ここでは、機械学習モデルが生テキストを理解し、効果的に処理できる形式に変換するために、埋め込みがどのように使われるかについて説明します。密な埋込みが単語間の複雑な関係をどのように捉えることができるのか、一方、疎な埋込みが特定のタイプのモデルやデータセットに対してどのように効率的なのかを探ります。
埋込みの魅力的な世界とその応用、そして埋込みがテキストベースのタスクにおいて機械学習モデルのパフォーマンスをどのように大幅に向上させることができるかを探求してみましょう。この投稿が終わるころには、あなた自身の自然言語処理プロジェクトにおいて、いつ、どのようにエンベッディングを使うべきか、より明確に理解できるようになっていることでしょう。
スパース埋め込みと高密度埋め込み:まとめ
スパースなベクトル
スパースベクトルの埋め込み次元は,高次元で非ゼロ値が少ないという特徴があります.この構造は,従来の情報検索アプリケーションに特に適しています.ほとんどの場合(これに限ったことではありませんが)、スパース・ベクトルで使用される次元数は、1 つまたは複数の言語にわたる異なるトークンに対応します。各次元には、文書内でのそのトークンの相対的な重要度を示す値が割り当てられる。このレイアウトは、ある程度のキーワードマッチングを伴うタスクに有利である。
スパースベクトルを生成する注目すべきアルゴリズムはBM25であり、TF-IDF(Term Frequency-Inverse Document Frequency)の基礎の上に構築されている。BM25は、用語頻度の飽和関数と長さの正規化係数という2つの重要な改良を取り入れることで、TF-IDFアプローチを強化している。これらの追加により、TF-IDFの限界のいくつかに対処することができ、よりロバストで効果的なスパース表現が得られる。
密なベクトル
密なベクトル](https://zilliz.com/learn/sparse-and-dense-embeddings)の埋め込み次元は、対照的に、ニューラルネットワークに由来する埋め込みである。順序付けられた配列に並べられたとき、これらのベクトルは入力テキストの意味的本質を捉える。密な埋め込みはテキスト処理に限らず、視覚データの意味内容を表現するためにコンピュータビジョンでも広く採用されていることは注目に値する。テキスト埋め込みモデルは、一般的にこれらのベクトルを生成し、その要素のすべてではないにせよ、ほとんどが非ゼロであるという事実によって区別されます。
密な埋め込みが持つ非ゼロの性質は、セマンティック検索アプリケーションに特に効果的です。このような文脈では、キーワードが完全に一致しない場合でも、ベクトル距離の計算に基づいて、非常に類似した結果を返すことができます。この機能により、キーワードベースのアプローチでは見逃されがちな概念間の関係性を捉えることができ、よりニュアンスや文脈を意識した検索結果を得ることができる。
主な違いを要約すると、密な埋め込みは、単語やテキスト全体の意味やあいまいな意味を符号化することに優れている。単語だけではすぐにわからないような微妙な関係や文脈のニュアンスを捉えることができます。一方、疎な埋め込みは、正確なまたは隣接する概念を符号化するのに優れています。文書内の特定の用語やその重要性を明確かつ効率的に表現することができる。
どちらのタイプの埋め込みも、テキスト検索アプリケーションにおいて重要な役割を果たし、それぞれが独自の強みを発揮します。しかし、この分野では、密な埋め込みはより汎用的で適応性が高いというコンセンサスが高まっている。より広範な意味的関係を捉える能力を維持しながら、特定のタスクのために細かく調整したり、ターゲットを絞ったりすることができる。
疎な埋め込みと密な埋め込みのどちらを選択するかは、手元のタスクの特定の要件に依存することが多い。法律文書の検索や、高度に専門化された技術語彙を扱う場合など、キーワードの正確なマッチングが重要な状況では、疎な埋め込みが好まれるかもしれません。一方、密な埋め込みは、会話AIやコンテンツ推薦システムのような、文脈やセマンティクスの理解を必要とするタスクにより適しているかもしれません。
このトピックの探求を続けるにあたり、スパース埋め込みとデンス埋め込みの実用的な例を検討し、その違いと応用をより具体的に説明します。この実践的なアプローチは、自然言語処理と情報検索におけるこれらの重要な概念の理解を深めるのに役立ちます。
分類例
スパースベクトルとデンスベクトルは、特徴ベクトルに特化したものです。従来の機械学習では、特徴ベクトルは生のデータに適用された手作りのアルゴリズムから得られることが多かった。これらのベクトルは、分類器や回帰器などの様々なモデルを学習するための入力として機能した。例えば、コンピュータビジョンでは、画像はキーポイントの集まりとして表現され、多くの場合、SIFT(Scale-Invariant Feature Transform)記述子のような技術が使われる。
手作りの特徴から、スパース埋め込みやデンス埋め込みなどの学習された表現への進化は、機械学習における重要な進歩を示している。この変化により、特に自然言語処理やコンピュータビジョンのような複雑な領域において、よりニュアンスがあり、文脈を考慮したデータ表現が可能になった。
スパース埋込みとデンス埋込みの実用的な応用を説明するために、自然言語処理(NLP)の古典的な問題である感傷の分類を扱う例を見てみよう。このタスクは、テキストの一部分の感情的なトーンを決定することを含み、通常、ポジティブ、ネガティブ、またはニュートラルに分類します。2つの異なるアプローチを使って分類器を訓練します:事前に訓練されたRecurrent Neural Network (RNN)からの密な埋め込みと、TF-IDF (Term Frequency-Inverse Document Frequency)アルゴリズムを使って生成された疎な埋め込みです。
どちらのタイプの埋め込みも、形は違えど貴重な情報を持っていることに注意することが重要である。RNNからの密な埋め込みは、意味的な関係や文脈的なニュアンスを捉え、TF-IDFからの疎な埋め込みは、センチメントを決定する上で特定の単語やフレーズの重要性を強調する。
この例では、センチメント分析で人気のベンチマークであるIMDBデータセットを使用する。このデータセットは、Internet Movie Database (IMDB)ウェブサイトの映画レビューで構成され、それぞれ対応するセンチメントラベル(肯定的または否定的)と対になっています。IMDBデータセットは、多様な文体、語彙、文構造を提供し、センチメント分類モデルにとって挑戦的で現実的なテストとなるため、このタスクに特に役立ちます。
はじめに、Hugging faceのdatasetsライブラリを使ってIMDBデータセットをダウンロードします。Hugging faceはNLPリソースの中心的なハブとなっており、幅広いデータセットと事前にトレーニングされたモデルに簡単にアクセスできます。datasets**ライブラリは、NLPデータセットの取得と前処理のプロセスを簡素化し、モデルの構築とトレーニングというコアタスクに集中できるようにします。
ここでは、datasets ライブラリを使って IMDB データセットをロードする方法を説明します:
python from datasets import load_dataset
IMDBデータセットをロードする
train_dataset = load_dataset("imdb", split="train") test_dataset = load_dataset("imdb", split="test")
データセットが揃ったので、IMDBデータセットで事前に学習した大規模RNNから埋め込みを生成してみよう。ここでは、Huggingfaceの `transformers` ライブラリで簡単にアクセスできる "モダンな" RNNである `RWKV` を使用する:
パイソン
インポートトーチ
from transformers import AutoTokenizer, RwkvModel
# トークナイザーとモデルをインスタンス化する
モデル名 = "RWKV/rwkv-4-169m-pile"
tokenizer = AutoTokenizer.from_pretrained(model_name)
モデル = RwkvModel.from_pretrained(model_name)
def generate_embeddings(dataset):
"""入力データセットに対する埋め込みを生成する。
"""
embeddings = []
for n, row in enumerate(dataset):
if n % 32 == 0:
print(f"{n}/{len(dataset)}")
inputs = tokenizer(row["text"], return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
embeddings.append({"embedding": outputs.last_hidden_state, "label": row["label"]})
return embeddings
# 訓練とテストの埋め込みを生成
train_embeddings = generate_embeddings(train_dataset)
test_embeddings = generate_embeddings(test_dataset)
generate_embeddings関数は、全シーケンスの最後のトークンにおけるRNNの隠れ状態の出力を取る。これを2回実行する。1回は
trainスプリットに対して、もう1回は
test` スプリットに対して実行する。
ここから、scikit-learn
を使って、train
分割の埋め込みとラベルを使ってSVM分類器を学習する:
python from sklearn.svm import SVC
計算された埋め込みとラベル付き学習データを使って線形SVM分類器を学習する。
classifier = SVC(kernel="linear") X = [行["埋め込み"][0,-1,:] for row in train_embeddings]. classifier.fit(X, train_dataset["label"])
ここから、テストの埋め込みデータを使って予測を行うことができます。scikit-learn`はたった2行のコードで評価のための素晴らしいフレームワークを提供してくれます:
python
from sklearn.metrics import accuracy_score
# テストセットで予測する
test_predictions = classifier.predict([row["embedding"][0,-1,:] for row in test_embeddings])
# 正解率で分類器をスコアリング
accuracy = accuracy_score(test_dataset["label"], test_predictions)
print(f "accuracy: {accuracy}")
このコードを実行すると、accuracy: 0.86248
が得られるはずです。
では、スパーステキストの分類を除いて、同じことをやってみよう。ここではTF-IDF(Term Frequency-Inverse Document Frequency)ベクタライザーを使います。TF-IDFは、ある単語が文書に出現する頻度を表すTF(Term Frequency)と、コーパスに共通する単語の重みを減らすIDF(Inverse Document Frequency)を組み合わせたものです。この結果、各次元が単語の調整された頻度に対応する疎なベクトルになり、文書に固有の単語が強調され、一般的な単語は強調されなくなる。
trainと
test`の分割でスパース埋め込みを計算し、線形SVM分類器を訓練し、訓練された分類器を評価する:
python from sklearn.feature_extraction.text import TfidfVectorizer
TF-IDF vectorizerを作成し、学習データを変換する。
vectorizer = TfidfVectorizer(max_features=10000) train_vectors = vectorizer.fit_transform(train_dataset["text"])
同じvectorizerを使ってテストデータを変換する
test_vectors = vectorizer.transform(test_dataset["text"])
線形SVM分類器を学習し、予測し、評価する。
classifier = SVC(kernel="linear") classifier.fit(train_vectors, train_dataset["label"]) test_predictions = classifier.predict(test_vectors) accuracy = accuracy_score(test_dataset["label"], test_predictions) print(f "accuracy: {accuracy}")
次のように表示されます:accuracy: 0.88144`です。この例では、スパースベクトルは `RWKV` から生成された埋め込みよりもわずかに性能が良い。
これをまとめると、次のようなスクリプトになる:
python
from datasets import load_dataset
import torch
from transformers import AutoTokenizer, RwkvModel
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import accuracy_score
from sklearn.svm import SVC
# IMDBデータセットをロードする
train_dataset = load_dataset("imdb", split="train")
test_dataset = load_dataset("imdb", split="test")
# トークナイザーとモデルをインスタンス化する
モデル名 = "RWKV/rwkv-4-169m-pile"
tokenizer = AutoTokenizer.from_pretrained(model_name)
モデル = RwkvModel.from_pretrained(model_name)
def generate_embeddings(dataset):
"""入力データセットに対する埋め込みを生成する。
"""
embeddings = []
for n, row in enumerate(dataset):
if n % 32 == 0:
print(f"{n}/{len(dataset)}")
inputs = tokenizer(row["text"], return_tensors="pt")
with torch.no_grad():
outputs = model(**inputs)
embeddings.append({"embedding": outputs.last_hidden_state, "label": row["label"]})
return embeddings
vectorizer = TfidfVectorizer(max_features=10000)
# 訓練埋め込みとテスト埋め込みを生成
train_embeddings = generate_embeddings(train_dataset)
test_embeddings = generate_embeddings(test_dataset)
train_vectors = vectorizer.fit_transform(train_dataset["text"])
test_vectors = vectorizer.transform(test_dataset["text"])
# 密なベクトルで分類と予測を行う
classifier = SVC(kernel="linear")
X = [row["embedding"][0,-1,:] for row in train_embeddings] # 密なベクトルで分類と予測を行う。
classifier.fit(X, train_dataset["label"])
test_predictions = classifier.predict([row["embedding"][0,-1,:] for row in test_embeddings])
accuracy = accuracy_score(test_dataset["label"], test_predictions)
print(f "dense vector (RNN) accuracy: {accuracy}")
# スパースベクトルによる分類と予測
classifier = SVC(kernel="linear")
classifier.fit(train_vectors, train_dataset["label"])
test_predictions = classifier.predict(test_vectors)
accuracy = accuracy_score(test_dataset["label"], test_predictions)
print(f "sparse vector (tf-idf) accuracy: {accuracy}")
この実験を単独で実行したい場合は、それなりの量のRAMと十分なランタイムが必要であることを覚えておいてほしい。
まとめ
この投稿では、IMDBデータセットに対して、密な埋め込みと疎な埋め込みの両方を生成し、その後これらの埋め込みを使ってサポートベクターマシン(SVM)分類器を学習させるプロセスを探りました。この実践的なアプローチにより、実用的なセンチメント分析タスクにおける異なる埋め込み技術の有効性を比較することができました。
高密度の埋め込みには、膨大なテキストデータのコーパスで事前学習された高度なリカレントニューラルネットワーク(RNN)であるRWKVを活用した。RWKVの事前学習により、言語の複雑な意味的関係やニュアンスを捉えることができ、これは特にセンチメント分析のようなタスクに有益である。
並行して、TF-IDF(Term Frequency-Inverse Document Frequency)アルゴリズムを用いて、スパースな単語埋め込みを生成した。TF-IDFは、データセット全体の文脈の中で特定の単語の重要性を強調する、高次元の疎な表現を作成する。このアプローチは、肯定的または否定的なセンチメントと強く関連する重要な用語を捕捉するのに特に効果的である。
次に、両方のタイプの埋め込みを使用して、同じ分類を実行しました。我々の特定の実験では、密なベクトルが優れた性能を示しました。しかし、この結果は普遍的なものではなく、特定のデータセット、タスク、モデル・アーキテクチャによって異なる可能性があることに注意することが重要です。
今後の探求のための興味深い道は、アンサンブルアプローチの行列において、密な埋め込みと疎な埋め込みの両方を組み合わせる可能性です。アンサンブルは多くの場合、異なる表現手法の長所を活用し、さらに優れた性能を達成することができます。このシリーズの後半では、アンサンブル手法をより深く見ていき、よりロバストで正確なモデルを作成するためにどのように使用できるかを探ります。
次回のチュートリアルでは、RNNからトランスフォーマーに焦点を移します。トランスフォーマーは、アテンションメカニズムを組み込んだアンロールRNNとして概念化することができ、シーケンシャルなデータを処理する際にいくつかの利点を提供します。トランスフォーマーベースのエンベッディングを使用して、このセンチメント分類実験を繰り返し、ここで検討したRNNベースのアプローチと直接比較します。
さらに、検索状況における埋込みの使用についても議論を広げます。これは、今日の機械学習においてベクトルデータベースの最も一般的なアプリケーションの1つであるため、特に関連性があります。セマンティック検索や推薦システムなどの検索タスクは、関連する情報を素早く見つけるために、効率的な埋め込み表現に大きく依存しています。
これらの高度なトピックを探求することで、様々な埋め込み技術が様々なNLPタスクにどのように適用できるかをより包括的に理解することができます。また、与えられた問題に対して最も適切な埋め込み手法を選択する際のトレードオフや考慮点についても理解を深めます。
今後のチュートリアルでは、これらのエンベッディング・モデル・テクニックとその応用、そして最新の自然言語処理システムや機械学習システムへの影響について、さらに理解を深めていきますので、どうぞご期待ください。