0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ランダムフォレストを用いたクラスタリングの性能比較(二次元)

前回の記事「ランダムフォレストはクラスタリングに用いられる」ではランダムフォレストを階層型(凝集)クラスタリングに応用する方法を述べたが, 今回はこれが他の一般的なクラスタリングアルゴリズムに比べてどのような性質を示すかを見ていく.

Scikit-learnの公式ドキュメントと比較する

Scikit-learnの公式ドキュメントでは, いくつかのクラスタリング手法について比較が行われている.

今回はこれに倣い, クラスタリング手法の一つに今回の「ランダムフォレストクラスタリング(仮)」を追加していく.

準備

RandomForestClusteringクラス

Scikit-learnのコード内で他のクラスタリング手法と同様に扱えるよう, クラスとして定義しておく.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.cluster import AgglomerativeClustering

class RandomForestCustering:

    def __init__(self, n_clusters, classifier_min_samples_split=0.05):
        #self.rng = np.random.default_rng()
        self.rfc = RandomForestClassifier(min_samples_split=classifier_min_samples_split)
        self.m = n_clusters
        self.label_ = []
    
    def fit(self, X):
        ii = np.random.choice(X.shape[0], size=[X.shape[0], X.shape[1]])
        X_gen = X[ii, np.arange(X.shape[1])]
        
        # RandomForest で2値分類
        # オリジナルデータならラベル 1
        X_bin = np.vstack([X, X_gen])
        y = np.hstack([np.ones(X.shape[0]), np.zeros(X.shape[0])])
        self.rfc.fit(X_bin, y)
    
        # オリジナルデータの類似度行列作成
        # T: X_org の各行データが RandomForest の各木でどの葉に落ちるか表す行列, shape=[n, n_estimator]
        # P: 類似度行列, shape=[n, n]
        T = self.rfc.apply(X)
        P = np.mean(T[:, np.newaxis]==T, axis=-1)
        
        # 類似度行列から距離行列を作ってクラスタリング
        # distance matrix に基づくクラスタリングに対応した関数が必要
        # AgglomerativeClustering だと affinity='precomputed' が必要で linkage は 'ward' 以外なら何でも使えるらしい
        k = self.m # クラスタ数
        D = np.sqrt(1-P)
        clst = AgglomerativeClustering(k, metric='precomputed', linkage='average')
        self.labels_ = clst.fit(D).labels_
        return self.labels_

Scikit-learnの比較スクリプトへの組み込み

    rfc = RandomForestCustering(n_clusters=params["n_clusters"])

    clustering_algorithms = (
        ("MiniBatch\nKMeans", two_means),
        ("Affinity\nPropagation", affinity_propagation),
        ("MeanShift", ms),
        ("Spectral\nClustering", spectral),
        ("Ward", ward),
        ("Agglomerative\nClustering", average_linkage),
        ("DBSCAN", dbscan),
        ("HDBSCAN", hdbscan),
        ("OPTICS", optics),
        ("BIRCH", birch),
        ("Gaussian\nMixture", gmm),
        ("RandomForest\nClustering", rfc),
    )

結果

図の一番右にRandomForestClusteringの列が追加されている.
image.png

本結果においては, 他の手法に対して優位性があるわけではなさそうである.
また、距離の算出にランダムフォレストの二値分類モデルを利用しているため, そのハイパーパラメータや乱数によって結果が大きく変わる傾向があった.

ただし, 本手法の特徴は

・計算速度がレコード数依存で, 説明変数の次元数によらない
・ユークリッド距離とは異なる指標でクラスタリングがなされる

という部分である.

今回の比較実験においては「二次元かつ視覚評価に頼った比較では本手法の優位性の確認はできない」ということが確認された, といえるかもしれない.

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?