LangChainとHugging FaceのSentence SimilarityモデルでテキストのEmbeddingを作成する

LangChainのAPIを使って、Hugging Faceで公開されているモデルを指定して日本語テキストのEmbeddingを作成してみました。
2023.08.15

データアナリティクス事業本部 機械学習チームの鈴木です。

LangChainを使うとHugging Faceのモデルを使ってテキストのEmbeddingを作成できることは知っていたのですが、実際に試したことがなかったので簡単な例で確認してみました。

今回はHugging Faceで日本語のテキストを扱えるSentence Similarityモデルを探してみるところから始めました。

本記事の内容

Hugging Face Hub向けのEmbeddingクラスを使い、Hugging Faceからダウンロードしたモデルを使ってテキストのEmbeddingを作成してみました。

以下のガイドのような内容になります。

HuggingFaceEmbeddingsクラスのドキュメントは以下になります。デフォルトではsentence-transformers/all-mpnet-base-v2を使いますが、model_nameパラメータにより使用するモデルを変更することができます。

モデルはHugging Faceから検索したintfloat/multilingual-e5-largeを利用させて頂きました。

多言語向けのSentence Similarityモデルになります。

やってみた

1. モデルの調査

sentence-transformers/all-mpnet-base-v2のページを確認すると、タスクはNatural Language ProcessingのSentence Similarityだったので、日本語に対応した同一タスクのモデルを検索しました。

タスクの確認

TasksがSentence SimilarityかつLanguagesがJapanseを選択して絞り込み、候補になったモデルの中からlike数やダウンロード数、ライセンスなどを条件にモデルを選びました。

モデルの検索

今回はintfloat/multilingual-e5-largeを利用させて頂きました。

Model cardのTraining DetailsのSecond stageの記載では、英語と中国語での学習が主ですが、日本語も含むcastorini/mr-tydimiracl/miraclのデータセットも使用していることが分かりました。

Evaluation resultsでもaccuracy on MTEB AmazonCounterfactualClassification (ja)を使った評価がされていることが分かります。

2. クライアント実行環境の準備

実行環境はGoogle Colaboratoryを使いました。ハードウェアアクセラレータはT4 GPU(Tesla T4 GPU)を選択しました。

Pythonのバージョンは以下でした。

!python --version
# Python 3.10.12

また、ライブラリは以下のようにインストールしました。

!pip install huggingface_hub
!pip install langchain
!pip install sentence_transformers

インストールされたライブラリのバージョンは以下でした。

!pip freeze | grep -e "langchain" -e "huggingface-hub" -e "sentence-transformers" 

# huggingface-hub==0.16.4
# langchain==0.0.264
# sentence-transformers==2.2.2

3. モデルのダウンロード

HuggingFaceEmbeddingsクラスでmodel_nameパラメータにてモデルを指定しました。

from langchain.embeddings import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-base")

実行するとモデルなどのダウンロードが行われました。

4. テキストの準備

以下のサイトの文章を利用しました。

Pythonスクリプト内で、文字列として直接利用しました。

テキストの具体的な内容は以下です。最初の2つは機械学習チームで提供している支援サービスの説明で、機械学習やシステム構築に関する内容です。3つ目はwikipediaに記載されている東京都の説明です。ベクトルにしたときには、3つ目のテキストはほかの2つとは似ていないことを期待したいです。

機械学習システム導入支援(クラスメソッド株式会社)

Amazon SageMakerなどAWSの機械学習サービスを活用したシステムの導入支援を行います。

AIや機械学習は、マーケティングから小売や流通、製造など様々なビジネスシーンで活用されています。一方で、データサイエンティストや機械学習を熟知したエンジニアがいない、機械学習のシステム部分は専門家におまかせして予測や分析など業務に集中したいといった悩みや課題も少なくありません。

機械学習やAWSの専門知識と豊富な導入実績を持つクラスメソッドが、お客様の機械学習システムの構築・導入を支援します。

レコメンドシステムプラン(クラスメソッド株式会社)

機械学習に強いクラスメソッドにおまかせください

レコメンド機能を活用しひとりひとりにあったコンテンツを提供することで、ユーザ滞在時間アップ、売上アップをはかります。

豊富な導入実績を持つクラスメソッドが、お客様のデータ検証から本番環境の構築までをサポートします。

東京都(ウィキペディア)

東京都(とうきょうと、英語: Tokyo Metropolis)は、日本の首都[1][2][注釈 2]。関東地方に位置する都[1][2]。都庁所在地は新宿区[1][注釈 3]。

