LoginSignup
0
0

ollamaでdocumemtをembeddingしてqueryとcoscine比較どうするねん

Last updated at Posted at 2024-04-21

langchainで ollama使ってembedding

文章をベクトル化する方法はググってすぐ出てきました1

from langchain_community.embeddings import OllamaEmbeddings
ollama_emb = OllamaEmbeddings(
    model="llama:7b",
)
r1 = ollama_emb.embed_documents(
    [
        "Alpha is the first letter of Greek alphabet",
        "Beta is the second letter of Greek alphabet",
    ]
)
r2 = ollama_emb.embed_query(
    "What is the second letter of Greek alphabet"
)

embedding_utils has gone

2023年11月にopenai.embedding_utilsが使えなくなってる2

代わりに案内されているのがscipy.spatial.distance

from scipy.spatial import distance
In [19]: distance.cosine(r1[0],r2)                                                                                           ¦   )
Out[19]: 0.2281260476912138

文章をベクトル化してcosine比較します。

scipy.spatial.distance.cosine — SciPy v1.13.0 Manual

簡単に説明すると、cosine距離は2つのベクトルの類似度を表す指標です。

cosine距離は0から1の範囲の値をとり、2つのベクトルが完全に同じ方向を向いている場合は0、完全に逆方向を向いている場合は1となります。

具体的な計算方法は以下の通りです:

  1. 2つのベクトルu, vを用意する
  2. u・vはuとvの内積(ドット積)を表す
  3. ||u||_2は2ノルム(ユークリッド距離)を表す
  4. cosine距離 = 1 - (u・v) / (||u||_2 * ||v||_2)

つまり、2つのベクトルが近いほど、cosine距離は小さくなり、遠いほど大きくなるということです。

複数の文章を比べて検索器を作ろう

たまたま過去にモデル就業規則を用いて500トークンごとに分割したJSONがあります345ので、それを使いましょう。



