python 中 GSDMM 的实际示例?

A practical example of GSDMM in python?

我想使用 GSDMM 为我的数据集中的一些推文分配主题。我找到的唯一例子(1 and 2)不够详细。我想知道您是否知道显示如何使用 python.

实现 GSDMM 的来源(或足够小心地制作一个小示例)

GSDMM (Gibbs Sampling Dirichlet Multinomial Mixture) is a short text clustering model. It is essentially a modified LDA (Latent Drichlet Allocation) which suppose that a document such as a tweet or any other text encompasses one topic.

GSDMM

LDA

地址:github.com/da03/GSDMM

import numpy as np
from scipy.sparse import lil_matrix
from scipy.sparse import find
import math

class GSDMM:
    def __init__(self, n_topics, n_iter, random_state=910820, alpha=0.1, beta=0.1):
        self.n_topics = n_topics
        self.n_iter = n_iter
        self.random_state = random_state
        np.random.seed(random_state)
        self.alpha = alpha
        self.beta = beta
    def fit(self, X):
        alpha = self.alpha
        beta = self.beta

        D, V = X.shape
        K = self.n_topics

        N_d = X.sum(axis=1)
        words_d = {}
        for d in range(D):
            words_d[d] = find(X[d,:])[1]

        # initialization
        N_k = np.zeros(K)
        M_k = np.zeros(K)
        N_k_w = lil_matrix((K, V), dtype=np.int32)

        K_d = np.zeros(D)

        for d in range(D):
            k = np.random.choice(K, 1, p=[1.0/K]*K)[0]
            K_d[d] = k
            M_k[k] = M_k[k]+1
            N_k[k] = N_k[k] + N_d[d]
            for w in words_d[d]:
                N_k_w[k, w] = N_k_w[k,w]+X[d,w]

        for iter in range(self.n_iter):
            print 'iter ', iter
            for d in range(D):
                k_old = K_d[d]
                M_k[k_old] -= 1
                N_k[k_old] -= N_d[d]
                for w in words_d[d]:
                    N_k_w[k_old, w] -= X[d,w]
                # sample k_new
                log_probs = [0]*K
                for k in range(K):
                    log_probs[k] += math.log(alpha+M_k[k])
                    for w in words_d[d]:
                        N_d_w = X[d,w]
                        for j in range(N_d_w):
                            log_probs[k] += math.log(N_k_w[k,w]+beta+j)
                    for i in range(N_d[d]):
                        log_probs[k] -= math.log(N_k[k]+beta*V+i)
                log_probs = np.array(log_probs) - max(log_probs)
                probs = np.exp(log_probs)
                probs = probs/np.sum(probs)
                k_new = np.random.choice(K, 1, p=probs)[0]
                K_d[d] = k_new
                M_k[k_new] += 1
                N_k[k_new] += N_d[d]
                for w in words_d[d]:
                    N_k_w[k_new, w] += X[d,w]
        self.topic_word_ = N_k_w.toarray()

我也在试验 GSDMM,运行 遇到了同样的问题,只是网上的资料不多(我找不到比你更多的资料,当然除了一些使用它的论文外)。如果您查看 GSDMM GitHub 存储库的代码,您会发现它是一个非常小的存储库,只有一些功能。这些基本上都是在 towarddatascience 的教程中使用的,所以我不认为你错过了什么。

如果您有具体问题,请随时提出!

编辑:如果您按照有关 towardsdatascience 的教程进行操作,您会发现这是一个不一致且未完成的项目。缺少一些辅助函数,算法未正确使用。作者使用 K=10 运行它并最终得到 10 个集群。如果你增加 K(你应该),那么集群的数量将高于 10,所以会有一点作弊发生。

我终于为 GSDMM 编译了我的代码,并将它从头开始放在这里供其他人使用。希望这可以帮助。我试图对重要部分发表评论:

# Imports
import random

import numpy as np
from gensim.models.phrases import Phraser, Phrases
from gensim.utils import simple_preprocess
from gsdmm import MovieGroupProcess


