混合ガウスモデル

Image from Gyazo

ノートブックの作成

Colabにアクセスし,新規にノートブックを作成してください. ノートブックのタイトルは chapter13 とします. また,numpymatplotlib.pyplotscikit-learnSciPyを導入しておいてください.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
from scipy.stats import norm

ガウス分布(正規分布)

ガウス分布(正規分布)は,ドイツの数学者のガウスに由来する確率・統計において最重要な確率分布の一つです. 自然界や社会の様々な現象を表現するモデルとして知られています. Pythonでは,Numpyを利用して,正規分布に従う乱数を生成することが可能です.

例えば,平均0,標準偏差1の正規分布に従う乱数を生成してみます. 生成した乱数のヒストグラム(度数)は下図のようになります. このヒストグラムからも分かるように,正規分布には下記の特徴があります.

x = np.random.normal(0, 1, 10000) # 10000の乱数を生成

plt.hist(x, bins=100) # 階級数を100に設定したヒストグラム
plt.xlim(-5, 5)
plt.xlabel("x")
plt.ylabel("Frequency")

Image from Gyazo

正規分布に従う特徴量の一つに人間の身長があります. 例えば,日本人男性の平均は167.7cm,標準偏差は6.6cm, また,アメリカ人男性の平均は178.4cmで,標準偏差は7.6cmとされています. それでは,この特徴量を利用して日本人男性とアメリカ人男性の正規分布に従う乱数を生成しましょう. そして,これを重ね合わせてしまいます.

x1 = np.random.normal(167.7,  6.6, 10000) 
x2 = np.random.normal(178.4, 7.6, 10000)
x = np.concatenate((x1, x2)) # 結合(重ね合わせ)

plt.hist(x, bins=100)
plt.xlabel("x")
plt.ylabel("Frequency")

結合された乱数のヒストグラムは下記のようになります. このように複数の正規分布に従う乱数を重ね合わせることで, 多彩な分布を表現することが可能になります. この正規分布を重ね合わせた表現を 混合ガウスモデル(Gaussian Mixture Model) と呼びます. 一方で,重ね合わせた分布からは,元の正規分布の特徴量を得ることは難しくなります. これを得るには EMアルゴリズム と呼ばれる手法が用いられます(詳細は割愛).

Image from Gyazo

scikit-learnで混合ガウスモデル

それでは,scikit-learnを利用して 混合ガウスモデル(Gaussian Mixture Model) の特徴量を推定してみましょう. まずは,対象のデータをreshapeで2次元配列に変換します(scikit-learnの制限のため).

[In:]

x = np.array(x).reshape(-1, 1)
print(x)

[Out:]

[[162.08389117]
 [170.77306785]
 [165.28550483]
 ...
 [175.53732234]
 [178.69420996]
 [177.08352499]]

次に,scikit-learnのGaussianMixtureを利用して特徴量を推定します. このとき,重ね合わせた元の正規分布の 分散 を指定します. ここでは,各次元の分散が共通である2つの正規分布が重なっているとします(今回のデータは身長のみの1次元).

gmm = GaussianMixture(
	n_components=2, # 重ね合わせた分布数
	covariance_type="spherical" # 分散は共通(球状)
).fit(x)

推定された 重み平均標準偏差を調べてみましょう. 推定された日本人男性の平均は167.4cm,標準偏差は6.4cm,また, 推定されたアメリカ人男性の平均は179.7cm,標準偏差は6.9cmです. かなり高い精度で推定されていることが分かります. また,重みは2つの分布を混合した割合を意味しており, 推定された重みは0.53:0.46となりました. 今回は0.5:0.5で混合したため,これもほぼ一致していることが分かります.

[In:]

weight = gmm.weights_ #重み(足すと1になる)
mean = gmm.means_ #平均
sd = np.sqrt(gmm.covariances_) #標準偏差
print(weight)
print(mean)
print(sd)

[Out:]

[0.46127772 0.53872228] #重み(足すと1になる)
[[179.65302075] [167.4491238 ]] #平均
[6.92751809 6.35107582] #標準偏差

推定された特徴量を用いて,正規分布を描いてみましょう. 正規分布の確率密度を求めるには norm.pdf を利用します.

x_ = np.arange(140, 210, 0.1)
y1 = weight[0] * norm.pdf(x_, mean[0], sd[0])
y2 = weight[1] * norm.pdf(x_,mean[1], sd[1])

plt.plot(x_, y1)
plt.plot(x_, y2)
plt.xlabel("Height")
plt.ylabel("Probability Density")

Image from Gyazo

この2つの正規分布を重ねると,元の分布の形状とほぼ一致した確率分布を得ることができます.

y3 = y1 + y2

plt.plot(x_, y3)
plt.xlabel("Height")
plt.ylabel("Probability Density")

Image from Gyazo

さて,今回の混合ガウスモデルは,前回の k平均法 と同じように, クラスタリングの手法としても用いることができます. 例えば,165cmの男性がどちらの分布(クラスタ)に属するかを predict で判定すると, 日本人の分布に属しているという結果になりました. 同様に,185cmの男性は,アメリカ人の分布に属しているという結果になりました.

[In:]

sample1 = np.array([[165]]) # 165cm
sample2 = np.array([[185]]) # 185cm

result1 = gmm.predict(sample1)
result2 = gmm.predict(sample2)

print(result1) # 日本人
print(result2) # アメリカ人

[Out:]

[1]
[0]

課題

下記のデータから元の正規分布の特徴量を推定しなさい. ただし,正規分布の数は2,また,分散は共通とすること.

x = np.array([14.25503594,  8.83020581, 10.45406782, 12.53819445,  7.86459267,
        8.03801485, 11.31295349, 10.09167258, 12.87803092, 14.48622644,
       11.99081559,  9.63743057, 10.77132259, 10.50821578, 12.2923627 ,
        6.83922144, 11.59345268,  8.38998967, 11.77040723,  8.50230634,
        7.3762556 , 11.11177995, 13.57393876, 14.39937259,  8.92640252,
       12.62335089, 10.04121407, 11.20886925, 10.53488673,  7.57188571,
       19.20054947, 20.67642748, 17.81617885, 24.66817129, 20.9813163 ,
       21.92106427, 19.31876107, 17.31019546, 16.69085822, 14.48237459,
       20.35137646, 20.19614246, 16.47291945, 18.87417032, 24.24447717,
       26.12173461, 27.47509222, 19.05972395, 18.82537232, 18.87784878,
       20.60160528, 14.17361497, 18.01530688, 21.87758915, 16.012469  ,
       19.69841929, 22.10291163, 15.22297199, 23.14124462, 14.84946092])

Image from Gyazo

課題を完成させたら,chapter13.ipynb を保存し, 共有用のリンクノートブック(.ipynb) をダウンロードして提出してください. このとき,必ず事前に下記の設定を行ってから提出してください.

参考書籍

愛知県名古屋市にある椙山女学園大学 文化情報学部 向研究室の公式サイトです. 専門は情報科学であり,人工知能やデータベースなどの技術要素を指導しています. この公式サイトでは,授業で使用している教材を公開すると共に, ベールに包まれた女子大教員のミステリアスな日常を4コマ漫画でお伝えしていきます. サイトに関するご意見やご質問はFacebookまたはTwitterでお問い合わせください.