In [21]: pd.read_json("data/model-embeddings.json")
Out[21]:
text  length                                          embedding
0    モデル就業規則令和4年 11 月版厚生労働省労働基準局監督課2はじめに1 就業規則の意義労...     500  [-0.0031310103
, -0.0081168134, 0.0068422724, -...
1     以上に分けて交替に就業させる場合においては就業時転換に関する事項(2) 賃金関係賃金の決定...     500  [-0.0118839
83400000001, -0.017528709, 0.027896...
2    その他事業場の労働者すべてに適用されるルールに関する事項なお就業規則の内容は法令及び当該...     500  [-0.00675
76934000000005, -0.0051615201, 0.0119...
3    する企業については営業所店舗等の就業規則が変更前変更後ともに本社の就業規則と同一の内容...     500  [-0.00412
3474, -0.0041268268, 0.00174996220000...
4    労基則といいます。)第6条の2)。就業規則の作成又は変更に当たってはその内容をよく吟味す...     500  [-0.01065
88136, -0.00044822950000000003, 0.011...
..                                                 ...     ...                                                ...
154   時間の通算や簡便な労働時間管理の方法について考え方を示していますのでその考え方に基づき通...     500  [-0.001495
9859000000001, -0.007987556, 0.01083...
155  日労働の合計の時間数について、1か月100時間未満及び2~6か月平均80時間以内とすること...     500  [0.000400
4154, -0.0113613438, 0.0087518478, -0...
156  ような場合に該当しないかの確認や該当しない場合であって労働時間の通算の対象となるときにおい...     500  [0.003357
9303, -0.0182754919, 0.01175449600000...
157  。・十和田運輸事件東京地判平成13年6月5日運送会社の運転手が年に1、2回の貨物運送のア...     500  [-0.01777
30452, -0.0215087812, 0.0167825092, -...
158   則により使用者の業務上の秘密を守る義務を負うとしたうえで会社が機密漏洩防止に特段の配慮を...     434  [-0.021447
9137, -0.0269076359, -0.0009704622, ...

[159 rows x 3 columns]

In [22]: df = pd.read_json("data/model-embeddings.json")

In [24]: len(df.text)
Out[24]: 159   # 159項目のモデル就業規則

In [27]: df = df[:20]  # 試しなので、先頭から20項目だけに絞ります。

In [28]: df
Out[28]:
text  length                                          embedding
0   モデル就業規則令和4年 11 月版厚生労働省労働基準局監督課2はじめに1 就業規則の意義労...     500  [-0.0031310103,
-0.0081168134, 0.0068422724, -...
1    以上に分けて交替に就業させる場合においては就業時転換に関する事項(2) 賃金関係賃金の決定...     500  [-0.01188398
3400000001, -0.017528709, 0.027896...
2   その他事業場の労働者すべてに適用されるルールに関する事項なお就業規則の内容は法令及び当該...     500  [-0.006757
6934000000005, -0.0051615201, 0.0119...
3   する企業については営業所店舗等の就業規則が変更前変更後ともに本社の就業規則と同一の内容...     500  [-0.004123
474, -0.0041268268, 0.00174996220000...
4   労基則といいます。)第6条の2)。就業規則の作成又は変更に当たってはその内容をよく吟味す...     500  [-0.010658
8136, -0.00044822950000000003, 0.011...
5   力発生時期は就業規則が何らかの方法によって労働者に周知された時期以降で就業規則に施行期日...     500  [-0.013857
6785, -0.0050431425, 0.0154229077, -...
6   日制を採用する場合の規程例第19条第2項中の「7 時間15分などの部分や第43条5第2...     500  [0.00226065
07, 0.0079080816, 0.0182731748, -0....
7   用労働者の雇用管理の改善等に関する法律平成5年法律第76号以下パートタイム有期雇用労...     500  [-0.014668
452600000001, 0.0034421473, 0.012050...
8    位の変形労働時間制隔週週休2日制を採用する場合の規程例7第19条労働時間及び休憩時間...     500  [-0.0046148
431, 0.009364034, 0.0174114592, -0....
9   家族手当第36条通勤手当第37条役付手当第38条技能資格手当第39条精勤...     500  [-0.011253
117600000001, -0.0004266213, 0.02345...
10  第56条退職金の支払方法及び支払時期第9章 無期労働契約への転換……………………………...     500  [-0.010817763400000001
, -0.0086236252, 0.00612...
11  就業に関する事項を定めるものである。2 この規則に定めた事項のほか就業に関する事項について...     500  [0.00205670
39, -0.0088717984, 0.00623263560000...
12  に関する事項については別に定めるところによる。3 前項については別に定める規則に定めのな...     500  [0.00169449
40000000002, -0.0068744714, 0.01481...
13  2.html)。2 働き方改革を推進するための関係法律の整備に関する法律平成30年法律第7...     500  [-0.0082969703, -
0.0068931733, 0.0128659317000...
14   第3条 会社はこの規則に定める労働条件により労働者に就業させる義務を負うまた労働...     500  [-0.01525460
9300000001, -0.015014798400000001,...
15  ことを要件とすること等は間接差別として禁止されています均等法第7条)。(採用時の提出書類...     500  [-0.017160
1791, -0.0022645593000000003, 0.0070...
16   か月間を試用期間とする。2 前項について会社が特に認めたときは試用期間を短縮し又は設...     500  [-0.01202933
9600000001, -0.008874323200000001,...
17  を記した労働条件通知書及びこの規則を交付して労働条件を明示するものとする。【第7条 労働条件...     500  [-0.0181804
337, 0.0012214353, 0.0092371562, -0...
18  れかの方法を希望した場合には当該方法により労働条件の明示を行うことができます。・ ファクシ...     500  [-0.0210897
569, 0.0112395687, 0.0040894994, -0...
19  り労働条件の明示を行うことはできませんさらにパートタイム有期雇用労働者については雇入...     500  [-0.002099
7389, -0.0057025515, 0.0071730209, -...

In [29]: df.embedding = ollama_emb.embed_documents(df.text)

ここで、質問をベクトル化します。

In [30]: query = "パートタイムについて"

In [31]: query_vector = ollama_emb.embed_query(query)

-3.123553991317749,
1.3652770519256592,
-0.0066312928684055805,
...]

比較する関数を作り、df.embeddingのすべての行にapplyします。

In [32]: from scipy.spatial import distance
In [33]: def compairer(x):
             return distance.cosine(x, query_vector)

In [34]: df.embedding.apply(compairer)
Out[34]:
0     0.613002
1     0.504562
2     0.799061
3     0.611230
4     0.693914
5     0.644467
6     0.805258
7     0.674750
8     0.764879
9     0.793973
10    0.657400
11    0.632991
12    0.895237
13    0.639640
14    0.513790
15    0.597422
16    0.710070
17    0.798069
18    0.729097
19    0.591398
Name: embedding, dtype: float64

最も高いスコア0.8を示したデータを選択します。
“パートタイム”という言葉が結構含まれています。

In [35]: df.text[6]
Out[35]: '日制を採用する場合)の規程例第19条第2項中の「7 時間15分」などの部分や、第43条5第2項中の「無給/通常
の賃金を支払うこと」の部分)には、あらかじめ数字や文言を記入しているものがありますが、これらは規程例の内容を分かりやす
く解説するために便宜的に記入したものですので、これらについても、法令に従い各事業場の実情に応じて具体的な数字等を定めて
ください。また、本規則は、主として通常の労働者への適用を想定して作成しています。したがって、パートタイム労働者や有期雇
用労働者等を雇用している場合、就業規則の作成に当たっては、本規則の各条項についてパートタイム労働者や有期雇用労働者等へ
の適用の可否について必ず検討し、必要に応じて別個の就業規則を作成してください。なお、パートタイム労働者や有期雇用労働者
に関する事項について就業規則を作成したり、変更する場合には、その事業場において雇用するパートタイム労働者や有期雇用労働
者の過半数を代表すると認められる者の意見を聴くように努めなければなりません(短時間労働者及び有期雇'

最も低いスコア0.5を示したデータを選択します。
“パートタイム”という言葉から遠そうです。

In [36]: df.text[1]
Out[36]: ' 以上に分けて交替に就業させる場合においては就業時転換に関する事項(2) 賃金関係賃金の決定、計算及び支払の方
法、賃金の締切り及び支払の時期並びに昇給に関する事項(3) 退職関係退職に関する事項(解雇の事由を含みます。)相対的必要
記載事項は次のとおりです。(1) 退職手当関係適用される労働者の範囲、退職手当の決定、計算及び支払の方法並びに退職手当の
支払の時期に関する事項(2) 臨時の賃金・最低賃金額関係臨時の賃金等(退職手当を除きます。)及び最低賃金額に関する事項(3
) 費用負担関係3労働者に食費、作業用品その他の負担をさせることに関する事項(4) 安全衛生関係安全及び衛生に関する事項
(5) 職業訓練関係職業訓練に関する事項(6) 災害補償・業務外の傷病扶助関係災害補償及び業務外の傷病扶助に関する事項(
7) 表彰・制裁関係表彰及び制裁の種類及び程度に関する事項(8) '

自前で組込みやってみよう

たまたまベクトル化されたデータがあったからさくっとできたものの、今はopenaiのembeddingを使わかなくてもできそうなので、それもOllamaにやってもらいましょう。

組込み用のモデルには次のようなものがあります。

Model Parameter Size
mxbai-embed-large 334M
nomic-embed-text 137M
all-minilm 23M

ollama.com/Embedding models

Chat用モデル(llama3とか)でも組込できますが、パラメータが多いためか、処理が遅かったです。
組込み処理用のモデルを使うと高速です。

text: 文字列の配列を渡して、query: 文字列との関連性を数値で返してくれるクラスを作りました。

クラスプロパティurl, modelを適宜変更してください。
ベクトルを一つ一つ比較するならdistance.cosine()が良いですが、複数のベクトルの各々の距離を調べるにはdistance.cdist(ArrayA, ArrayB, "cosine")を使いましょう6

class Embedding:
    url = "http://localhost:11434"
    model = "all-minilm"
    embedder = OllamaEmbeddings(base_url=url, model=model)

    def __init__(self, text: list[str]):
        """組込みLLMを使ってドキュメントをベクトル化し、
        compareメソッドにより比較したスコアを返す

        Usage:
            documents = [
                # ...文字列list
            ]
            emb = Embedding(documents)
            result = emb.compare("質問")
            # retult == array([[0.65659238], [0.79229155], [0.69539101],...
        """
        self.document_vector = Embedding.embedder.embed_documents(text)

    def compare(self, query: str) -> list[list[float]]:
        """queryとtextをコサイン比較する。
        スコアが0に近いほど関連性が高く、
        1に近いほど関連性が低い
        """
        query_vector = Embedding.embedder.embed_query(query)
        return distance.cdist(self.document_vector, [query_vector], "cosine")
  1. langchain_community.embeddings.ollama.OllamaEmbeddings — 🦜🔗 LangChain 0.1.16

  2. Embeddings_utils / distance formulas - where did it move?

  3. 【業務効率化】ChatGPTを活用した就業規則の自動回答システムの開発

  4. model-embedding.json

  5. 厚生労働省 / モデル就業規則について

  6. scipy.spatial.distance.cdist

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