NISHIO Hirokazu[日本語][English]

TTTC:empty vocabulary

Talk to the Cityにおける未解決問題

僕は2024-09-11ごろ体験した

わかっていることメモ

ValueError: empty vocabulary; perhaps the documents only contain stop words clusteringのここで発生する :

    _, __ = topic_model.fit_transform(docs, embeddings=embeddings)

(9/11)返り値を使ってないように見えるがこの行自体は必要

  • Talk to the Cityの“BERTopicつかってないのでは?“という話に関して _, __ = topic_model.fit_transform(docs, embeddings=embeddings) をコメントアウトしたら下の result = topic_model.get_document_infoで ValueError: This BERTopic instance is not fitted yet. Call 'fit' with appropriate arguments before using this estimator. になったので使ってはいる、返り値を使わずにmodelの内部状態か更新されてるだけ(だったら_, __ =ってかかなくていいのに) ということがわかりました

(9/11)PDBで追いかけてみたが途中で断念 :

409             else:
410                  # Extract topics by calculating c-TF-IDF
411  ->             self._extract_topics(documents, embeddings=embeddings)

:

(Pdb) self._c_tf_idf(documents_per_topic)
*** ValueError: empty vocabulary; perhaps the documents only contain stop words

:

3485            if partial_fit:
3486                X = self.vectorizer_model.partial_fit(documents).update_bow(documents)
3487 ->         elif fit:
3488                self.vectorizer_model.fit(documents)
3489                X = self.vectorizer_model.transform(documents)
3490            else:
3491                X = self.vectorizer_model.transform(documents)

(Pdb) self.vectorizer_model.fit(documents)
*** ValueError: empty vocabulary; perhaps the documents only contain stop words

まあvectorizer_modelは下記なのでCountVectorizerがエラーを出しているのは間違いない

   CountVectorizer = import_module(
       'sklearn.feature_extraction.text').CountVectorizer
   ...
   vectorizer_model = CountVectorizer(stop_words=stop)
   
   topic_model = BERTopic(
       umap_model=umap_model,
       hdbscan_model=hdbscan_model,
       vectorizer_model=vectorizer_model,
       verbose=True,
   )

僕の手元のsklearn.__version__のバージョンは1.3.1だった

tokenizer.get_feature_names_outとかで使われてるfeaturesを見ると、もちろん日本語は単語に分けられてない

  • defaultでCountVectorizer(..., token_pattern='(?u)\\b\\w\\w+\\b')なんだから当たり前だと思う
  • むしろ安野都知事選のタイミングでなぜこれで動いてたのかわからない
    • 振り返ってみると6/9の僕のコメント:
      • 元のソースはクラスタリング部分で英語を前提としたCountVectorizerを使ってるので僕の実験では(世界に向けて見せたかったこともあり)英語で抽出、英語でクラスタリングして結果を和訳したが、翻訳のクオリティの問題はあった。今回は日本人がターゲットなので日本語で抽出、日本語でクラスタリング、翻訳はなし、がいいのではないか。その場合は、クラスタリング部分でBag of Wordsしてるので、日本語の場合は形態素解析かキーワード抽出が必要

      • この後6/11に「日本語プロンプトでやってみたらできた」という報告があったので、時間もないから動くならそれでいいか、となった
      • 9/16のコメント
        • そもそも論としてTTTCのメインの処理の部分は日本語を想定した実装になってなくてストップワードも英語だし形態素解析もしてない。英語でやって結果を和訳するか、日本語が通るように形態素解析を入れるかのどっちかが必要なのではという話になったのだけど、プロンプトを和訳したら問題なく動いたと報告があって、自分の手元でも追試したら確かに動いたので「じゃあいいかー」となった

        • 動かない現状の方が僕の理解にマッチする振る舞い

  • 単語に分割できない時に文字での分割にfallbackする仕組みがバージョンによっては入ってるとか?

9/16の投稿:

  • 9/11の発生時はAzure関連だと思ってたので、ライブラリの依存関係を追うのが面倒で真面目な解決を諦めた
    • 代わりに抽出した日本語データに対して英訳を末尾につけるようにプロンプトを修正してワークアラウンドした
      • 末尾に英語への翻訳をつけてください。

    • その方法でワークアラウンドできるということは日本語文章のトークナイズに関する問題だろうと思っててる

9/18

  • 今現在の考えとしてはanalyzer=‘char’で動くのでは?と思っている
  • 本質的にはちゃんと形態素解析すべきだと思う
    • CountVectorizerは関数を渡してoverrideできるのでその方法で。

(C)NISHIO Hirokazu / Converted from Markdown (ja)
Source: [GitHub] / [Scrapbox]