使用 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 个样本(即它们的中心之间的距离远大于它们的任何一个色散),所以答案非常明确。情况并非总是如此,而且这些方法通常都不会自信地告诉您要使用的高斯数,而是一些合理的范围。