1) GMM-классификатор использует Алгоритм ожидания-максимизации для подбора смеси гауссовых моделей: гауссовые компоненты случайным образом центрируются в точках данных, затем алгоритм перемещает их до тех пор, пока не сходится к локальному оптимуму. Из-за случайной инициализации результаты могут отличаться при каждом запуске. Поэтому вам также необходимо использовать random_state
параметр GMM
(или попытаться установить большее число инициализаций n_init
и ожидать более похожих результатов.)
2) Проблема с точностью возникает из-за того, что GMM
(так же, как kmeans
) просто соответствует гауссианам n
и сообщает гауссовский компонент «число», которому принадлежит каждая точка; это число отличается в каждом запуске. Вы можете видеть в своих прогнозах, что кластеры одинаковы, но их метки поменялись местами: (1,2,0) -> (1,0,2) -> (0,1,2), последняя комбинация совпадает с правильные классы, так что вы получите 98% баллов. Если вы построите их, вы увидите, что сами гауссы в этом случае, как правило, остаются такими же, например
Вы можете использовать ряд метрик кластеризации , которые учитывают это:
>>> [round(i,5) for i in (metrics.homogeneity_score(y_predict, y_train),
metrics.completeness_score(y_predict, y_train),
metrics.v_measure_score(y_predict,y_train),
metrics.adjusted_rand_score(y_predict, y_train),
metrics.adjusted_mutual_info_score(y_predict, y_train))]
[0.86443, 0.8575, 0.86095, 0.84893, 0.85506]
Код для построения графика, из https://scikit -learn.org / stable / auto_examples / mixed / plot_gmm_covariances.html , обратите внимание, что код отличается в разных версиях, если вы используете старую версию, которую нужно заменить make_ellipses
функция:
model = mix(n_components=len(np.unique(y_train)), covariance_type="full", verbose=0, n_init=100)
X_train = X_train.astype(float)
model.fit(X_train)
y_predict = model.predict(X_train)
import matplotlib as mpl
import matplotlib.pyplot as plt
def make_ellipses(gmm, ax):
for n, color in enumerate(['navy', 'turquoise', 'darkorange']):
if gmm.covariance_type == 'full':
covariances = gmm.covariances_[n][:2, :2]
elif gmm.covariance_type == 'tied':
covariances = gmm.covariances_[:2, :2]
elif gmm.covariance_type == 'diag':
covariances = np.diag(gmm.covariances_[n][:2])
elif gmm.covariance_type == 'spherical':
covariances = np.eye(gmm.means_.shape[1]) * gmm.covariances_[n]
v, w = np.linalg.eigh(covariances)
u = w[0] / np.linalg.norm(w[0])
angle = np.arctan2(u[1], u[0])
angle = 180 * angle / np.pi # convert to degrees
v = 2. * np.sqrt(2.) * np.sqrt(v)
ell = mpl.patches.Ellipse(gmm.means_[n, :2], v[0], v[1],
180 + angle, color=color)
ell.set_clip_box(ax.bbox)
ell.set_alpha(0.5)
ax.add_artist(ell)
def plot(model, X, y, y_predict):
h = plt.subplot(1, 1, 1)
plt.subplots_adjust(bottom=.01, top=0.95, hspace=.15, wspace=.05,
left=.01, right=.99)
make_ellipses(model, h)
for n, color in enumerate( ['navy', 'turquoise', 'darkorange']):
plt.scatter(X[y == n][:,0], X[y == n][:,1], color=color,marker='x')
plt.text(0.05, 0.9, 'Accuracy: %.1f' % ((np.mean(y_predict == y)) * 100),
transform=h.transAxes)
plt.show()
plot(model, X_train, y_train, y_predict)