0
0

数百の文章からAWS生成AIで話題を取得してみた(その2)

Last updated at Posted at 2024-09-01

背景

こちらの記事の続きになります。

umapで次元削減 -> hdbscanでクラスタリング

前回の記事で取得した(100, 1536)行列を、まずは(100, 適当な次元数)行列へ次元削減しようと思います。
次元削減を行う理由としては、1536次元は後続のクラスタリング処理にとっては多次元過ぎる気がする、になります。


次元削減のアルゴリズムには、pcaやt-sneなどもありますが、今回は新しそうなumapを使ってみます。

ここで、UMAPメソッドの引数n_componentsでは「何次元に次元削減するか」を指定する形になります。

決め打ちにする事も考えましたが、何かしらの理由を以て「何次元に次元削減するか」を決めたかったので、下記の形にしてみました。

hdbscanで最もクラスター数が多くなる次元

具体的には、

  • 引数n_componentsを2で次元削減を行った後にhdbscanのデフォルト設定でクラスタリングを行ってクラスター数を取得
  • 引数n_componentsを3で次元削減を行った後にhdbscanのデフォルト設定でクラスタリングを行ってクラスター数を取得
  • ・・・

そして、最大のクラスター数の次元を、引数n_componentsの値にします。 何かしらの根拠がある訳ではありませんが、最もクラスター数が多いならば、うまくクラスタリング出来る次元、と割り切ってみました(笑)

では、NotebookインスタンスにPythonコードを書いてみます。
まずは、前回の記事から追加のライブラリーをインポートします。

hogehoge.ipynb
import umap
import hdbscan

続いて、umapで次元削減を行う関数を作成します。UMAPメソッドの引数n_componentsに設定する値は、この関数の引数reducted_num_dimensionで取得するようにします。

hogehoge.ipynb
def dimension_reduction(vector, reducted_num_dimension):
    umap_ = umap.UMAP(n_components=reducted_num_dimension,
                      random_state=42,
                      n_jobs=1,  # random_stateを設定してもエラーメッセージが表示されないようにするため
                      n_neighbors=15,
                      min_dist=0.1)
    two_dimension_vector = umap_.fit_transform(vector)
    return two_dimension_vector

次に、hdbscanでクラスタリングを行う関数を作成します。

hogehoge.ipynb
def clustering_function(reducted_dimension_vector, hdbscan_cluster_min_size):
    clustering_data = hdbscan.HDBSCAN(min_cluster_size=hdbscan_cluster_min_size)
    clustering_data.fit(reducted_dimension_vector)
    return clustering_data

それでは、umapを行う関数と、hdbscanを行う関数を使って、「hdbscanで最もクラスター数が多くなる次元」を探す関数を作ってみます。今回は、2~30次元を対象にして、探す形にしてみます。
途中で呼び出している関数clustering_functionは、先程のhdbscanでクラスタリングを行う関数になります。引数hdbscan_cluster_min_sizeは、hdbscanのHDBSCANメソッドの引数min_cluster_sizeへ設定する値になります。一旦は引数min_cluster_sizeのデフォルト値の5を使いました。

hogehoge.ipynb
def search_reducted_dimension(vector_all):
    reducted_vector_num_list = []
    cluster_num_list = []
    for reducted_num_dim in range(2, 30):
        reducted_dimension_vector_all = dimension_reduction(vector=vector_all,
                                                            reducted_num_dimension=reducted_num_dim)
        clustering_data = clustering_function(reducted_dimension_vector=reducted_dimension_vector_all,
                                              hdbscan_cluster_min_size=5)
        reducted_vector_num_list.append(reducted_num_dim)
        cluster_num_list.append(len(np.unique(clustering_data.labels_)))
    cluster_num_per_vector_num_df = pd.DataFrame(data={"reducted_vector_num": reducted_vector_num_list,
                                                       "cluster_num": cluster_num_list})
    cluster_num_index = cluster_num_per_vector_num_df["cluster_num"].idxmax()
    cluster_num_vector_dim = cluster_num_per_vector_num_df.iloc[cluster_num_index, 0]
    print("クラスター数が最大値になるベクトル次元は", cluster_num_vector_dim)
    cluster_num_min = cluster_num_per_vector_num_df.iloc[cluster_num_index, 1]
    print("そのベクトル次元でのクラスター数は", cluster_num_min)
    return cluster_num_vector_dim

では、search_reducted_dimension関数を使って、「hdbscanで最もクラスター数が多くなる次元」を探してみます。引数vector_allには、その1の記事でのアウトプットである変数text_vectorを設定します。

hogehoge.ipynb
reducted_dim_num = search_reducted_dimension(vector_all=text_vector)
クラスター数が最大値になるベクトル次元は 24
そのベクトル次元でのクラスター数は 6

2~30次元では、24次元に次元削減した時、最もhdbscanでクラスター数が多かったようなので、1536次元ベクトルをUMAPで24次元ベクトルへ次元削減する事にします。

hogehoge.ipynb
reducted_vector = dimension_reduction(vector=text_vector,
                                      reducted_num_dimension=reducted_dim_num)
print(reducted_vector.shape)
(100, 24)

そして、hdbscanでクラスタリングを行います。

hogehoge.ipynb
clustering_data = clustering_function(reducted_dimension_vector=reducted_vector,
                                      hdbscan_cluster_min_size=5)
print(np.unique(clustering_data.labels_))
[-1  0  1  2  3  4]

想定通りの動きをしてくれました。


今回は以上になります。
次回は、同じクラスターに属する文章をclaudeに投げて、話題を取得してみます。

次の記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0