You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

616 lines
22 KiB

WEBVTT
00:00.620 --> 00:07.640
さて、 JupyterLabのこのセッションは、 ついにベクトルを直接見ることができるということで、 期待に胸を膨らませていることだろう。
00:07.670 --> 00:15.710
だから、 あなたが5週目のフォルダに入っていて、 3日目に入っていて、 これまで以上に私についてきてくれることを願っている。
00:15.710 --> 00:20.960
今回はビジュアルが重要で、 何が起こっているのかを実感できるだろうからね。
00:20.960 --> 00:25.940
だから、 これは前日の重複にさらに追加しただけだ。
00:25.940 --> 00:33.380
まずはインポートをいくつか用意し、 そのインポートにこれから取り組む特別なものを追加した。
00:33.380 --> 00:33.920
今日は
00:33.920 --> 00:41.960
OpenAIのエンベッディングをインポートします。 これはLang Lang chain OpenAIパッケージの一部です。
00:42.230 --> 00:45.860
ラングチェーンchromaからクロマをインポートする。
00:46.130 --> 00:50.690
t-SNEと呼ばれるものについてはこれから説明します。
00:50.690 --> 00:59.720
それからPlotlyのもので、 素敵な図を作成することができます。
00:59.720 --> 01:01.750
インポートを全部やろう。
01:02.380 --> 01:07.120
よし、 定数を調べてみよう。
01:07.120 --> 01:09.040
環境変数を持ってくる。
01:09.040 --> 01:11.440
もちろん、 これはもうお馴染みだろう。
01:11.470 --> 01:14.440
ナレッジベースを読み込むためにローダーを使っている。
01:14.440 --> 01:20.920
テキスト分割ツールを使ってチャンク(123個)を作っている。
01:20.920 --> 01:27.730
そして、 契約、 製品、 従業員、 会社の4つのフォルダごとにチャンクがある。
01:28.300 --> 01:35.110
そこで、 エンベッディングと自動エンコーディングLMSについて、 もう1度思い出していただきたいのですが、
01:35.110 --> 01:40.030
これまでのコースのほとんどで、 自動回帰LMSについてお話ししてきました。
01:40.060 --> 01:49.660
今回は、 入力全体を受け取り、 それを使って1つの出力(この場合はベクトル)を作成するオートエンコーディングLMSについて初めて見ていく。
01:50.140 --> 01:53.890
そして、 自動エンコーディングのアラームの例がバートだ。
01:53.920 --> 01:56.380
これからこれを使う。
01:56.410 --> 01:58.000
OpenAIのエンベッディング。
01:58.210 --> 01:59.280
それを実行しよう。
01:59.520 --> 02:00.420
オーケー。
02:00.420 --> 02:05.010
クロマはこれからクロマ・データ・ストアを作るところだ。
02:05.310 --> 02:10.770
そして、 もしすでにデータベースがある場合は、 削除するか空にするために、 この小さなセクションをここに入れました。
02:10.800 --> 02:15.480
そうしないと、 このコードを実行するたびに、 また別のベクトルが追加され、 ある種の重複したベクトル・セットとなり、
02:15.480 --> 02:17.520
混乱することになる。
02:17.520 --> 02:20.760
これはデータベースをリフレッシュするのに役立つ。
02:20.760 --> 02:27.090
すでに1度実行したことがある人なら想像がつくと思うが、 私はすでに1度か2度実行しているので、 これは私にとって便利なものだ。
02:27.360 --> 02:28.890
削除します。
02:29.400 --> 02:41.340
このフォルダーの中にあるvector db umは、 DB名で、 DB名がvector DBであることを示すために一番上に設定した定数だ。
02:41.370 --> 02:45.480
SQLiteをベースにしている。
02:45.510 --> 02:49.440
この中に入ってみると、 SQLiteが使われているのがわかるだろう。
02:49.440 --> 02:56.730
つまり、 あなたが選んだデータベース名の中に、 さまざまなファイルが並んでいるだけなのだ。
02:56.730 --> 02:58.730
この場合はベクトルdb。
02:59.660 --> 03:06.170
それでは、 ベクターデータベースを作成し、 ベクターを入れてみましょう。
03:06.170 --> 03:08.930
そして、 私はここでまたグラディオの瞬間を迎えることになる。
03:08.930 --> 03:14.870
ドキュメントの束をベクトル化し、 それをベクトル化してベクトル・データベースに保存するプロセスは、
03:14.870 --> 03:21.740
それなりに高度なもので、 少なくとも数セルは必要だと思うかもしれない。
03:21.980 --> 03:27.200
しかし、 もちろん、 1つのセルで、 1行のコードでできることがわかるだろう。
03:27.200 --> 03:34.010
そしてそれはもちろん、 ラング・チェインが素晴らしいグルーコードをたくさん用意してくれたおかげだ。
03:34.040 --> 03:39.560
手作業でそれを繰り返し、 それぞれの埋め込みを、 それぞれのチャンクをベクトルに変換し、
03:39.560 --> 03:46.970
それをクロマに保存するのは、 実際にはそれほど難しいことではない。
03:47.060 --> 03:50.870
うーん、 でも、 こうやってひとつにまとめられたら、 もっとシンプルになるよね。
03:50.870 --> 03:55.490
そして、 これのもうひとつの素晴らしいところは、 別のベクター・データ・ストアを試してみても、
03:55.490 --> 04:01.630
ラング・チェーンからインポートされた別のベクター・ストアを使うだけで同じことができるということです。
04:01.630 --> 04:06.700
でも、 この1行を走らせてみたら走った。
04:06.700 --> 04:11.200
そして、 ベクターストアは123のドキュメントで作られている。
04:11.200 --> 04:14.800
123個のチャンクがあったのだから。
04:14.800 --> 04:21.040
だから、 ベクター・データ・ストアに同じ数のドキュメントがあるのはいいことだ。
04:21.520 --> 04:26.950
Chromeを作成して戻ってきたベクターストアオブジェクトに、
04:26.950 --> 04:35.860
チャンク、 埋め込み(OpenAIの埋め込み)、 そしてデータベース名を渡しました。
04:35.860 --> 04:40.060
この3つは私たちが提供したもので、 まったく理にかなっている。
04:40.090 --> 04:42.820
ベクターストアを作るために必要なことはこれだけだ。
04:42.820 --> 04:51.220
そして、 このベクターストアは、 underscore collection dot countを呼び出して、 ベクターストア内のドキュメント数を取得することができる。
04:51.850 --> 05:04.380
そこで、 これらのベクトルが何次元かを調べ、 これでコレクションからベクトルを取得できるようにしよう。
05:04.410 --> 05:11.640
つまり、 このアンダースコア・コレクションをベクター・ストアから呼び出すと、 コレクションが生成されます。
05:11.640 --> 05:14.040
そこでドットゲットを呼び出せばいい。
05:14.070 --> 05:15.300
制限内でパスできる。
05:15.300 --> 05:16.380
欲しいのは1つだけだ。
05:16.380 --> 05:20.550
ベクトルそのものであるエンベッディングを持ち帰らせたいのだ。
05:20.760 --> 05:26.490
その大きさを見てみよう。
05:26.490 --> 05:30.180
寸法は1536。
05:30.180 --> 05:34.920
つまり、 1536の数字がこの塊を構成している。
05:34.920 --> 05:38.850
では、 これを印刷できるように自分で見てみよう。
05:38.850 --> 05:43.260
埋め込みのサンプルを印刷してみましょう。
05:43.890 --> 05:44.430
すごい。
05:44.430 --> 05:45.810
たくさんの数字だ。
05:46.080 --> 05:48.000
つまり、 数字の羅列だ。
05:48.030 --> 05:51.360
あなたや私にとっては無意味なことだ。
05:51.540 --> 05:54.770
ええと、 でもこの数字は何らかの形で
05:55.460 --> 06:02.450
私たちは、 これらの数字が何らかの形で、 その数字に関連するチャンクの意味を反映していると見ている。
06:02.450 --> 06:03.230
いずれ分かることだ。
06:03.650 --> 06:06.560
すぐにチャンクと関連付ける。
06:07.370 --> 06:09.140
だから、 トンデモナイ数字なんだ。
06:09.140 --> 06:17.480
これは1536個の数字で、 1536次元空間の座標を表していると解釈できる。
06:17.720 --> 06:28.790
そして、 その座標は、 ベクトル空間において近い位置にある、 似たような座標を持つ他のベクトルが同じような意味を持つように選ばれている。
06:28.790 --> 06:30.740
それがこの構想のすべてだ。
06:30.980 --> 06:34.940
では、 ちょっとイメージしてみよう。
06:34.940 --> 06:37.640
そうすれば、 このようなコメントもなくなるだろう。
06:37.640 --> 06:46.070
これは、 舞台裏で何が起こっているのかを本当に調査することができる、 素晴らしい、 ええと、 ええと、 ええと、 いい方法になるだろう。
06:46.070 --> 06:53.320
だから、 Collectiongettyを呼び出して、 エンベッディング、 ドキュメント、 メタデータを求めることができる。
06:53.320 --> 06:56.320
それができたら、 ベクターを置くことができる。
06:56.320 --> 07:04.720
埋め込みをベクターの配列に入れ、 docタイプをdocタイプというものに入れる。
07:04.720 --> 07:07.960
それから、 見ての通り、 いくつかの色を作るつもりだ。
07:07.990 --> 07:10.300
だから、 これは準備のためのプレワークにすぎない。
07:10.600 --> 07:22.360
今ひとつ問題なのは、 人間には3次元以上のものを視覚化する能力がないということだ。
07:22.360 --> 07:27.610
つまり、 1536次元で何かを視覚化することは、 実に難しいことなのだ。
07:27.670 --> 07:34.360
でも、 幸運なことに、 投影法とか、 次元を2次元に縮小して、
07:34.360 --> 07:41.290
多次元表現に忠実であるように、 可能な限り物事を分離できるようにする方法とか、
07:41.290 --> 07:47.680
いろいろなテクニックがあるんだ。
07:47.680 --> 07:57.780
だから、 これらすべての次元で離れているものを、 2次元に投影してもまだかなり離れているようにしようとする。
07:58.290 --> 07:59.340
そういうことだ。
07:59.370 --> 08:04.710
そのためのテクニックはいろいろあるが、 ここでは割愛する。
08:04.710 --> 08:09.660
これはt-SNEと呼ばれるもので、 T-distributed Stochastic
08:09.660 --> 08:14.670
Neighbor embeddingの略です。
08:15.150 --> 08:19.710
何次元がいい?
08:19.740 --> 08:24.630
千差万別なものを二次元に投影してほしい。
08:24.630 --> 08:29.790
そしてこのランダム・ステートは、 ランダム・シードを設定する方法であり、 これを呼び出すたびに同じものが得られるので、
08:29.790 --> 08:33.210
これを再現できる。
08:33.450 --> 08:41.400
そして、 このt-SNEオブジェクトのfit transformメソッドを呼び出すだけで、 縮小されたベクトルを得ることができます。
08:41.820 --> 08:49.770
それから、 素晴らしいライブラリplotlyを使って散布図を作っています。
08:49.890 --> 08:56.170
そして、 これはすべて、 コピー&ペーストして好きなように再利用できるコードのようなものなんだ。
08:56.170 --> 09:01.720
でも、 ここで設定したドキュメントの種類によってマーカーの色を変えたり、
09:01.720 --> 09:14.560
ポップアップ・テキストでチャンク自体の最初の100文字を表示させたりしています。
09:14.560 --> 09:20.050
つまり、 ここで見たいのは、 ベクター・データベースでドキュメントがどのように見えるか、 ということだ。
09:20.050 --> 09:25.810
そして、 これらの異なるベクトルそれぞれについて、 どのような文書であるかによって色分けする。
09:25.810 --> 09:27.850
そして、 テキストにカーソルを合わせる。
09:27.850 --> 09:33.100
だから、 このチャンクが表すテキストの断片を少し読むことができる。
09:33.100 --> 09:34.600
だから、 これがうまくいくかどうか見てみよう。
09:34.600 --> 09:35.800
それはとてもクールだ。
09:36.370 --> 09:37.420
もちろん、 効果があることは知っている。
09:37.420 --> 09:38.470
もう試したよ。
09:38.530 --> 09:39.580
これだ。
09:39.610 --> 09:40.420
オーケー。
09:40.420 --> 09:42.040
では、 私たちは何を見ているのか。
09:42.670 --> 09:53.370
つまり、 私たちは多次元ベクトルを2次元に投影して可視化したものを見ているのであって、 X軸とY軸に特別な意味はない。
09:53.370 --> 09:59.100
いろいろなポイントを分散させる最善の方法なんだ。
09:59.190 --> 10:01.560
さて、 いくつか気になることがある。
10:01.560 --> 10:07.500
ここに見える緑の点は従業員を表している。
10:07.530 --> 10:10.350
赤い点がそれを表している。
10:10.530 --> 10:17.730
従業員というのは、 従業員の文書から抜き出したテキストのかたまりという意味だ。
10:17.760 --> 10:22.020
赤いのは契約書から出てくるテキストの塊。
10:22.050 --> 10:28.830
青は製品ドキュメントから、 黄色はアバウトなドキュメントから。
10:29.760 --> 10:36.900
さて、 OpenAIのエンベッディングは、 テキストの塊をベクトル化するときに、
10:36.930 --> 10:44.850
ドキュメントタイプを知らなかった。
10:44.850 --> 10:46.830
メタデータは伝えていない。
10:46.830 --> 10:52.190
夏の従業員、 夏の製品、 夏の契約ということは伝えていない。
10:52.190 --> 10:55.580
テキストの塊を渡して、 これをベクターに変換してくれ、 と言っただけだ。
10:55.580 --> 10:57.500
それしかなかった。
10:57.770 --> 11:04.880
だから、 そのチャンクに基づいて、 これらのチャンクがベクトル空間で分離され、 空間内の異なる領域を占めるというのは、
11:04.880 --> 11:10.730
ある意味不思議なことなんだ。
11:10.910 --> 11:16.070
内容や象徴する意味という点では、
11:16.070 --> 11:20.630
ある程度似ているからね。
11:20.630 --> 11:26.570
契約はこっちで、 製品はこっちだ。
11:26.690 --> 11:37.100
契約情報の一部が、 商品と同じ近辺にあるように見えるかもしれない。
11:37.100 --> 11:39.290
そして、 それは一瞬驚くかもしれない。
11:39.290 --> 11:41.210
何かが間違っているように見えるかもしれない。
11:41.210 --> 11:48.010
しかし、 そうではなく、 これらの塊にカーソルを合わせると、 これが契約書の特定のテキストの塊であり、
11:48.010 --> 11:53.170
そのクライアントが契約した主な機能が記述されていることがわかる。
11:53.380 --> 11:56.260
そこにテキストを入力してください。
11:56.290 --> 12:02.920
2行目のテキストと書いてあるところにカーソルを合わせると、 それがベクター空間のその場所に置かれたチャンクから抽出されたもので、
12:02.920 --> 12:10.420
1つのAIパワーのマッチングから始まっているのがわかると思います。
12:10.660 --> 12:12.250
そして、 ここでもう一つ探してみよう。
12:12.610 --> 12:17.620
ええと、 AIを使ったリスク評価機能です。
12:17.800 --> 12:19.420
同じことだよ。
12:19.870 --> 12:28.420
つまり、 契約には機能的な情報も含まれているということだ。
12:28.420 --> 12:35.980
そしてその機能は、 他の製品情報と同じようなベクトル空間に存在する。
12:35.980 --> 12:38.800
だから、 あー、 理解してもらえるといいんだけど。
12:38.830 --> 12:49.290
空間上の適切な位置と文書の背後にある意味を結びつけるのが、 これまた不気味なくらいうまいんだ。
12:49.590 --> 12:59.520
そして最後のポイントは、 これは言い過ぎかもしれないが、 本当にこういうことだと思う。
12:59.550 --> 13:04.260
会社に関する3つの文書があることにお気づきだろう。
13:04.440 --> 13:07.380
この3人が真ん中だね。
13:07.410 --> 13:10.290
彼らはこれらの異なる文書のちょうど真ん中にいる。
13:10.290 --> 13:23.370
それは、 従業員や契約、 製品に関連する情報も含まれているからだと思う。
13:23.580 --> 13:28.080
ええと、 それはすべてに関連する中心的な情報なんだ。
13:28.080 --> 13:34.950
だからこそ、 他のすべての情報の真ん中にあるような場所にあるんだ。
13:35.400 --> 13:37.350
それはとても魅力的なことだ。
13:37.350 --> 13:41.280
深読みしすぎかもしれないが、 私にはそう見える。
13:41.400 --> 13:48.770
ベクター・データベースに好きなテキストのかたまりを入れて試してみるのもいい。
13:48.860 --> 13:57.080
ここで読み込んだドキュメントに、 他のドキュメントを追加することができる。
13:57.080 --> 14:02.360
ファイルを直接指定するか、
14:02.360 --> 14:08.690
テキストを追加するか、
14:08.690 --> 14:25.940
既存のドキュメントにテキストを追加するだけです。
14:26.060 --> 14:28.220
それが全体のアイデアなんだ。
14:28.730 --> 14:33.140
この2D表現は本当にクールだった。
14:33.140 --> 14:35.420
ええと、 2Dで表現するよりもいいものがありますか?
14:35.450 --> 14:36.320
もちろんある。
14:36.350 --> 14:40.040
3D表現があり、 それが次にやることだ。
14:40.220 --> 14:51.140
2という数字を3という数字に変えるだけで、 ベクトルを3Dで視覚化することができる。
14:51.170 --> 14:52.280
それほど単純なことではなかった。
14:52.310 --> 14:59.480
ここに3Dも入れなければならなかったし、 他のベクターもいじらなければならなかった。
14:59.480 --> 15:02.510
そして、 タイトルも2Dから3Dに変更しなければならなかった。
15:02.690 --> 15:04.910
とにかく、 これがどう見えるか見てみよう。
15:04.910 --> 15:06.170
これだ。
15:06.440 --> 15:13.010
これが、 2Dではなく3Dに投影されたベクトルです。
15:13.160 --> 15:17.990
ええと、 まずお気づきになるかもしれないのは、 実は、 これは映画のように、 3Dが必ずしも2Dより優れているわけではない、
15:17.990 --> 15:23.090
稀な時代のひとつだということです。
15:23.300 --> 15:27.200
ちょっとごちゃごちゃしているように見えるね。
15:27.200 --> 15:28.790
ちょっと見づらいけど。
15:28.820 --> 15:31.100
黄色が真ん中にあるようにまた見える。
15:31.220 --> 15:34.910
そして、 緑、 赤、 青がはっきりと分かれている。
15:34.910 --> 15:40.610
しかし、 以前見たように、 予想通り、 いくつか組み合わされたものもある。
15:40.640 --> 15:46.360
でも、 これのいいところは、 積極的に、 あー、 インタラクティブにこれで遊ぶことができるんだ。
15:46.390 --> 15:48.310
このように回転させることができる。
15:49.060 --> 15:50.260
そうだろう?
15:50.260 --> 15:55.150
そして、 これを使うことで、 どのようにレイアウトされているかを把握することができる。
15:55.150 --> 15:59.830
そして、 両者の間に区別があることを感じさせてくれる。
16:00.130 --> 16:07.540
うーん、 でも、 2Dの表現ほど明確ではないことは認めざるを得ないね。
16:07.630 --> 16:10.780
あー、 それにしても、 いい感じだね。
16:10.780 --> 16:13.900
カーソルを合わせると、 ポイントの背後にある意味を見ることができる。
16:13.900 --> 16:26.410
もちろん、 前回と同じように、 黄色はすべての真ん中に位置しているように見える。
16:26.800 --> 16:36.970
3Dで表現するのも楽しいけど、 2Dの方がもう少しわかりやすい部分もあるかもしれない。
16:37.360 --> 16:43.310
とにかく、 これでベクトルを使った遊びは終わりですが、 大きな収穫があります。 それは、 これらの図を見て、
16:43.310 --> 16:50.930
さまざまなテキストのかたまりを調べるだけでなく、 あなた自身のテキストのかたまりを追加することです。
16:50.960 --> 16:55.970
簡単な方法は、 ドキュメントをナレッジ・ベース・ディレクトリに置くことだ。
16:55.970 --> 16:58.040
そうするだけで、 すぐにうまくいく。
16:58.130 --> 17:06.260
しかし、 単にドキュメントをそこにドロップするのではなく、 ラング・チェイン・コードを使ってチャンクを追加するために、 テキスト・ローダー・クラスを弄ることもできる。
17:06.260 --> 17:12.800
しかし、 チャンクを入れたら、 ベクタースペースのどこに配置されるかを見て、 それがどのように機能するか感覚をつかんでほしい。
17:12.830 --> 17:17.480
あるいは、 ナレッジ・ベース・ディレクトリを丸ごと置き換えて、 別の名前に変更し、
17:17.480 --> 17:28.430
新しいディレクトリを作成し、 その中に非常に単純なものを入れるだけで、 ドキュメントがベクター・スペース内のさまざまな場所にどのように配置されるかを実験することができます。
17:28.790 --> 17:39.170
これは超重要な宿題で、 次のパート、 つまり本格的にボロを出すときのいい基礎になるからだ。
17:39.200 --> 17:41.000
まず、 スライドに戻ろう。