RandomTreesEmbeddingはsklearnにたくさんある謎クラスの一つ*1。
たぶんスパースコーディングに決定木を使いましょうね~系の奴なんだと思う。
ドキュメントを読むと、なんとなく雰囲気はわかる。
sklearn.ensemble.RandomTreesEmbedding — scikit-learn 0.20.1 documentation
あー、なるほど、決定木を作った後、木のパスを符号にしてるのね(わかってない。でもハフマン符号みたいなものかな、という見当はつく)。
とりあえずどんなものか試してみる。というかこの記事は本当に試してみただけ。
なにはともあれirisから
いつも通り分類問題の前処理をやらせてみよう。
プログラム。
# coding: UTF-8 from sklearn.datasets import load_iris, load_digits from sklearn.ensemble import RandomTreesEmbedding as RTE,\ RandomForestClassifier as RFC from sklearn.naive_bayes import GaussianNB from sklearn.model_selection import cross_validate def test_func(dataset, clf, embed=True): if embed: rte = RTE(n_estimators=100, sparse_output=False, n_jobs=-1) X = rte.fit_transform(dataset.data) else: X = dataset.data print(X.shape) scoring = {"p": "precision_macro", "r": "recall_macro", "f":"f1_macro"} scores = cross_validate(clf, X, dataset.target, scoring=scoring, return_train_score=False, n_jobs=-1) print("p:{0:.5f} r:{1:.5f} f:{2:.5f}".format( scores["test_p"].mean(), scores["test_r"].mean(), scores["test_f"].mean())) def main(): iris = load_iris() digits = load_digits() gnb = GaussianNB() rfc = RFC(n_estimators=1000, n_jobs=-1) print("iris") test_func(iris, gnb, embed=False) test_func(iris, rfc, embed=False) test_func(iris, gnb, embed=True) test_func(iris, rfc, embed=True) print("digits") test_func(digits, gnb, embed=False) test_func(digits, rfc, embed=False) test_func(digits, gnb, embed=True) test_func(digits, rfc, embed=True) if __name__ == "__main__": main()
結果
iris (150, 4) p:0.93611 r:0.93423 f:0.93411 (150, 4) p:0.96768 r:0.96732 f:0.96731 (150, 2155) p:0.96234 r:0.96038 f:0.96027 (150, 2189) p:0.96234 r:0.96038 f:0.96027 digits (1797, 64) p:0.84221 r:0.81910 f:0.82039 (1797, 64) p:0.94671 r:0.94478 f:0.94473 (1797, 2503) p:0.90086 r:0.89582 f:0.89597 (1797, 2488) p:0.93643 r:0.93373 f:0.93403
まあ思った通り、4次元から2000次元以上に張られてしまう奴だった。ナイーブベイズだと分類精度に恩恵があるっぽいが、ランダムフォレストで効く訳もなく。
ちなみに、木の数を増やすと次元数はだいたい比例して増える。おっかない。まあ、逆に言えば木の数で適当な次元数に調整できるということでもあるのだが(他の決定木のパラメタでもできる)。
まとめ
本来の使い方じゃないと思うので、そのうちちゃんとした記事を書きます・・・。
たぶん画像処理とかの問題を解くのに使えるんだと思う。
*1:ひどい言い方だけど、「僕にとって謎」という意味である。予防線張っとく