我正在尝试使用Weka中找到的EM方法来实现聚类估计方法,更具体地说是以下描述:
为了确定聚类数量而进行的交叉验证按以下步骤进行:
- 将聚类数量设置为1
- 将训练集随机分成10个折叠
- 使用10个折叠以通常的CV方式进行10次EM
- 将所有10个结果的对数似然值取平均
- 如果对数似然值增加,则聚类数量增加1,程序继续执行步骤2
我当前的实现如下:
def estimate_n_clusters(X): "通过最大化EM的对数似然值来找到最佳聚类数量。" last_log_likelihood = None kf = KFold(n_splits=10, shuffle=True) components = range(50)[1:] for n_components in components: gm = GaussianMixture(n_components=n_components) log_likelihood_list = [] for train, test in kf.split(X): gm.fit(X[train, :]) if not gm.converged_: raise Warning("GM未收敛") log_likelihood = np.log(-gm.score_samples(X[test, :])) log_likelihood_list += log_likelihood.tolist() avg_log_likelihood = np.average(log_likelihood_list) if last_log_likelihood is None: last_log_likelihood = avg_log_likelihood elif avg_log_likelihood+10E-6 <= last_log_likelihood: return n_components last_log_likelihood = avg_log_likelihood
我通过Weka和我的函数得到了相似的聚类数量,然而,使用函数估计的聚类数量n_clusters
gm = GaussianMixture(n_components=n_clusters).fit(X)print(np.log(-gm.score(X)))
结果为NaN,因为-gm.score(X)
产生了负结果(约-2500)。而Weka报告对数似然值: 347.16447
。
我的猜测是Weka步骤4中提到的似然值与函数score_samples()
中提到的似然值不同。
有谁能告诉我哪里出了问题吗?
谢谢
回答:
根据文档,score
返回的是平均对数似然值。显然,你不希望使用对数-对数。