我有一些数据(用于说话人识别的MFCC特征),来自两个不同的说话人。每个人有60个13特征的向量(总共120个)。每个人都有自己的标签(0和1)。我需要在混淆矩阵上显示结果。但是sklearn中的GaussianMixture
模型不稳定。每次运行程序时我都会得到不同的分数(有时准确率是0.4,有时是0.7…)。我不知道自己做错了什么,因为我类似的创建了SVM和k-NN模型,它们运行得很好(稳定准确率约为0.9)。你有任何想法我做错了什么吗?
gmmclf = GaussianMixture(n_components=2, covariance_type='diag')gmmclf.fit(X_train, y_train) #X_train是mfcc向量,y_train是标签ygmm_pred_class = gmmclf.predict(X_test)print(accuracy_score(y_test, ygmm_pred_class))print(confusion_matrix(y_test, ygmm_pred_class))
回答:
简短回答:你应该不使用GMM进行分类。
详细回答…
从一个相关线程的回答中,使用scikit-learn进行多类分类的高斯混合模型(原文强调):
高斯混合模型不是分类器。它是一种密度估计方法,期望其组件能神奇地与你的类别对齐并不是一个好主意。[…] GMM只是试图将高斯混合模型拟合到你的数据中,但没有任何东西强迫它根据标签(甚至在fit调用中未提供)来放置它们。有时这会起作用 – 但仅限于简单问题,其中类别分离得如此好,以至于即使是Naive Bayes也能起作用,但一般来说,它对于这个问题来说根本不是有效的工具。
并且回答者本人的评论(再次强调原文):
如回答中所述 – GMM不是分类器,因此询问你是否正确使用”GMM分类器”是无法回答的。将GMM用作分类器在定义上是不正确的,没有“有效”的方法在这种问题中使用它,因为这不是该模型设计的用途。你可以做的是为每个类别构建一个适当的生成模型。换句话说,构建你自己的分类器,你为每个标签拟合一个GMM,然后使用分配的概率进行实际分类。然后它就是一个适当的分类器。见github.com/scikit-learn/scikit-learn/pull/2468
(为了说明,这可能值得注意的是,回答者是DeepMind的研究科学家,并且是Stack Overflow上第一个获得machine-learning
金牌的人)
进一步阐述(这就是为什么我没有简单地将问题标记为重复):
确实,在scikit-learn的文档中有一个标题为GMM分类的帖子:
展示用于分类的高斯混合模型的演示。
我猜在2017年以上回应写的时候,这个帖子还不存在。但深入研究提供的代码,你会意识到GMM模型实际上是以lejlot上面提出的方式使用的;没有形式为classifier.fit(X_train, y_train)
的语句 – 所有使用都是classifier.fit(X_train)
的形式,即不使用实际的标签。
这正是我们从类似聚类的算法(GMM确实是这种算法)中期望的,而不是从分类器中期望的。再一次,确实scikit-learn提供了在GMM fit
方法中也提供标签的选项:
fit
(self, X, y=None)
你实际上在这里使用了它(而且再次,可能在2017年以上回应暗示时还不存在),但是,考虑到我们对GMM及其用法的了解,这个参数在这里的用途并不完全清楚(并且,请允许我说,scikit-learn在从纯粹的编程角度看起来合理,但从建模角度来看意义很小的做法上也有自己的份额)。
最后的话:尽管固定随机种子(如评论中建议的)可能会看起来“有效”,但信任一个根据随机种子给出0.4到0.7之间准确率范围的“分类器”显然不是一个好主意…