区部(特別区23区)、多摩地域(26市と西多摩郡3町1村)および島嶼部(2町7村)からなる。関東南西部にあって東西に細長い都域を有し、東部は東京湾に面する[2]。西部は雲取山を最高峰とする関東山地となる[3]。

行政機関、金融機関や大企業などが集中し、新聞・放送・出版などの文化面、大学・研究機関などの教育・学術面においても日本の中枢をなす。交通面でも鉄道網、道路網、航空路の中心。

東京都と周辺7県で首都圏を構成している。特に東京圏(東京都・神奈川県・千葉県・埼玉県)の総人口は約3500万人に達し、日本の人口の約30%が集中している[4]。東京都市圏としては世界最大級の人口を有する国際的大都市である[2]。

※ テキストのライセンスはCC BY-SA 3.0Wikipedia:ウィキペディアを二次利用するより)

5. Embeddingの作成

以下のようにEmbeddingを作成しました。

sample_text = """
Amazon SageMakerなどAWSの機械学習サービスを活用したシステムの導入支援を行います。
AIや機械学習は、マーケティングから小売や流通、製造など様々なビジネスシーンで活用されています。一方で、データサイエンティストや機械学習を熟知したエンジニアがいない、機械学習のシステム部分は専門家におまかせして予測や分析など業務に集中したいといった悩みや課題も少なくありません。
機械学習やAWSの専門知識と豊富な導入実績を持つクラスメソッドが、お客様の機械学習システムの構築・導入を支援します。
"""

doc_result1 = embeddings.embed_documents([sample_text])
# または
# query_result1 = embeddings.embed_query(sample_text)
sample_text = """
機械学習に強いクラスメソッドにおまかせください
レコメンド機能を活用しひとりひとりにあったコンテンツを提供することで、ユーザ滞在時間アップ、売上アップをはかります。
豊富な導入実績を持つクラスメソッドが、お客様のデータ検証から本番環境の構築までをサポートします。
"""

doc_result2 = embeddings.embed_documents([sample_text])
# または
# query_result2 = embeddings.embed_query(sample_text)
sample_text = """
東京都(とうきょうと、英語: Tokyo Metropolis)は、日本の首都[1][2][注釈 2]。関東地方に位置する都[1][2]。都庁所在地は新宿区[1][注釈 3]。
区部(特別区23区)、多摩地域(26市と西多摩郡3町1村)および島嶼部(2町7村)からなる。関東南西部にあって東西に細長い都域を有し、東部は東京湾に面する[2]。西部は雲取山を最高峰とする関東山地となる[3]。
行政機関、金融機関や大企業などが集中し、新聞・放送・出版などの文化面、大学・研究機関などの教育・学術面においても日本の中枢をなす。交通面でも鉄道網、道路網、航空路の中心。
東京都と周辺7県で首都圏を構成している。特に東京圏(東京都・神奈川県・千葉県・埼玉県)の総人口は約3500万人に達し、日本の人口の約30%が集中している[4]。東京都市圏としては世界最大級の人口を有する国際的大都市である[2]。
"""

doc_result3 = embeddings.embed_documents([sample_text])
# または
# query_result3 = embeddings.embed_query(sample_text)

Embeddingは例えば以下のようになっていました。

print(f"Length: {len(doc_result1[0])}")
print(f"First five elements: {doc_result1[0][:5]}")
Length: 768
First five elements: [-0.006449126172810793, 0.04611961916089058, -0.006391456816345453, 0.049257416278123856, 0.025383668020367622]

HuggingFaceEmbeddingsのドキュメントによるとembed_documentsembed_queryの違いは入力のテキストおよび出力のembeddingが複数かどうかです。

6. 類似度の評価

3つの決めうちのテキストから作っただけのベクトルなのであくまで参考までですが、コサイン類似度で直感と合っていそうかは確認してみました。

from sklearn.metrics.pairwise import cosine_similarity

cosine_similarity(doc_result1, doc_result2)
# array([[0.87510902]])

cosine_similarity(doc_result1, doc_result3)
# array([[0.75636261]])

cosine_similarity(doc_result2, doc_result3)
# array([[0.75218351]])

3つ目のテキストはほかの2つと内容が明らかに異なるので、少なくとも今回の例については類似度の観点から上手くEmbeddingができていると言えそうでした。

最後に

LangChainのAPIを使って、Hugging Faceで公開されているモデルを指定して日本語テキストのEmbeddingを作成してみました。

この仕組みが使えれば、ローカルでテキストをベクトルに変換して検索やインデックスによる絞り込みをすることも可能そうですね。

参考になりましたら幸いです。

ほかに参考にした資料