
【Python】混合ガウス分布【scikit-learn】
目次
1. 理論
2. 学習
2.1. 基本
モデルを宣言し、fitでデータを当てはめます。
当てはめた後のオブジェクト(gmm)が学習後のモデルです。
means_メソッドやbicメソッド、predictを利用して下流の解析に用います。
Text
# librariesfrom sklearn import mixturefrom sklearn.mixture import GaussianMixture
# dataxy = np.array(res_decomposition.iloc[:, :2])
# fitgmm = mixture.GaussianMixture( n_components = 50, covariance_type = 'full', # ['spherical', 'tied', 'diag', 'full'] n_init = 10, reg_covar = 0.1, random_state=42)gmm.fit(xy)2.2. BICによるモデル選択
ハイパーパラメータをBICに基づいて選択し、ベストなモデルを返す関数とその実行例は以下です。
Text
def calc_gmm_BICs( res_decomposition, n_component, cv_types = ['spherical', 'tied', 'diag', 'full'], reg_covar = 0.1): # to nparray xy = np.array(res_decomposition.iloc[:, :2])
# BIC BICs = [] best_gmm = None lowest_bic = np.infty lowest_bic_cv_type = "" lowest_bic_n_component = 0 n_components_range = range(1, n_component + 1) n_init = 10 for cv_type in cv_types: for n_components in n_components_range: gmm = mixture.GaussianMixture( n_components = n_components, covariance_type = cv_type, n_init = n_init, reg_covar = reg_covar, random_state=42 ) gmm.fit(xy) BICs.append(gmm.bic(xy)) if BICs[-1] < lowest_bic: lowest_bic = BICs[-1] best_gmm = gmm lowest_bic_cv_type = cv_type lowest_bic_n_component = n_components
return { 'best_gmm': best_gmm, 'BICs': BICs, 'lowest_bic': lowest_bic, 'lowest_bic_cv_type': lowest_bic_cv_type, 'lowest_bic_n_component': lowest_bic_n_component, 'n_component': n_component, 'cv_types': cv_types, 'reg_covar': reg_covar }
# PCAとUMAPの各々についてBICを計算bic_results_pca = calc_gmm_BICs(res_pca, 50)bic_results_umap = calc_gmm_BICs(res_umap, 50)
# 結果の保存no = now()os.makedirs(f'{TEMP_DIR}/best_gmm/{no}')pickle_save(f'{TEMP_DIR}/best_gmm/{no}/bic_dict_pca.pkl', bic_results_pca)pickle_save(f'{TEMP_DIR}/best_gmm/{no}/bic_dict_umap.pkl', bic_results_umap)上記の結果を棒グラフで可視化する関数は以下です。
Text
# libraryimport itertools
# Plot the BIC scoresdef plot_gmm_BICs(bic_results, cv_colors = ['blue', 'green', 'red', 'orange']): # unpacking BICs = np.array(bic_results['BICs']) n_components_range = range(1, bic_results['n_component'] + 1) cv_types = bic_results['cv_types']
# figure plt.figure(figsize=(14, 6),dpi=100) ax = plt.subplot(111)
# bar plot bars = [] cv_colors_iter = itertools.cycle(cv_colors) for i, (cv_type, color) in enumerate(zip(cv_types, cv_colors_iter)): xposes = np.array(n_components_range) + .2 * (i - 2) bars.append(plt.bar(xposes, BICs[i * len(n_components_range):(i + 1) * len(n_components_range)], width=.2, color=color))
# text (place * near the best model) xpos = BICs.argmin() % len(n_components_range) + .65 + .2 * BICs.argmin() // len(n_components_range) plt.text(xpos, BICs.min() * 0.97 + .03 * BICs.max(), '*', fontsize=14)
# layouts plt.title(f'BIC score per model') plt.xticks(n_components_range) ax.set_xlabel('Number of components') plt.ylim([BICs.min() * 1.01 - .01 * BICs.max(), BICs.max()]) ax.legend([b[0] for b in bars], cv_types)
# shoe plt.show()上記関数の実施例は以下です。
Text
plot_gmm_BICs(bic_results_pca)
3. 平均・分散・AIC・BIC
Text
# 平均 (各componentの平均)mean_x = best_gmm.means_[:, 0]mean_y = best_gmm.means_[:, 1]
# BICgmm.bic(xy)4. 予測
どのcomponentに属するか予測(クラスタリング)
Text
clusters = [i + 1 for i in best_gmm.predict(xy)]5. 等高線による可視化
関数と実行例は以下です。
Text
def plot_decomposition_with_best_gmm(data, bic_results): # to nparray xy = np.array(data.iloc[:, :2])
# unpacking best_gmm = bic_results['best_gmm'] lowest_bic_n_component = bic_results['lowest_bic_n_component'] lowest_bic_cv_type = bic_results['lowest_bic_cv_type']
# plot decomsition plt.figure(figsize=(14, 10)) plt.scatter(xy[:, 0], xy[:, 1], s=5, label='Data', color='blue', alpha=0.5)
# plot cluster centers plt.scatter(best_gmm.means_[:, 0], best_gmm.means_[:, 1], marker='o', s=100, label='Means', color='red', edgecolors='black')
# plot contours x_min, x_max = min(xy[:,0]), max(xy[:,0]) y_min, y_max = min(xy[:,1]), max(xy[:,1]) x_delta, y_delta = x_max - x_min, y_max - y_min x = np.linspace(x_min - 0.05 * x_delta, x_max + 0.05 * x_delta, 100) y = np.linspace(y_min - 0.05 * y_delta, y_max + 0.05 * y_delta, 100) X_grid, Y_grid = np.meshgrid(x, y) Z = -best_gmm.score_samples(np.array([X_grid.ravel(), Y_grid.ravel()]).T) Z = Z.reshape(X_grid.shape) plt.contour(X_grid, Y_grid, Z, levels=10, linewidths=1, colors='green', linestyles='dashed', alpha=0.5)
# layout plt.xlabel('Axis 1') plt.ylabel('Axis 2') plt.title(f'Gaussian Mixture Model with {lowest_bic_n_component} components and {lowest_bic_cv_type}') plt.legend() plt.grid(True) plt.show()
plot_decomposition_with_best_gmm(res_pca, bic_results_pca)