# data
data = ...

# stop words
stop_words = ...

# turning sentences into words
data_words =[]
for doc in data:
    doc = doc.split()
    data_words.append(doc)

# create vocabulary
vocabulary = ...

# Removing stop Words
stop_words.extend(['from', 'rt'])

def remove_stopwords(texts):
    return [
        [
            word
            for word in simple_preprocess(str(doc))
            if word not in stop_words
        ]
        for doc in texts
    ]

data_words_nostops = remove_stopwords(vocabulary)

# building bi-grams 
bigram = Phrases(vocabulary, min_count=5, threshold=100) 
bigram_mod = Phraser(bigram)
print('done!')

# Form Bigrams
data_words_bigrams = [bigram_mod[doc] for doc in data_words_nostops]

# lemmatization
pos_to_use = ['NOUN', 'ADJ', 'VERB', 'ADV']
data_lemmatized = []
for sent in data_words_bigrams:
    doc = nlp(" ".join(sent)) 
    data_lemmatized.append(
        [token.lemma_ for token in doc if token.pos_ in pos_to_use]
    )
      
docs = data_lemmatized
vocab = set(x for doc in docs for x in doc)

# Train a new model 
random.seed(1000)
# Init of the Gibbs Sampling Dirichlet Mixture Model algorithm
mgp = MovieGroupProcess(K=10, alpha=0.1, beta=0.1, n_iters=30)

vocab = set(x for doc in docs for x in doc)
n_terms = len(vocab)
n_docs = len(docs)

# Fit the model on the data given the chosen seeds
y = mgp.fit(docs, n_terms)

def top_words(cluster_word_distribution, top_cluster, values):
    for cluster in top_cluster:
        sort_dicts = sorted(
            mgp.cluster_word_distribution[cluster].items(),
            key=lambda k: k[1],
            reverse=True,
        )[:values]
        print('Cluster %s : %s'%(cluster,sort_dicts))
        print(' — — — — — — — — — ')

doc_count = np.array(mgp.cluster_doc_count)
print('Number of documents per topic :', doc_count)
print('*'*20)

# Topics sorted by the number of document they are allocated to
top_index = doc_count.argsort()[-10:][::-1]
print('Most important clusters (by number of docs inside):', top_index)
print('*'*20)


# Show the top 10 words in term frequency for each cluster 
top_words(mgp.cluster_word_distribution, top_index, 10)


希望对您有所帮助!

编辑:

链接

  1. gensim 个模块
  2. Python library gsdmm

据我了解,您有代码 https://github.com/rwalk/gsdmm,但您需要决定如何应用它。

它是如何工作的?

可以下载论文A dirichlet multinomial mixture model-based approach for short text clustering,说明聚类搜索等同于table选择游戏。图像有一组学生,并希望根据他们的电影兴趣将他们分组在 tables 上。每个学生 (=item) 在每一轮中切换到一个 table(=cluster),其中有学生有类似的电影并且很受欢迎。 Alpha 控制一个因素,该因素决定 table 为空时被删除的难易程度(低 alpha = 较少 tables)。小 betas 意味着选择 table 是基于与 table 的相似性,而不是基于 table 的受欢迎程度。对于短文本聚类,您使用单词而不是电影。

Alpha, beta, 迭代次数

因此,低 alpha 会导致许多包含单个词的聚类,而高 alpha 会导致较少的聚类和更多的词。高 beta 导致流行的集群,而低 beta 导致相似的集群(人口不多)。您需要什么参数取决于数据集。集群的数量主要由 beta 控制,但 alpha 也有(如所述)影响。 迭代次数 似乎是 stable 20 次迭代后,但 10 次也可以。

数据准备过程

在训练算法之前,您需要创建一个干净的数据集。为此,您将每个文本转换为小写,删除非 ASCII 字符和 stop-words and you apply stemming or lemmatisation。在新样本上执行时,您还需要应用此过程。