【问题标题】:model selection for GaussianMixture by using GridSearch使用网格搜索的高斯混合模型选择
【发布时间】:2017-02-16 16:00:04
【问题描述】:

我想使用 scikit-learn 的 GaussianMixture 函数,我必须进行模型选择。 我想通过使用 GridSearchCV 来做到这一点,并且我想使用 BIC 和 AIC 进行选择。 这两个值都在 GaussianMixture() 中实现,但我不知道如何将它们插入到我的自定义记分器的定义中,因为函数

make_scorer(score_func, greater_is_better=True, needs_proba=False, needs_threshold=False, **kwargs)

我用来创建我的自定义记分器将函数 score_funct 作为输入,该函数必须定义为

score_func(y, y_pred, **kwargs)

有人可以帮我吗?

【问题讨论】:

  • 请问您为什么使用 BIC 或 AIC?我建议改用交叉验证。另外,我假设您正在使用 GridSearchCV 来决定要使用的高斯数?
  • 是的,我也在使用 GridSearchCV 作为高斯数。我正处于分析的真正开始,我正在尝试很多事情,我发现 BIC 和 AIC 是两种可能的方法。我正在使用 GaussianMixture 进行异常检测,我不知道这是否有帮助。
  • 我将发布一个答案,详细说明如何使用 GridSearchCV,以及如何使用 BIC 或 AIC。
  • 非常感谢,期待。
  • 认为我会比较彻底。希望这会有所帮助!

标签: python scikit-learn grid-search


【解决方案1】:

使用 BIC/AIC 是使用交叉验证的替代方法GridSearchCV 使用交叉验证选择模型。要使用 BIC/AIC 执行模型选择,我们必须做一些不同的事情。让我们举一个例子,我们从两个高斯生成样本,然后尝试使用 scikit-learn 拟合它们。

import numpy as np
X1 = np.random.multivariate_normal([0.,0.],[[1.,0.],[0.,1.]],10000)
X2 = np.random.multivariate_normal([10.,10.],[[1.,0.],[0.,1.]],10000)
X = np.vstack((X1,X2))
np.random.shuffle(X)

方法一:交叉验证

Cross validation 涉及将数据拆分为多个片段。然后将模型拟合到某些部分(“训练”)并测试它在其余部分上的执行情况(“验证”)。这可以防止过度拟合。在这里,我们将使用双重交叉验证,将数据分成两半。

from sklearn.mixture import GaussianMixture
from sklearn.model_selection import GridSearchCV
import matplotlib.pyplot as plt

#check 1->4 components
tuned_parameters = {'n_components': np.array([1,2,3,4])}
#construct grid search object that uses 2 fold cross validation
clf = GridSearchCV(GaussianMixture(),tuned_parameters,cv=2)
#fit the data
clf.fit(X)
#plot the number of Gaussians against their rank
plt.scatter(clf.cv_results_['param_n_components'],\
            clf.cv_results_['rank_test_score'])

正如我们所料,我们可以看到 2 折交叉验证有利于两个高斯分量。

方法二:BIC/AIC

我们可以使用给定每个高斯数的最佳拟合模型来评估BIC,而不是使用交叉验证。然后我们选择具有最低 BIC 的模型。如果使用 AIC,过程将是相同的(尽管它是不同的统计数据,并且可以提供不同的答案:但您的代码结构将与下面相同)。

bic = np.zeros(4)
n = np.arange(1,5)
models = []
#loop through each number of Gaussians and compute the BIC, and save the model
for i,j in enumerate(n):
    #create mixture model with j components
    gmm = GaussianMixture(n_components=j)
    #fit it to the data
    gmm.fit(X)
    #compute the BIC for this model
    bic[i] = gmm.bic(X)
    #add the best-fit model with j components to the list of models
    models.append(gmm)

执行此过程后,我们可以根据 BIC 绘制高斯数。

plt.plot(n,bic)

所以我们可以看到,对于两个高斯,BIC 被最小化了,所以最好的模型 根据这种方法也有两个组成部分。

因为我从两个分离得很好的高斯分布中抽取了 10000 个样本(即它们的中心之间的距离远大于它们的任何一个色散),所以答案非常明确。情况并非总是如此,而且这些方法通常都不会自信地告诉您要使用的高斯数,而是一些合理的范围。

【讨论】:

  • 非常感谢您的出色解释。关键是是否可以使用 GridSearchCV 通过使用 BIC(或 AIC)而不是使用 for 循环来选择模型。
  • 是的,但是GridSearchCV 是专门为交叉验证而设计的。交叉验证是 BIC/AIC 的替代方法,因此将 BIC/AIC 与 GridSearchCV 一起使用并没有什么意义。一个应该使用一个或另一个。
  • this page 的第 3.2.4.2 节解释说,在某些情况下您可以使用信息标准而不是交叉验证,但它似乎只针对 linear_model.LassoLarsIC 明确实现,因此必须使用for 循环 GaussianMixture 就像我在上面所做的那样。我已经编辑了我的答案,以使这一切都更加清晰。这有帮助吗?
  • 我的想法是使用我在帖子中提到的函数make_scorer 使用 BIC 定义自定义记分器。关键是这个函数显然接受了一个函数 score_funct (应该是我的 BIC)的输入,但 score_funct 应该定义为score_func(y, y_pred, **kwargs);我想利用(就像你在循环中所做的那样)在 GaussianMixture() 中定义的属性 .bic,但我不知道怎么做。 (我不知道我是否把我的问题说得更清楚了)
  • 我想我明白你在问什么,只是GridSearchCV 不合适,因为你在使用它时必须使用某种交叉验证。当您选择具有 BIC/AIC 的模型时,您将使用所有数据,而不是子样本。所以你不能使用GridSearchCV,它要求你对数据进行细分和交叉验证。因此,for 循环是 BIC/AIC 的最佳方法。这有意义吗?
猜你喜欢
  • 2021-09-30
  • 2016-12-28
  • 2023-03-24
  • 2014-01-09
  • 2012-05-08
  • 2018-07-19
  • 1970-01-01
  • 2013-06-11
  • 2016-08-06
相关资源
最近更新 更多