Python 通过scikit learn中的EM估计群集数

Python 通过scikit learn中的EM估计群集数,python,scikit-learn,artificial-intelligence,cluster-analysis,weka,Python,Scikit Learn,Artificial Intelligence,Cluster Analysis,Weka,我尝试使用EM实现聚类估计方法,更准确地说,如下描述: 为确定集群数量而执行的交叉验证是 按以下步骤完成: 群集数设置为1 训练集被随机分成10组 EM使用通常的CV方式进行10次,每次重复10次 对数似然是所有10个结果的平均值 如果对数似然性增加,则簇数增加1,程序继续执行步骤2 我目前的执行情况如下: def estimate_n_clusters(X): "Find the best number of clusters through maximization of the lo

我尝试使用EM实现聚类估计方法,更准确地说,如下描述:

为确定集群数量而执行的交叉验证是 按以下步骤完成:

  • 群集数设置为1
  • 训练集被随机分成10组
  • EM使用通常的CV方式进行10次,每次重复10次
  • 对数似然是所有10个结果的平均值
  • 如果对数似然性增加,则簇数增加1,程序继续执行步骤2
  • 我目前的执行情况如下:

    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
    
    由于
    -gm.score(X)
    产生负结果(约-2500),因此在NaN中产生结果。而Weka报告
    对数可能性:347.16447

    我的猜测是,Weka步骤4中提到的可能性与
    score\u samples()
    中提到的可能性不同

    谁能告诉我哪里出了问题


    谢谢

    根据文档,
    得分
    返回平均对数可能性。显然,您不想使用log log。

    作为将来的参考,fixed函数如下所示:

    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
    
    def估计n_簇(X):
    “通过最大化EM中的对数似然值,找到最佳聚类数。”
    最后一次\u日志\u可能性=无
    kf=KFold(n_splits=10,shuffle=True)
    组件=范围(50)[1:]
    对于组件中的n_组件:
    gm=高斯混合(n_分量=n_分量)
    日志可能性列表=[]
    对于列车,在kf中进行试验。拆分(X):
    gm.fit(X[列车:])
    如果不是gm.converged\UU3:
    提出警告(“GM未聚合”)
    log_似然=-gm.score_样本(X[测试:])
    log_likelion_list+=log_likelion.tolist()
    平均对数似然=np.平均值(对数似然列表)
    打印(平均日志)
    如果last_log_似然为无:
    最后对数似然=平均对数似然
    
    elif avg_log_似然+10E-6令人尴尬,这是真的。让我不高兴的是,在迭代过程中,我得到了数以百万计的
    avg_log_likelion
    ,因此我应用log时认为它至少应该在最后结果的大致范围内,但显然不是。简单地删除日志,我得到的最终可能性与Weka发现的相同。谢谢
    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