WordCloudでChatGPTのチャット履歴を解析してみる

お疲れ様です。

会社の勉強会でChatGPTのチャット履歴を取得して解析をしました。 その内容を記事として残しておこうと思います。

全体観としては、取得したチャット履歴からユーザの入力内容のみを抽出し、その文書情報を使ってWordCloudを作成するというものになります。

WordCloudについて詳しくはこちら。
チャット履歴の入力内容の全体的な傾向をみることができ、実装もそれほど難しくないので採用しました。 aiacademy.jp



ChatGPTから履歴をエクスポート

ChatGPTのサイドバー下部のユーザの項目から、設定->データコントロール->エクスポートを順に選択します。その後登録したメールアドレスに履歴データのダウンロードリンクがついたメールが届くのでそこからダウンロードします。
(以前書いた記事 でも書いた方法と同じにはなります。)
export

詳細はこちらが参考になります。
www.goatman.co.jp

ダウンロードしたデータのうち、conversations.jsonを使用します。 このファイルにチャット履歴のデータが記録されています。
json

ソースコード

ソースコードはこちらにありますので、詳細はこちらをご確認ください。 なお、実際に勉強会で作成したコードを整理して再度作成したものになります。
github.com

コード解説

ベースとしてこちらの記事のコードを使用しています。
qiita.com

実装する場合下記のライブラリをインストールしてください。

pip install wordcloud janome matplotlib

コードの全体は以下のようになっています。

# ①
# conversations.jsonを読み込み
json_path = "./conversations.json"
with open(json_path, mode='r', encoding='utf-8') as f:
    json_contents = json.load(f)

# ユーザの入力内容のみを取得
text = ""
for json_content in json_contents:
    for chat_id in json_content["mapping"].keys():
        if json_content["mapping"][chat_id]["message"]:
            message = json_content["mapping"][chat_id]["message"]
            if message["author"]["role"] == "user":
                part = message["content"]["parts"][0]
                if isinstance(part, str):
                    text += part

# ②
# 正規表現を使った文字列の削除
text = re.sub(r"[^\w\s\u3000-\u9FFF]", "", text, flags=re.UNICODE)
# 文字列の正規化
text_norm = unicodedata.normalize('NFKC', text)

# 文書のtoken化(janomeで分かち書きする)
t = Tokenizer()
tokenized_text = t.tokenize(text_norm)

# 文字列のうち名詞のみを抽出
words_list=[]
for token in tokenized_text:
    tokenized_word = token.surface
    hinshi = token.part_of_speech.split(',')[0]
    hinshi2 = token.part_of_speech.split(',')[1]
    if hinshi == "名詞":
        if (hinshi2 != "数") and (hinshi2 != "代名詞") and (hinshi2 != "非自立"):
            words_list.append(tokenized_word)

# 抽出した単語のリストをスペース区切りの文字列に変換
words_wakachi = " ".join(words_list)

# ③
# 頻出単語を確認
for word_count in Counter(words_list).most_common():
    print(word_count)

# ストップワードの設定
stopwords = ["_", "u"]

# ④
# WordCloudを作成
word_cloud = WordCloud(
    font_path=r"C:\Windows\Fonts\BIZ-UDGOTHICB.TTC", 
    width=1500, height=900, stopwords=set(stopwords),
    min_font_size=5, collocations=False, background_color='white', max_words=400
)
word_cloud_img = word_cloud.generate(words_wakachi)

# 表示
figure = plt.figure(figsize=(15, 10))
plt.imshow(word_cloud_img)
plt.tick_params(labelbottom=False, labelleft=False)
plt.xticks([])
plt.yticks([])
plt.show()
figure.savefig("wordcloud.png")

①はconversations.jsonの読み込みの段階です。
チャット履歴のデータを含みますが構造がかなり複雑なので、ループを駆使してrole="user"のテキストのみを抽出しています。 ChatGPTで画像生成をさせている場合などにデータ構造が変化する場合があるのでそこは注意してください。

②はテキストの前処理の段階。下記の3つの処理を適用しています。
最終的に抽出した単語を半角スペース区切りで1つの文字列にしています。

  1. 記号を正規表現で除く処理

  2. 全角半角を統一するための正規化処理

  3. 分かち書きし名詞のみを抽出する処理

③ではWordCloud作成前の準備段階です。
単語を出現頻度順に並べて表示する処理と、ストップワードの設定の部分になります。 頻出単語の表示させ、意味のない単語があればストップワードのリストに追加するイメージです。 こちらで検討した際は、"_"と"u"があったのでストップワードに設定しています。(前処理の段階でうまく取り除けなかったようですね…。)

words

④でようやくWordCloudを作成しています。
インストールしたwordcloudのライブラリをインポートし、ここまでで作成したデータを投入すると画像として生成できます。 その後、matplotlibで画面表示させるような形になっています。

出力結果

出力結果が以下のようになりました。
私自身のチャット履歴を使用して出力してみたのですが、プログラム関係の内容をよく質問していることがわかります。
あと、「下記の内容について答えて」のような質問の仕方をよくするので「下記」という単語も頻出単語として出ています。 自分の質問の書き方の癖が可視化できるのも面白いなと思いました。

wordcloud