ロゴ ロゴ

【Python】Gemini Pro APIを使った文章類似度計算

はじめに

最近、GoogleからGeminiという言語モデルのAPIが公開されました。さっそく使ってみたので、簡単な使い方などをメモしていこうと思います。

インストールについて

Google Colab上で触ることのできるコードを公開されている方がいるので、Pythonが入っていない方はそちらを触るのが良いと思います。Pythonは3.9以上が必須でそれ以下ではGemini Proを動作させられないので注意してください。インストールコマンドは

pip install google-generativeai

になります。最新版では使用できるはずなので、特にバージョン指定はいらないと思われます。

API KEYの取得

https://makersuite.google.com/app/apikeyにアクセスして、発行することができます。特にわかりにくい点はなかったので問題ないと思いますが、ここでしくじってしまった場合は他で使い方を紹介されている動画がわかりやすいと思います。

また、APIはGemini Proであれば1分で60リクエストまでは無料で可能とのことなので(期間限定かもしれないが)、使えるうちに使っておくのがいいと思います。

使い方

まずは文章生成についての使い方を説明していきます。

import google.generativeai as genai

apikey = 'API_KEY'
genai.configure(api_key=apikey)

model = genai.GenerativeModel('gemini-pro')

response = model.generate_content("芝浦工業大学の電子計算機研究会について教えてください。",
                                   generation_config=genai.types.GenerationConfig(
                                       candidate_count=1,
                                       temperature=1,
                                       ),
                                    stream=True
                                  )
for chunk in response:
    print(chunk.text, end='')

model.generate_content関数で文章に続く文の返答を行ってくれます。candidate_countで生成する文章の候補数(現在は1のみとのこと)の指定が可能で、temperatureで返答の温度(0より大きく1以下の実数の範囲で与えあれる)によって、返答のランダム性を制御できます。0に近いほどランダムな返答になりますが、意味が破綻する可能性が上がるので注意しましょう。しかし、1にしても完全に同じ文章が出てくるとは限らないようです。また、streamTrueにすることで、ChatGPTのようなストリーム返答を可能にします。Falseの場合は以下のようにすることで返答を表示することができます。

response = model.generate_content("芝浦工業大学の電子計算機研究会について教えてください。",#"Pythonの勉強方法を教えてください",
                                    generation_config=genai.types.GenerationConfig(
                                        candidate_count=1, # 現在は1個まで
                                        temperature=0.9,
                                    )
                                    ,stream=False)
print(response.text)

ちなみに、この質問で作成された文章は次のようになります。

芝浦工業大学の電子計算機研究会は、1963年に創設された歴史ある研究会です。略称は電計研。

芝浦工業大学の電子計算機研究会は、大学における重要な技術的課題への取り組み、およびコンピューターサイエンス分野における教育における革新的なアプローチの導入を特徴としています。クラブは、AI、機械学習、暗号化、
ロボット工学、データマイニングなど、多種多様のコンピューターサイエンス分野に関する研究、開発を行う学生で構成されています。

芝浦工業大学の電子計算機研究会は、学生が技術的スキルを開発し、創造性を発揮し、問題解決能力を高めることを可能にする環境を提供することに焦点を当てています。この研究会は、革新的なプロジェクトに取り組むために学 生と教員の協働を奨励し、学生が最新の技術動向に精通していくために必要な資源とサポートを提供しています。

芝浦工業大学の電子計算機研究会は、学生が刺激的な環境の中でコンピューターサイエンスの研究に積極的に取り組むことができるように、学内の様々な活動に参加しています。学術的なプレゼンや講演会の開催、研究プロジェクトのコンテストへの参加、学外のコンピューターサイエンスイベントへの参加など、学内の様々な活動に参加しています。これらの活動により、学生はコンピューターサイエンスの知識を深め、研究プロジェクトに取り組むために必要なスキルを鍛えることができます。

