Gakushukun1’s diary

20代エンジニア, 統計的機械学習勉強中 twitter: @a96665004

AutoEncoderを用いた政令指定都市の区の分析と, 主成分分析との比較

目的

AutoEncoderにより、東京23区および政令都市の区(n=198)のデータの次元削減を行い, 主成分分析と比較する.

gakushukun1.hatenablog.com
前回の記事で主成分分析を行なった各政令指定都市の区のデータについて, 今回はAutoEncoderにより次元削減を行う.

具体的には, 各区のデータが持つ11次元の情報について, 下のような構成のエンコーダーデコーダーを組み合わせたニューラルネットにより, 2次元の情報に落とし込む.

f:id:gakushukun1:20190711223052p:plain

f:id:gakushukun1:20190711223049p:plain
Kerasにより実装したコードは次の通り. なお, 分析に用いたベクトルは, 主成分分析の時と同様, 地域ごとの人口差による影響を除くために, 各次元を総人口で割っている. また今回は, AutoEncoderの出力層の活性化関数をシグモイド関数としたため, ベクトルの各次元の値が0〜1の間に収まるよう正規化も行なった.

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation, BatchNormalization
from keras.activations import sigmoid
from keras.optimizers import Adam
from keras.utils import plot_model
import matplotlib.pyplot as plt
import matplotlib
import pandas as pd


if __name__ == '__main__':
    matplotlib.rcParams['font.family'] = 'IPAexGothic'

    df = pd.read_csv('ku2015.csv', encoding="SHIFT-JIS")
    df.loc[:, '総人口':] = df.loc[:, '総人口':].astype(float)
    pop = df.loc[:, '総人口'].values
    X = df.iloc[:, 2:].apply(lambda x: x / pop, axis=0)
    X_norm = X.loc[:, :].apply(lambda x: x / x.max(), axis=0)
    print(len(X_norm.columns))

    # エンコーダー
    encoder = Sequential()
    encoder.add(Dense(6, input_shape=(11,)))
    encoder.add(BatchNormalization())
    encoder.add(Activation(sigmoid))
    encoder.add(Dense(2))
    encoder.add(BatchNormalization())
    encoder.add(Activation(sigmoid))

    # デコーダー
    decoder = Sequential()
    decoder.add(Dense(6, input_shape=(2,)))
    decoder.add(BatchNormalization())
    decoder.add(Activation(sigmoid))
    decoder.add(Dense(11))
    decoder.add(BatchNormalization())
    decoder.add(Activation(sigmoid))

    model = Sequential([encoder, decoder])
    model.compile(optimizer=Adam(), loss='mean_squared_error', metrics=['accuracy'])

    fit = model.fit(X_norm, X_norm, epochs=2000)
    y = encoder.predict(X_norm)

上記のコードによりAutoEncoderの学習を行なった後, 元のデータ(コード中のX_norm)をEncoderに入力して得られた出力が, 今回必要な次元削減された情報である.
f:id:gakushukun1:20190711232212p:plain
図の横軸は, Encoderから得られた出力の一次元目を, 縦軸は二次元目を表している. 主成分分析の主成分得点の結果と比較すると, よく似ているが, 千代田区, 中央区, 港区については, 曲がった座標に埋め込まれていることが分かる. この3つの区は, 特別な性質を持つのかもしれない.

上の図の各x=(0〜0.75), y=(0〜0.75)の点について, Decoderに入力して得られた出力を次に示す.
f:id:gakushukun1:20190711233919p:plain
x, y=(0, 0)から復元された情報では, 5:転入, 6:転出, 9:単独世帯,10:婚姻件数,11:離婚件数が少なく, 人の往来の少ない町であると分かる. x, y=(0.75, 0)は, 4:死亡数, 9:単独世帯が多く, 高齢化の進んだ町であると分かる. x, y=(0, 0.75)は, 4:死亡者数が少なく, 8:昼間人口が多いためビジネス街のような場所であると推測される. x,y=(0.75, 0.75)は, 5:転入, 6:転出, 9:単独世帯,10:婚姻件数,11:離婚件数が多いため, 人の往来が激しい町であると分かる.

まとめ

AutoEncoderを用い政令都市の区のデータの分析を行い, 主成分分析と比較した. AutoEncoderでは, 主成分分析とほぼ同じ結果が得られたが, いくつかの町では, 線形変換ではみつからない特徴が取り出されていた.