実験

では Mnistの手書き数字画像のランダムフォレストアンサンブルを学習します。

Mnistの 0 - 4 の数字画像を読み込みます。

In [1]:
%matplotlib inline
print(__doc__)
from time import time

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import offsetbox
from sklearn import (manifold, datasets, decomposition, ensemble,
                     discriminant_analysis, random_projection)

# Mnistの 0 - 4 の数字画像を読み込む

digits = datasets.load_digits(n_class=5)
X = digits.data
y = digits.target
n_samples, n_features = X.shape
n_neighbors = 50


# 図作成

def plot_embedding(X, title=None):
    x_min, x_max = np.min(X, 0), np.max(X, 0)
    X = (X - x_min) / (x_max - x_min)

    plt.figure()
    fig = plt.figure(figsize=(4,4),dpi=200)
    ax = plt.subplot(111)
    for i in range(X.shape[0]):
        plt.text(X[i, 0], X[i, 1], str(y[i]),
                 color=plt.cm.Set1(y[i] / 10.),
                 fontdict={'weight': 'bold', 'size': 9})

    if hasattr(offsetbox, 'AnnotationBbox'):
        # サムネイル matplotlib > 1.0
        shown_images = np.array([[1., 1.]])  # just something big
        for i in range(X.shape[0]):
            dist = np.sum((X[i] - shown_images) ** 2, 1)
            if np.min(dist) < 4e-3:
                # 近すぎるポイントを表示しない
                continue
            shown_images = np.r_[shown_images, [X[i]]]
            imagebox = offsetbox.AnnotationBbox(
                offsetbox.OffsetImage(digits.images[i], cmap=plt.cm.gray_r),
                X[i])
            ax.add_artist(imagebox)
    plt.xticks([]), plt.yticks([])
    if title is not None:
        plt.title(title)
Automatically created module for IPython interactive environment

Mnistのサンプルデータを表示します。

各画像は8x8の64次元のデータセットです。

In [2]:
fig = plt.figure(figsize=(4,4),dpi=200)
n_img_per_row = 20
img = np.zeros((10 * n_img_per_row, 10 * n_img_per_row))
for i in range(n_img_per_row):
    ix = 10 * i + 1
    for j in range(n_img_per_row):
        iy = 10 * j + 1
        img[ix:ix + 8, iy:iy + 8] = X[i * n_img_per_row + j].reshape((8, 8))

plt.imshow(img, cmap=plt.cm.binary)
plt.xticks([])
plt.yticks([])
plt.title('Mnist digits dataset')
Out[2]:
Text(0.5, 1.0, 'Mnist digits dataset')

ランダムで図を作成します。

In [3]:
# ランダム 2D の random unitary matrix
rp = random_projection.SparseRandomProjection(n_components=2, random_state=42)
X_projected = rp.fit_transform(X)
plot_embedding(X_projected, "Random Projection of the digits")
plt.show()
<Figure size 432x288 with 0 Axes>

sklearn.ensemble.RandomTreesEmbedding


class sklearn.ensemble.RandomTreesEmbedding(n_estimators=’warn’, max_depth=5, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, sparse_output=True, n_jobs=None, random_state=None, verbose=0, warm_start=False)


n_estimators デフォルトの値は10.バギングに用いる決定木の個数を指定

max_depth   決定木の深さの最大値を指定。過学習を避けるためにはこれを調節するのが最も重要

min_samples_split ノードを分割するために必要な最小サンプルサイズ

min_samples_leaf 葉を構成するのに必要な最小限のサンプルの数

min_weight_fraction_leaf   葉における重みの総和の最小加重率を指定

max_leaf_nodes   生成される決定木における最大の葉の数を指定

min_impurity_split   決定木の成長の早期停止の閾値

n_jobs  フィットおよび予測の際に用いるスレッドの数を指定

random_state  乱数のタネの指定

verbose  モデル構築の過程のメッセージを出すかどうか


先ず木の数を600に指定して、決定木の深さの最大値を5に指定してみます。

数字の画像は分けているが、曖昧なところを見えます。

In [4]:
# Random Trees embedding 
# ランダムフォレストで用いる木の数 = 600
# 決定木の深さの最大値を指定 = 5

hasher = ensemble.RandomTreesEmbedding(n_estimators=600, 
                                       random_state=0,
                                       max_depth=5)
t0 = time()
X_transformed = hasher.fit_transform(X)
pca = decomposition.TruncatedSVD(n_components=2)
X_reduced = pca.fit_transform(X_transformed)

plot_embedding(X_reduced,
               "Random forest embedding of the digits (time %.2fs)" %
               (time() - t0))

plt.show()
<Figure size 432x288 with 0 Axes>

次に木の数を800に指定して、決定木の深さの最大値を8に指定してみます。

数字の画像はよく分けていると見えますした。

In [5]:
# Random Trees embedding of the digits dataset
# ランダムフォレストで用いる木の数 = 800
# 決定木の深さの最大値を指定 = 8

hasher = ensemble.RandomTreesEmbedding(n_estimators=800, 
                                       random_state=0,
                                       max_depth=8)
t0 = time()
X_transformed = hasher.fit_transform(X)
pca = decomposition.TruncatedSVD(n_components=2)
X_reduced = pca.fit_transform(X_transformed)

plot_embedding(X_reduced,
               "Random forest embedding of the digits (time %.2fs)" %
               (time() - t0))

plt.show()
<Figure size 432x288 with 0 Axes>

最後は木の数を1000に指定して、決定木の深さの最大値を15に指定してみます。

過学習しまいました。

In [6]:
# Random Trees embedding of the digits dataset
# ランダムフォレストで用いる木の数 = 1000
# 決定木の深さの最大値を指定 = 15

hasher = ensemble.RandomTreesEmbedding(n_estimators=1000, 
                                       random_state=0,
                                       max_depth=15)
t0 = time()
X_transformed = hasher.fit_transform(X)
pca = decomposition.TruncatedSVD(n_components=2)
X_reduced = pca.fit_transform(X_transformed)

plot_embedding(X_reduced,
               "Random forest embedding of the digits (time %.2fs)" %
               (time() - t0))

plt.show()
<Figure size 432x288 with 0 Axes>
In [ ]: