OpenAIのText Embeddingを使ってゴミ分別カテゴリ判定の実験

はじめに

OpenAIのテキスト埋め込み(text-embedding-ada-002)を活用して、横浜市のごみの捨て方の分類シートに関する実験を行いました。このシートには品目名と捨て方のカテゴリが記載されており、品目リストは3000件以上に及びます。この実験の目標は、Text embedding を活用して、分類シートにない品目を入力した場合にも、その品目の捨て方を正しく予測することです。

(実は、横浜市のサイトにチャットボット「イーオ」が既に存在しており、これが精度高いので実用上はこれを活用することで十分です。)

実験内容

最初にゴミの捨てた分類シートの品目3431件のembeddingを取得しました。embeddingの取得コストが非常に低い($0.0001 / 1K tokens)のでこれくらいだと $1 にもなりません。

実験準備:カテゴリの分布の確認、embedding の可視化

まず、捨て方のカテゴリの分布を確認しました。燃やすごみが一番多く、粗大ごみ・小さな金属類が続くことがわかります。


次に tSNE で 得られた embedding にクラスタが見られるか確認しました。小さな金属類・古紙などは比較的クラスタになっているようですが、燃やすごみ・粗大ごみなどは幅広く分布しているようです。

ごみ品目名 text embedding -> tSNE


実験1: Cosine Similarityによる品目予測

この実験では、品目名 embedding同士のCosine Similarityを使用して類似度の高い品目を予測しました。以下、3431件の品目に対してそれぞれ一番類似している品目の捨て方カテゴリを予測した結果です。
    • 精度評価:
    • Accuracy: 0.47
    • Precision: 0.16
    • Recall: 0.19
    • F1 Score: 0.17

    誤りの多くは「アコーディオンカーテン(粗大ごみ)」と「カーテン(古布)」のように、キーワード文字列が類似しているが、捨て方カテゴリが別の品目によるものでした。数値だけを見ると精度があまり良くなさそうでした。

    次に以下のようなシステムを作り、キーワードに対して捨て方を返すプログラムを作成しました。

    キーワード入力 → text-embedding-ada-002 を call し embedding を取得 → 捨て方分類シートのうち一番 embedding 類似度の高い品目の「捨て方」を返す


    以下のように適当なキーワードを選んで予測するとほぼ正解と思える結果が返ってきました。 
    入力キーワード予測カテゴリ
    学習机粗大ごみ
    金属のペンダント小さな金属類
    コロコロコミック古紙(雑誌・その他の紙)
    金属製のオタマ小さな金属類
    家庭用トランポリン粗大ごみ
    カニの殻燃やすごみ
    缶・びん・ペットボトル
    電池販売店・回収協力店または専用回収箱
    電動自転車の電池販売店か回収協力店または収集事務所

    ただし、類似度の計算は素朴な実装なので、予測には多少時間がかかります。

    real 0m19.314s

  • 実験2: embeddingを特徴量として使用した分類学習

  • 次に Open AI のドキュメントから Classification using embeddings を参考に、得られたembeddingを特徴量としてRandom Forest を使用してカテゴリの予測モデルを構築しました。
  • embedding 類似度のみの予測と比較すると、カテゴリ予測精度も数値上向上しました。

    • キーワード入力 → text-embedding-ada-002 を call し embedding を取得 → Random Forestモデルの Feature として embeddingを渡し、「捨て方」カテゴリを予測

  • TreeBaseModelでの予測を行うので素朴なembedding類似度による予測に比べて速度が早いのも良いポイントでした。
    real 0m2.778s

     ただし、こちらの予測器に思いついたキーワードを入力してみると、あまり精度良くなく感じました。特に、不明な品目に関しては燃やせるごみに分類する傾向が強い点が気になりました。

入力キーワード予測カテゴリ
学習机燃やすごみ
金属のペンダント小さな金属類
コロコロコミック燃やすごみ
金属製のオタマ小さな金属類
家庭用トランポリン燃やすごみ
カニの殻燃やすごみ
燃やすごみ
電池燃やすごみ
電動自転車の電池燃やすごみ

  • 実験3: テキストに付加情報を追加したembedding

  • embeddingによる類似予測の精度を上げられないか考えて、生成時にテキストに付加情報を追加したら精度が上がるのかどうかを実験しました。
「{item}の捨て方」「{item}の大きさ・素材」

  • しかしこの方法は精度には改善が見られませんでした。text embedding API は トークンを足し合わせたときにおそらく単純な演算しか行わないのだと考えられます。

実験4: Elasticsearchを活用したCosine Similarityによる品目予測

  • 振り返ってみると、Cosine Similarity のみによるカテゴリ予測が悪くなかったので、高速化して使用感を高める実験をしました。類似度計算にはElasticsearchのknnを使用しました。
    • キーワード入力 → text-embedding-ada-002 を call し embedding を取得 → elasticsearch knn で Top N 件取得
  • キーワード:「コロコロコミック」
    • Score: 0.9373514, Document: 雑誌の切り抜き, Category: 古紙(雑誌・その他の紙)
    • Score: 0.93563974, Document: しかけ絵本, Category: 古紙(雑誌・その他の紙)
    • Score: 0.93444514, Document: コルクボード, Category: 燃やすごみ
    • Score: 0.9333709, Document: スケッチブック, Category: 古紙(雑誌・その他の紙)
    • Score: 0.93336546, Document: 広報誌, Category: 古紙(雑誌・その他の紙)

    • real 0m2.747s
  • 実行速度は速く、またランキング形式でいくつかの結果を提示することで納得感が高くなりました。

結論

検証データやパラメータ選択などは十分とは思えませんが、品目名のCosine Similarityによるカテゴリの予測がそこそこの精度であると感じられました。

機会あれば検証データを整えて数値比較をやっていきたいと思います。


コード


参考


https://www.city.yokohama.lg.jp/kurashi/sumai-kurashi/gomi-recycle/gomi/dashikata.html

https://platform.openai.com/docs/guides/embeddings/use-cases#expander-0

https://zenn.dev/yutoo89/articles/a3ade8e93f346e

https://bunsekikobako.com/t-sne-code-example/

https://medium.com/mlearning-ai/zero-shot-classification-with-embeddings-1ebc58f48726

https://www.elastic.co/guide/en/elasticsearch/reference/current/knn-search.html