極限までシンプルなテキストエンベディングツールを作ってみる

今回は、OpenAIのAPIを使ってシンプルなテキストエンベディングツールを作り、それにStreamlitでインターフェースをつけた話をご紹介します。私はプログラミング初心者なので、少しでも同じ立場の方の参考になれば幸いです。

## 背景

テキストを数値化する「エンベディング」という概念を知りました。解説書などを見てみると確かに簡単に実行できてエンベディングという技術を使ってみたいという要求は満たせるものの、手軽に「使う」「使ってもらう」という観点ではインターフェースが欲しいなと感じました。しかし、そうなると別の解説書を見るわけですが、初心者にとってはエラーハンドリングの処理部分とかが複雑に感じてしまうありさま。　そこで、Streamlitを使って簡単なエンベディングを生成するツールを作り、自分だけでなく誰でも簡単に使えるものを作ってみようと思いました。

## 目指したもの

- **シンプルで分かりやすいコード**：初心者でも理解しやすいもの
- **手軽な操作**：CSVファイルをアップロードするだけで結果が得られる
- **再現性の高いツール**：Streamlitで直感的なインターフェースを提供

## 処理できるCSVファイルのイメージ


![スクリーンショット 2025-01-13 212339.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973582/f9f3daf0-4aaa-3a5a-a166-b0dea5b31cf8.jpeg)


## ツールのイメージ

![スクリーンショット 2025-01-13 212339.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973582/56262c31-aad2-e73a-89df-1d572741b7fd.jpeg)



以下が完成したコードと解説です。

## コード

```python
import openai # openai==0.28 を利用
import os
import pandas as pd
import streamlit as st
import io

# OpenAI APIキーの設定
openai.api_key = os.getenv("OPENAI_API_KEY")

# ファイルアップロード
file = st.file_uploader(label='CSVファイルを選んでください', type='csv')

if file is not None:
    # ファイルを読み込む
    df = pd.read_csv(io.StringIO(file.getvalue().decode("utf-8")))

    df.columns = ['text']

    # テキストエンベディング関数
    def get_embedding(text, model="text-embedding-ada-002"):
        response = openai.Embedding.create(input=[text], model=model)
        return response['data'][0]['embedding']

    # テキストカラムにエンベディングを適用
    df["embeddings"] = df['text'].apply(lambda x: get_embedding(x) if pd.notnull(x) else None)

    # 結果を保存
    df.to_csv(r'C:\Users\XXXX\Desktop\embeddings.csv', index=False)
    st.success("エンベディングの作成が完了しました。ファイル 'embeddings.csv' を確認してください。")
```

## 解説

### 初めに

このコードは初心者の私がシンプルさを重視して書いたものです。そのため、一般的なベストプラクティスから外れている部分もありますが、動作することと分かりやすさを優先しています。その点についても解説の中で触れていきます。

### 1. 必要なライブラリの準備

このコードでは以下のライブラリを使用しています。

- **openai**: OpenAIのAPIを使うため
- **pandas**: データフレーム操作のため
- **streamlit**: ユーザーインターフェースを簡単に作るため

まず、これらをインストールしてください。

```bash
pip install openai pandas streamlit
```

### 2. OpenAI APIキーの設定

環境変数にAPIキーを保存し、コード内で読み込む方法を採用しました。

```python
openai.api_key = os.getenv("OPENAI_API_KEY")
```

これにより、APIキーを直接コードに記載せずに済みます。

### 3. ファイルアップロード

Streamlitの`file_uploader`を使って、CSVファイルをアップロードできるようにしています。

```python
file = st.file_uploader(label='CSVファイルを選んでください', type='csv')
```

この部分でユーザーが選択したファイルを読み込みます。 本来なら、CSVファイルの内容やカラム名を事前にチェックするべきですが、簡易化のために固定のカラム名を設定しています。

&#x20;  &#x20;

### 4. テキストエンベディングの生成

OpenAIの`text-embedding-ada-002`モデルを使用して、各テキストのエンベディングを生成しています。

```python
def get_embedding(text, model="text-embedding-ada-002"):
    response = openai.Embedding.create(input=[text], model=model)
    return response['data'][0]['embedding']
```

`apply`メソッドを使って、データフレーム内の各行に適用しています。

### 5. 結果の保存

処理結果はCSV形式で保存します。保存先は自分の環境に合わせて変更してください。 本来なら、保存先をユーザーが指定できるようにするべきですが、ここでは固定パスを使用しています。

```python
df.to_csv(r'C:\Users\XXXX\Desktop\embeddings.csv', index=False)
```

### 6. 成功メッセージの表示

処理が完了すると、Streamlitの`success`メッセージが表示されます。

```python
st.success("エンベディングの作成が完了しました。ファイル 'embeddings.csv' を確認してください。")
```

## 実行方法

以下のコマンドでStreamlitアプリを実行できます。

```bash
streamlit run your_script_name.py
```

ブラウザにインターフェースが表示され、CSVファイルをアップロードするだけでエンベディングが作成されます。

## 出力結果
![スクリーンショット 2025-01-13 212455.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973582/f61aab0d-09fb-ad8d-f0b3-cedbf7b9d888.jpeg)


## 最後に

極力シンプルにコードを書こうとすると、それはそれで工夫が必要なんですね。ただ、インターフェースの部分はStreamlitのおかげで簡単でした。もしこの記事が少しでも参考になれば嬉しいです！ぜひ皆さんも試してみてください！

フィードバックや改善案があれば、コメントで教えていただけると幸いです！