在scikit-learn

时间:2018-03-20 14:04:02

标签: python scikit-learn artificial-intelligence cluster-analysis weka

我正在尝试使用Weka中的EM实现聚类估算方法,更准确地说是以下描述:

  

执行交叉验证以确定簇的数量   按以下步骤完成:

     
      
  1. 群集数量设置为1
  2.   
  3. 训练集随机分成10次。
  4.   
  5. EM使用通常的CV方式进行10次。
  6.   
  7. 对数似然是对所有10个结果的平均值。
  8.   
  9. 如果对数似然增加,则群集数量增加1,程序在步骤2继续。
  10.   

我目前的实施如下:

def estimate_n_clusters(X):
   "Find the best number of clusters through maximization of the log-likelihood from 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 not converged")
           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报告Log likelihood: 347.16447

我的猜测是,Weka第4步中提到的可能性与function score_samples()中提到的可能性不同。

谁能告诉我哪里出错?

由于

2 个答案:

答案 0 :(得分:1)

根据文档,score会返回平均日志的可能性。显然,你不想使用log-log。

答案 1 :(得分:0)

为了将来参考,固定功能如下:

def estimate_n_clusters(X):
   "Find the best number of clusters through maximization of the log-likelihood from 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 not converged")
           log_likelihood = -gm.score_samples(X[test, :])

           log_likelihood_list += log_likelihood.tolist()

       avg_log_likelihood = np.average(log_likelihood_list)
       print(avg_log_likelihood)

       if last_log_likelihood is None:
           last_log_likelihood = avg_log_likelihood
       elif avg_log_likelihood+10E-6 <= last_log_likelihood:
           return n_components-1
       last_log_likelihood = avg_log_likelihood