In [1]:
from sklearn import mixture

In [2]:
np.random.seed(1)

In [3]:
g = mixture.GMM(n_components=2)

In [4]:
# 平均が0と平均が10の正規分布に従う乱数を生成する
obs = np.concatenate((np.random.randn(100, 1),
                      10 + np.random.randn(300, 1)))

In [5]:
# データにフィットするGMMを学習
g.fit(obs)


Out[5]:
GMM(covariance_type='diag', init_params='wmc', min_covar=0.001,
  n_components=2, n_init=1, n_iter=100, params='wmc', random_state=None,
  thresh=0.01)

In [6]:
g.weights_


Out[6]:
array([ 0.75,  0.25])

In [7]:
g.means_


Out[7]:
array([[ 10.04741807],
       [  0.06058285]])

In [8]:
g.covars_


Out[8]:
array([[ 1.01053171],
       [ 0.78450152]])

In [10]:
# テストデータを作成
# 1次元データでもサンプルが行にくる縦ベクトルにする必要がある
test = np.array([0, 2, 9, 10])[:, np.newaxis]
test


Out[10]:
array([[ 0],
       [ 2],
       [ 9],
       [10]])

In [11]:
g.predict(test)


Out[11]:
array([1, 1, 0, 0])

In [12]:
g.score(test)


Out[12]:
array([-2.18621876, -4.58115903, -1.75468435, -1.21297144])

Densitiy Estimation for a mixture of Gaussians

http://scikit-learn.org/stable/auto_examples/mixture/plot_gmm_pdf.html


In [39]:
from sklearn import mixture
from matplotlib.colors import LogNorm

In [14]:
n_samples = 300

In [15]:
np.random.seed(0)

In [17]:
# データ生成
shifted_gaussian = np.random.randn(n_samples, 2) + np.array([20, 20])

C = np.array([[0, -0.7], [3.5, 0.7]])
stretched_gaussian = np.dot(np.random.randn(n_samples, 2), C)

In [19]:
# 訓練データ
X_train = np.vstack([shifted_gaussian, stretched_gaussian])
X_train


Out[19]:
array([[ 18.44957065,  20.41731882],
       [ 19.05563151,  20.23810315],
       [ 18.59403708,  19.40994235],
       ..., 
       [ -1.94594761,   0.35104203],
       [  0.64207589,   0.10969831],
       [  0.95478736,   0.52047722]])

In [26]:
clf = mixture.GMM(n_components=2, covariance_type='full')
clf.fit(X_train)


Out[26]:
GMM(covariance_type='full', init_params='wmc', min_covar=0.001,
  n_components=2, n_init=1, n_iter=100, params='wmc', random_state=None,
  thresh=0.01)

In [47]:
x = np.linspace(-20.0, 30.0)
y = np.linspace(-20.0, 40.0)
X, Y = np.meshgrid(x, y)
XX = np.array([X.ravel(), Y.ravel()]).T
Z = -clf.score_samples(XX)[0]
Z = Z.reshape(X.shape)

In [52]:
CS = plt.contour(X, Y, Z, levels=np.logspace(0, 3, 10))
plt.scatter(X_train[:, 0], X_train[:, 1], 0.8)


Out[52]:
<matplotlib.collections.PathCollection at 0x73fd290>

In [100]:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

In [56]:
def scale(X):
    """データ行列Xを属性ごとに標準化したデータを返す"""
    # 属性の数(=列の数)
    col = X.shape[1]
    
    # 属性ごとに平均値と標準偏差を計算
    mu = np.mean(X, axis=0)
    sigma = np.std(X, axis=0)
    
    # 属性ごとデータを標準化
    for i in range(col):
        X[:,i] = (X[:,i] - mu[i]) / sigma[i]
    
    return X

In [80]:
data = np.genfromtxt("faithful.txt")
X_train = scale(data)
N = len(X_train)

In [81]:
N


Out[81]:
272

In [139]:
# データは2つのガウス分布の混合だと仮定する
# 共分散行列の形状はfullなので特に仮定を置かない
n_components = 2
gmm = mixture.GMM(n_components, covariance_type='full')

In [127]:
gmm.fit(X_train)


Out[127]:
GMM(covariance_type='full', init_params='wmc', min_covar=0.001,
  n_components=2, n_init=1, n_iter=100, params='wmc', random_state=None,
  thresh=0.01)

In [128]:
# 推定した混合係数
gmm.weights_


Out[128]:
array([ 0.35597816,  0.64402184])

In [129]:
# 推定した各ガウス分布の平均ベクトル
gmm.means_


Out[129]:
array([[-1.27373939, -1.20972547],
       [ 0.70404975,  0.66866654]])

In [130]:
# 推定した各ガウス分布の共分散行列
gmm.covars_


Out[130]:
array([[[ 0.05445178,  0.02829092],
        [ 0.02829092,  0.18407749]],

       [[ 0.13173538,  0.06060868],
        [ 0.06060868,  0.19652982]]])

In [137]:
# 訓練データを描画
plt.plot(X_train[:, 0], X_train[:, 1], 'gx')

# 推定したガウス分布を描画
x = np.linspace(-2.5, 2.5, 1000)
y = np.linspace(-2.5, 2.5, 1000)
X, Y = np.meshgrid(x, y)

# 各ガウス分布について
for k in range(n_components):
    # 平均を描画
    plt.plot(gmm.means_[k][0], gmm.means_[k][1], 'ro')
    # ガウス分布の等高線を描画
    Z = mlab.bivariate_normal(X, Y,
                              np.sqrt(gmm.covars_[k][0][0]), np.sqrt(gmm.covars_[k][1][1]),
                              gmm.means_[k][0], gmm.means_[k][1],
                              gmm.covars_[k][0][1])
    plt.contour(X, Y, Z)

# メッシュ上の各点での対数尤度の等高線を描画
XX = np.array([X.ravel(), Y.ravel()]).T
Z = gmm.score_samples(XX)[0]
Z = Z.reshape(X.shape)
CS = plt.contour(X, Y, Z)
CB = plt.colorbar(CS)

xlim(-2.5, 2.5)
ylim(-2.5, 2.5)


Out[137]:
(-2.5, 2.5)