芝浦工業大学の電子計算機研究会は、学生がより良いコンピューターサイエンスの専門家になるためのスキルと知識を提供することを目指しています。学生は、この研究会に参加することで、コンピューターサイエンスの基礎を学ぶことができるだけでなく、最新の技術動向に精通することもできます。また、研究プロジェクトに取り組むことで、問題解決能力を高めることができます。この研究会は、学生がコンピューターサイエンス分野で成功するための基盤を築くために必要なサポートとリソースを提供します。

Embedding(文章のベクトル変換)

自分は自然言語の素人なので、これについて詳細な解説ができるほどの知識を持ち合わせていないのですが、Embeddingは文章を洗剤空間にマッピングする役割を持っている物です。そこで、これを応用することで文章の類似度を計算することができ、検索システムなどに利用することができます。CLIPで文章から何が書かれているかを分類するというようなタスクやStableDiffusionの文章の埋め込みはこれが使用されています。Gemini Pro APIにはこれを呼び出す関数が存在し、その関数の説明は以下のようになっています。

Calls the API to create embeddings for content passed in.

    Args:
        model: Which model to call, as a string or a `types.Model`.

        content: Content to embed.

        task_type: Optional task type for which the embeddings will be used. Can only be set for `models/embedding-001`.

        title: An optional title for the text. Only applicable when task_type is `RETRIEVAL_DOCUMENT`.

    Return:
        Dictionary containing the embedding (list of float values) for the input content.

これを利用して実際にコサイン類似度を計算する関数を作成しました。

import math
def cosine_similarity(text1:str, text2:str):
    result1 = genai.embed_content(
        model="models/embedding-001",
        content=text1,
        task_type="retrieval_document",
    )['embedding']
    result2 = genai.embed_content(
        model="models/embedding-001",
        content=text2,
        task_type="retrieval_document",
    )['embedding']
    size1 = 0
    size2 = 0
    similarity = 0
    for x, y in zip(result1, result2):
        size1 += x**2
        size2 += y**2
        similarity += x * y
    return similarity / (math.sqrt(size1) * math.sqrt(size2))

コサイン類似度とは、二つのベクトルの角度をコサインを用いて計算するもので、内積からそれぞれのベクトルの大きさで割ったものといえます。言い換えると、二つのベクトルの単位ベクトルの内積です。二つのベクトル\vec{a}, \vec{b}のコサイン類似度を計算する式は次のように表せます。

\cos\theta = \frac{\vec{a}\cdot\vec{b}}{|\vec{a}||\vec{b}|}

実際にこの関数を使用してコサイン類似度を計算してみました。

text1 = '私はリンゴが好きです。'
text2 = 'I lile apples.'
text3 = 'もうやばいと、手を挙げなかった人は人生を悔い改めた方がいい。自分自身の人生を、自分はどういう考えで生きてきたんだと。ChatGPTは何回もテレビにも新聞にも雑誌にも出ているのに、それを自分自身で毎日活用してないと。もうそれは電気を否定するとか自動車を否定する人と同じ'

print(cosine_similarity(text1, text1))
print(cosine_similarity(text1, text2))
print(cosine_similarity(text1, text3))
print(cosine_similarity(text2, text3))

結果は以下のようになりました。

0.9999999999999999
0.8301109386794231
0.9237937542986656
0.7840560884687009

同じ文章を入れると1になります(計算の仮定で丸目誤差が出る場合もある)。また、Gemini Proは言語間で同じように考えているのではないということがわかります。同じ言語の方が類似度が高い当為結果になりました。しかし、内容が全く違う文章の方が類似度が低いことからしっかりと判別はされていそうです。

おわりに

今回は文章の類似度をGemini Proを使って計算しましたが、他にもチャット機能なども存在します。無料で使えるにしては強いモデルなので、これを機にAPIで何かを作ってみるのもいいのかなと思います。自分用の論文QAボットを作成でもしてみようかな…

コメント入力

関連サイト