使用高斯混合模型和 scikit learn 进行多类分类

Posted

技术标签:

【中文标题】使用高斯混合模型和 scikit learn 进行多类分类【英文标题】:Multiclass classification using Gaussian Mixture Models with scikit learn 【发布时间】:2017-12-04 19:09:51 【问题描述】:

我正在尝试使用 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 等,但结果还是一样。

【问题讨论】:

这段代码甚至不应该运行,因为“i”是未定义的。您是否错误地截断了这一行? @lejlot 谢谢。我编辑了代码。 【参考方案1】:

高斯混合不是分类器。这是一种密度估计方法,期望它的组件会神奇地与您的类对齐并不是一个好主意。您应该尝试实际的监督技术,因为您显然可以访问标签。 Scikit-learn 提供了很多这些,包括随机森林、KNN、SVM,......选择你最喜欢的。 GMM 只是尝试将高斯混合拟合到您的数据中,但没有什么迫使它根据标签放置它们(甚至在 fit 调用中都没有提供)。有时这会起作用 - 但仅适用于琐碎的问题,其中类分离得非常好,即使是朴素贝叶斯也能起作用,但一般来说,它只是解决问题的无效工具。

【讨论】:

感谢您的回答。我已经使用过其他分类器,我想将结果与 GMM 分类器进行比较。请告诉我是否要使用 GMM 分类器,我错过了什么吗? 如答案中所述 - GMM 不是分类器,因此无法回答您是否正确使用“GMM 分类器”。根据定义,使用 GMM 作为分类器是不正确的,在这样的问题中没有“有效”的使用方式,因为这不是该模型的设计目的。你可以做的是为每个班级建立一个适当的生成模型。换句话说,构建自己的分类器,每个标签适合一个 GMM,然后使用分配的概率进行实际分类。那么它是一个适当的分类器。见github.com/scikit-learn/scikit-learn/pull/2468【参考方案2】:

GMM 不是分类器,而是生成模型。您可以通过应用贝叶斯定理将其用于分类问题。基于 GMM 的分类仅适用于微不足道的问题是不正确的。然而,它基于高斯分量的混合,因此适合具有高级特征的最佳问题。

您的代码错误地使用 GMM 作为分类器。您应该使用 GMM 作为后验分布,每个类一个 GMM。

【讨论】:

以上是关于使用高斯混合模型和 scikit learn 进行多类分类的主要内容,如果未能解决你的问题,请参考以下文章

使用 scikit-learn.mixture.GMM 寻找条件高斯混合模型

如何在 Scikit-learn 中使用“狄利克雷过程高斯混合模型”? (n_components?)

如何使用高斯混合模型进行聚类?

使用分数度量评估高斯混合模型?

了解高斯混合模型

scikit-learn GMM 产生正对数概率