Мультиклассовая классификация с использованием моделей гауссовской смеси с помощью scikit learn

Я пытаюсь использовать sklearn.mixture.GaussianMixture для классификации пикселей в гиперспектральном изображении. Всего 15 классов (1-15). Я пробовал использовать метод http://scikit-learn.org/stable/auto_examples/mixture/plot_gmm_covariances.html. Здесь среднее значение инициализируется с помощью means_init, я тоже пробовал это, но моя точность низкая (около 10%). Я также пытался изменить тип ковариации, порог, максимальное количество итераций и количество инициализаций, но результаты остались такими же.
Правильно ли я делаю? Пожалуйста, предоставьте материалы.

import numpy as np
from sklearn.mixture import GaussianMixture
import scipy.io as sio
from sklearn.model_selection import train_test_split
uh_data =sio.loadmat('/Net/hico/data/users/nikhil/contest_uh_casi.mat')
data = uh_data['contest_uh_casi']

uh_labels = sio.loadmat('/Net/hico/data/users/nikhil/contest_gt_tr.mat')
labels = uh_labels['contest_gt_tr']

reshaped_data = np.reshape(data,(data.shape[0]*data.shape[1],data.shape[2]))
print 'reshaped data :',reshaped_data.shape

reshaped_label = np.reshape(labels,(labels.shape[0]*labels.shape[1],-1))
print 'reshaped label :',reshaped_label.shape

con_data = np.hstack((reshaped_data,reshaped_label))
pre_data = con_data[con_data[:,144] > 0]
total_data = pre_data[:,0:144]
total_label = pre_data[:,144]

train_data, test_data, train_label, test_label =  train_test_split(total_data, total_label, test_size=0.30, random_state=42)

classifier = GaussianMixture(n_components = 15 ,covariance_type='diag',max_iter=100,random_state = 42,tol=0.1,n_init = 1)

classifier.means_init = np.array([train_data[train_label == i].mean(axis=0) 
                                for i in range(1,16)]) 
classifier.fit(train_data)

pred_lab_train = classifier.predict(train_data)
train_accuracy = np.mean(pred_lab_train.ravel() == train_label.ravel())*100
print 'train accuracy:',train_accuracy

pred_lab_test = classifier.predict(test_data)
test_accuracy = np.mean(pred_lab_test.ravel()==test_label.ravel())*100
print 'test accuracy:',test_accuracy  

Мои данные содержат 66485 пикселей и 144 функции в каждой. Я также попытался сделать это после применения некоторых техник сокращения функций, таких как PCA, LDA, KPCA и т. Д., Но результаты все те же.


person Nikhil Makkar    schedule 30.06.2017    source источник
comment
этот код даже не должен запускаться, поскольку i не определен. Вы по ошибке обрезали эту строку?   -  person lejlot    schedule 01.07.2017
comment
@lejlot Спасибо. Я редактировал код.   -  person Nikhil Makkar    schedule 01.07.2017


Ответы (2)


Смесь Гаусса не классификатор. Это метод оценки плотности, и ожидать, что его компоненты волшебным образом выровняются с вашими классами, - не лучшая идея. Вам следует опробовать действительные контролируемые методы, поскольку у вас явно есть доступ к ярлыкам. Scikit-learn предлагает множество из них, включая Random Forest, KNN, SVM, ... выберите свой любимый. GMM просто пытается вписать смесь гауссиан в ваши данные, но ничто не заставляет его размещать их в соответствии с маркировкой (которая даже не предусмотрена в вызове fit). Время от времени это будет работать - но только для тривиальных проблем, где классы настолько хорошо разделены, что даже наивный байесовский метод будет работать, однако в целом это просто недопустимый инструмент для решения проблемы.

person lejlot    schedule 30.06.2017
comment
Спасибо за ответ. Я уже использовал другие классификаторы и хочу сравнить результаты с классификатором GMM. Скажите, хочу ли я использовать классификатор GMM, я чего-нибудь упускаю? - person Nikhil Makkar; 02.07.2017
comment
Как указано в ответе, GMM не является классификатором, поэтому на вопрос, правильно ли вы используете классификатор GMM, невозможно ответить. Использование GMM в качестве классификатора неверно по определению, не существует допустимого способа его использования в такой задаче, так как это не то, для чего предназначена эта модель. Что вы могли бы сделать, так это построить правильную генеративную модель для каждого класса. Другими словами, создайте свой собственный классификатор, в котором вы поместите один GMM на метку, а затем используйте присвоенную вероятность для фактической классификации. Тогда это правильный классификатор. См. github.com/scikit-learn/scikit-learn/pull/2468 - person lejlot; 02.07.2017

GMM - это не классификатор, а генеративная модель. Вы можете использовать его для задачи классификации, применив теорему Байеса. Неверно, что классификация на основе GMM работает только для тривиальных задач. Однако он основан на смеси компонентов Gauss, поэтому лучше всего подходит для задач с функциями высокого уровня.

Ваш код неправильно использует GMM в качестве классификатора. Вы должны использовать GMM как апостериорное распределение, по одному GMM на каждый класс.

person podludek    schedule 29.01.2019