99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀短文本主題建模方法
短文本主題建模方法
2016-11-22
收藏

短文本主題建模方法

1. 引言

許多數(shù)據(jù)分析應(yīng)用都會涉及到從短文本中提取出潛在的主題,比如微博、短信、日志文件或者評論數(shù)據(jù)。一方面,提取出潛在的主題有助于下一步的分析,比如情感評分或者文本分類模型。另一方面,短文本數(shù)據(jù)存在一定的特殊性,我們無法直接用傳統(tǒng)的主題模型算法來處理它。短文本數(shù)據(jù)的主要難點在于:

短文本數(shù)據(jù)中經(jīng)常存在多詞一義的現(xiàn)象[1],比如 “dollar”, “$”, “$$”, “fee”, “charges” 擁有相同的含義,但是受限于文本篇幅的原因,我們很難直接從短文本數(shù)據(jù)中提取出這些信息。

與長文檔不同的地方在于,短文本數(shù)據(jù)中通常只包含一個主題。這看似很好處理,但是傳統(tǒng)的主題模型算法都假設(shè)一篇文檔中包含多個主題,這給建模分析帶來了不小的麻煩。
主題提取模型通常包含多個流程,比如文本預(yù)處理、文本向量化、主題挖掘和主題表示過程。每個流程中都有多種處理方法,不同的組合方法將會產(chǎn)生不同的建模結(jié)果。

本文將主要從實際操作的角度來介紹不同的短文本主題建模算法的優(yōu)缺點,更多理論上的探討可以參考以下文章。

下文中我將自己創(chuàng)建一個數(shù)據(jù)集,并利用 Python scikit-learn 來擬合相應(yīng)的主題模型。

2. 主題發(fā)現(xiàn)模型

本文主要介紹三個主題模型, LDA(Latent Dirichlet Allocation), NMF(Non-Negative Matrix Factorization)和SVD(Singular Value Decomposition)。本文主要采用 scikit-learn 來實現(xiàn)這三個模型。
除了這三個模型外,還有其他一些模型也可以用來發(fā)現(xiàn)文檔的結(jié)構(gòu)。其中最重要的一個模型就是 KMeans 聚類模型,本文將對比 KMeans 聚類模型和其他主題模型的擬合效果。
In [1]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.decomposition import TruncatedSVD, NMF, LatentDirichletAllocation
from sklearn.cluster import KMeans
首先,我們需要構(gòu)建文本數(shù)據(jù)集。本文將以四個自己構(gòu)建的文本數(shù)據(jù)集為例來構(gòu)建主題模型:

clearcut topics: 該數(shù)據(jù)集中只包含兩個主題—— “berger-lovers” 和 “sandwich-haters”。
unbalanced topics: 該數(shù)據(jù)集與第一個數(shù)據(jù)集包含的主題信息一致,但是此數(shù)據(jù)集的分布是有偏的。
semantic topics: 該數(shù)據(jù)集包含四個主題,分別是 “berger-lovers”, “berger-haters”,”sandwich-lovers” 和 “sandwich-haters”。此外,該數(shù)據(jù)集中還包含了兩個潛在的主題 “food” 和 “feelings”。
noisy topics: 正如前文所說的,短文本數(shù)據(jù)中經(jīng)常存在多詞一義的現(xiàn)象,該數(shù)據(jù)集主要用于模擬兩個主題不同類型的文本。該數(shù)據(jù)集文本的篇幅小于其他三個數(shù)據(jù)集,這可以用來檢驗?zāi)P褪欠衲軌蚝芎玫靥幚矶涛谋緮?shù)據(jù)。
In [2]:

def generate_clearcut_topics():
    ## for demostration purpose, don't take it personally : )
    return np.repeat(["we love bergers", "we hate sandwiches"], [1000, 1000])

def generate_unbalanced_topics():
    return np.repeat(["we love bergers", "we hate sandwiches"], [10, 1000])

def generate_semantic_context_topics():
    return np.repeat(["we love bergers"
                      , "we hate bergers"
                      , "we love sandwiches"
                      , "we hate sandwiches"], 1000)

def generate_noisy_topics():
    def _random_typos(word, n):
        typo_index = np.random.randint(0, len(word), n)
        return [word[:i]+"X"+word[i+1:] for i in typo_index]
    t1 = ["we love %s" % w for w in _random_typos("bergers", 15)]
    t2 = ["we hate %s" % w for w in _random_typos("sandwiches", 15)]
    return np.r_[t1, t2]

sample_texts = {
     "clearcut topics": generate_clearcut_topics()
    , "unbalanced topics": generate_unbalanced_topics()
    , "semantic topics": generate_semantic_context_topics()
    , "noisy topics": generate_noisy_topics()
}
In [3]:

from collections import Counter
for desc, texts in sample_texts.items():
    print desc
    print Counter(texts).most_common()
    print ""
noisy topics
[('we love bergerX', 4), ('we love berXers', 4), ('we love Xergers', 3), ('we hate sandwiXhes', 3), ('we hate sandXiches', 3), ('we love bergXrs', 2), ('we hate sanXwiches', 2), ('we hate sandwicheX', 2), ('we hate saXdwiches', 2), ('we hate sXndwiches', 1), ('we hate sandwXches', 1), ('we love bXrgers', 1), ('we hate Xandwiches', 1), ('we love bergeXs', 1)]

clearcut topics
[('we love bergers', 1000), ('we hate sandwiches', 1000)]

unbalanced topics
[('we hate sandwiches', 1000), ('we love bergers', 10)]

semantic topics
[('we love bergers', 1000), ('we love sandwiches', 1000), ('we hate sandwiches', 1000), ('we hate bergers', 1000)]
首先,我們需要考慮下如何評估一個主題模型建模效果的好壞程度。多數(shù)情況下,每個主題中的關(guān)鍵詞有以下兩個特征

關(guān)鍵詞出現(xiàn)的頻率得足夠大
足以區(qū)分不同的主題
一些研究表明:關(guān)鍵詞還需具備以下兩個特征

相同主題的文檔中關(guān)鍵詞共同出現(xiàn)的頻率應(yīng)該差不多
每個主題中關(guān)鍵詞的語義應(yīng)該十分接近,比如水果主題中的 “apples” 和 “oranges”,或者情感主題中的 “l(fā)ove” 和 “hate”。
接下來,我們將介紹如何實現(xiàn)上述的四個模型——NMF, SVD, LDA 和 KMEANS。對于每個主題模型,我們將分別采用兩種文本向量化的方法—— TF(Term Frequence) 和 TFIDF(Term-frequence-inverse-document-frequence)。通常情況下,如果你的數(shù)據(jù)集中有許多詞語在多篇文檔中都頻繁出現(xiàn),那么你應(yīng)該選擇采用 TFIDF 的向量化方法。此時這些頻繁出現(xiàn)的詞語將被視為噪聲數(shù)據(jù),這些數(shù)據(jù)會影響模型的擬合效果。然而對于短文本數(shù)據(jù)而言,TF和TFIDF方法并沒有顯著的區(qū)別,因為短文本數(shù)據(jù)集中很難碰到上述情況。如何將文本數(shù)據(jù)向量化是個非常熱門的研究領(lǐng)域,比如 基于word embedding模型的方法——word2vec和doc2vec。

主題模型將選擇主題詞語分布中頻率最高的詞語作為該主題的關(guān)鍵詞,但是對于 SVD 和 KMEANS 算法來說,模型得到的主題詞語矩陣中既包含正向值也包含負向值,我們很難直接從中準(zhǔn)確地提取出主題關(guān)鍵詞。為了解決這個問題,我選擇從中挑出絕對數(shù)值最大的幾個詞語作為關(guān)鍵詞,并且根據(jù)正負值的情況加上相應(yīng)的標(biāo)簽,即對負向詞語加上 “^” 的前綴,比如“^bergers”。

In [4]:

def find_topic(texts, topic_model, n_topics, vec_model="tf", thr=1e-2, **kwargs):
    """Return a list of topics from texts by topic models - for demostration of simple data
    texts: array-like strings
    topic_model: {"nmf", "svd", "lda", "kmeans"} for LSA_NMF, LSA_SVD, LDA, KMEANS (not actually a topic model)
    n_topics: # of topics in texts
    vec_model: {"tf", "tfidf"} for term_freq, term_freq_inverse_doc_freq
    thr: threshold for finding keywords in a topic model
    """
    ## 1. vectorization
    vectorizer = CountVectorizer() if vec_model == "tf" else TfidfVectorizer()
    text_vec = vectorizer.fit_transform(texts)
    words = np.array(vectorizer.get_feature_names())
    ## 2. topic finding
    topic_models = {"nmf": NMF, "svd": TruncatedSVD, "lda": LatentDirichletAllocation, "kmeans": KMeans}
    topicfinder = topic_models[topic_model](n_topics, **kwargs).fit(text_vec)
    topic_dists = topicfinder.components_ if topic_model is not "kmeans" else topicfinder.cluster_centers_
    topic_dists /= topic_dists.max(axis = 1).reshape((-1, 1))   
    ## 3. keywords for topics
    ## Unlike other models, LSA_SVD will generate both positive and negative values in topic_word distribution,
    ## which makes it more ambiguous to choose keywords for topics. The sign of the weights are kept with the
    ## words for a demostration here
    def _topic_keywords(topic_dist):
        keywords_index = np.abs(topic_dist) >= thr
        keywords_prefix = np.where(np.sign(topic_dist) > 0, "", "^")[keywords_index]
        keywords = " | ".join(map(lambda x: "".join(x), zip(keywords_prefix, words[keywords_index])))
        return keywords
    
    topic_keywords = map(_topic_keywords, topic_dists)
    return "n".join("Topic %i: %s" % (i, t) for i, t in enumerate(topic_keywords))
2.1 SVD: 正交分解

sklearn 中的 truncated SVD implementation 類似于主成分分析算法,它們都試圖利用正交分解的方法選擇出具有最大方差的變量信息。

對于 clearcut-topic 數(shù)據(jù)集來說,我們分別利用 TF 和 TFIDF方法來向量化文本數(shù)據(jù),并構(gòu)建 SVD 模型,模型的擬合結(jié)果如下所示。正如我們之前所提到的,SVD 模型所提取的關(guān)鍵詞中包含正負向詞語。為了簡單起見, 我們可以理解為該主題包含正向詞語,不包含負向的詞語。

比如,對于 "Topic 1: bergers | ^hate | love | ^sandwiches" 來說,該文本的主題中包含 “l(fā)ove bergers” 但是不包含 “hate sandwiches”。

由于模型的隨機效應(yīng),所以每次運行模型得到的結(jié)果都會存在細微的差異。在 SVD 的擬合結(jié)果中我們發(fā)現(xiàn)發(fā)現(xiàn) Topic 3: bergers | ^hate | ^love | sandwiches 成功地提取了 “food” 的主題。

In [9]:

print(find_topic(sample_texts["clearcut topics"], "svd", 4, vec_model="tf"))
Topic 0: bergers | hate | love | sandwiches | we
Topic 1: bergers | ^hate | love | ^sandwiches
Topic 2: bergers | hate | love | sandwiches | ^we
Topic 3: bergers | ^hate | ^love | sandwiches
In [10]:

print(find_topic(sample_texts["clearcut topics"], "svd", 4, vec_model="tfidf"))
Topic 0: bergers | hate | love | sandwiches | we
Topic 1: bergers | ^hate | love | ^sandwiches
Topic 2: bergers | hate | love | sandwiches | ^we
Topic 3: bergers | ^hate | ^love | sandwiches
在上述的例子中,我們設(shè)定了過多的主題數(shù)量,這是因為大多數(shù)時候我們無法事先知道某個文檔包含多少個主題。如果我們令主題個數(shù)等于2,可以得到下述結(jié)果:

In [11]:

print(find_topic(sample_texts["clearcut topics"], "svd", 2, vec_model="tfidf"))
Topic 0: bergers | hate | love | sandwiches | we
Topic 1: bergers | ^hate | love | ^sandwiches
當(dāng)我們在解釋 SVD 模擬的擬合結(jié)果時,我們需要對比多個主題的信息。比如上述的模型擬合結(jié)果可以解釋成:數(shù)據(jù)集中文檔的主要差異是文檔中包含 “l(fā)ove bergers” 但不包含 “hate sandwiches”。

接下來我們將利用 SVD 來擬合 unbalanced topic 數(shù)據(jù)集,檢驗該模型處理非平衡數(shù)據(jù)集的效果。

In [12]:

print(find_topic(sample_texts["unbalanced topics"], "svd", 3, vec_model="tf"))
Topic 0: hate | sandwiches | we
Topic 1: bergers | ^hate | love | ^sandwiches | we
Topic 2: bergers | hate | love | sandwiches | ^we
從下述結(jié)果中可以看出,SVD無法處理噪聲數(shù)據(jù),即無法從中提取出主題信息。

In [13]:

print(find_topic(sample_texts["noisy topics"], "svd", 2, vec_model="tf"))
Topic 0: bergerx | bergexs | bergxrs | berxers | bxrgers | hate | love | sandwichex | sandwixhes | sandwxches | sandxiches | sanxwiches | saxdwiches | sxndwiches | we | xandwiches | xergers
Topic 1: ^bergerx | ^bergexs | ^bergxrs | ^berxers | ^bxrgers | hate | ^love | sandwichex | sandwixhes | sandwxches | sandxiches | sanxwiches | saxdwiches | sxndwiches | we | xandwiches | ^xergers
2.2 LDA: 根據(jù)詞語的共現(xiàn)頻率來提取主題

LDA 是最常用的主題提取模型之一,因為該模型能夠處理多種類型的文本數(shù)據(jù),而且模擬的擬合效果非常易于解釋。

直觀上來看,LDA 根據(jù)不同文檔中詞語的共現(xiàn)頻率來提取文本中潛在的主題信息。另一方面,具有相同主題結(jié)構(gòu)的文本之間往往非常相似,因此我們可以根據(jù)潛在的主題空間來推斷詞語之間的相似性和文檔之間的相似性。

LDA 算法中主要有兩類參數(shù):

每個主題中各個關(guān)鍵詞的分布參數(shù)
每篇文檔中各個主題的分布參數(shù)
接下來我們將研究這些參數(shù)是如何影響 LDA 模型的計算過程,人們更多的是根據(jù)經(jīng)驗來選擇最佳參數(shù)。

SVD 模型不同的是,LDA 模型所提取的主題非常好解釋。以 clearcut-topics 數(shù)據(jù)集為例,LDA 模型中每個主題都有明確的關(guān)鍵詞,它和SVD主要有以下兩個區(qū)別:

LDA 模型中可能存在重復(fù)的主題
不同的主題可以共享相同的關(guān)鍵詞,比如單詞 “we” 在所有的主題中都出現(xiàn)了。
此外,對 LDA 模型來說,采用不同的文本向量化方法也會得到不同的結(jié)果。

In [14]:

print(find_topic(sample_texts["clearcut topics"], "lda", 4, vec_model="tf"))
Topic 0: bergers | love | we
Topic 1: bergers | love | we
Topic 2: hate | sandwiches | we
Topic 3: bergers | love | we
In [15]:

print(find_topic(sample_texts["clearcut topics"], "lda", 4, vec_model="tfidf"))
Topic 0: bergers | love | we
Topic 1: bergers | love | we
Topic 2: bergers | love | we
Topic 3: hate | sandwiches | we
在 sklearn 中,參數(shù) topic_word_prior 和 doc_topic_prior 分別用來控制 LDA 模型的兩類參數(shù)。

其中 topic_word_prior 的默認值是 1n_topics1n_topics,這意味著主題中的每個詞語服從均勻分布。

In [16]:

print(find_topic(sample_texts["unbalanced topics"], "lda", 4, vec_model="tf"))
Topic 0: bergers | hate | love | sandwiches | we
Topic 1: hate | sandwiches | we
Topic 2: bergers | hate | love | sandwiches | we
Topic 3: hate | sandwiches | we
選擇更小的 topic_word_prior 參數(shù)值可以提取粒度更小的主題信息,因為每個主題中都會選擇更少的詞語。

In [17]:

print(find_topic(sample_texts["unbalanced topics"], "lda", 4, vec_model="tf", topic_word_prior=1e-5))
Topic 0: bergers | love | we
Topic 1: hate | sandwiches | we
Topic 2: hate | sandwiches | we
Topic 3: hate | sandwiches | we
LDA 模型同樣無法很好地處理 noisy topics 數(shù)據(jù)集,從下述結(jié)果中可以看出 LDA 模型提取的主題相當(dāng)模糊:

In [18]:

print find_topic(sample_texts["noisy topics"],"lda",3, vec_model = "tfidf")
Topic 0: bergerx | bergexs | bergxrs | berxers | bxrgers | hate | love | sandwichex | sandwixhes | sandwxches | sandxiches | sanxwiches | saxdwiches | sxndwiches | we | xandwiches | xergers
Topic 1: bergerx | bergexs | bergxrs | berxers | bxrgers | hate | love | sandwichex | sandwixhes | sandwxches | sandxiches | sanxwiches | saxdwiches | sxndwiches | we | xandwiches | xergers
Topic 2: bergerx | bergexs | bergxrs | berxers | bxrgers | hate | love | sandwichex | sandwixhes | sandwxches | sandxiches | sanxwiches | saxdwiches | sxndwiches | we | xandwiches | xergers
2.3 NMF

NMF 可以視為 LDA模型的特例,從理論上來說,這兩個模型之間的聯(lián)系非常復(fù)雜。但是在實際應(yīng)用中,NMF 經(jīng)常被視為參數(shù)固定且可以獲得稀疏解的 LDA 模型。雖然 NMF 模型的靈活性不如 LDA 模型,但是該模型可以很好地處理短文本數(shù)據(jù)集。

另一方面,NMF 最大的缺點是擬合結(jié)果的不一致——當(dāng)我們設(shè)置過大的主題個數(shù)時,NMF 擬合的結(jié)果非常糟糕。相比之下,LDA模型的擬合結(jié)果更為穩(wěn)健。

首先我們來看下 NMF 模型不一致的擬合結(jié)果。對于 clearcut topics 數(shù)據(jù)集來說,當(dāng)我們設(shè)置提取5個主題時,其結(jié)果和真實結(jié)果非常相似:

In [19]:

print(find_topic(sample_texts["clearcut topics"], "nmf", 5, vec_model="tf"))
Topic 0: bergers | love | we
Topic 1: hate | sandwiches | we
Topic 2: bergers | love | we
Topic 3: bergers | love | we
Topic 4: hate | sandwiches | we
但是當(dāng)我們增加主題個數(shù)時(遠大于真實主題數(shù)2),NMF 模型將會得到一些奇異的結(jié)果:

In [20]:

print(find_topic(sample_texts["clearcut topics"], "nmf", 25, vec_model="tf"))
Topic 0: we
Topic 1: bergers | love | we
Topic 2: hate | sandwiches | we
Topic 3: bergers | love | we
Topic 4: hate | sandwiches | we
Topic 5: bergers | love | we
Topic 6: bergers | love | we
Topic 7: bergers | love | we
Topic 8: hate | sandwiches | we
Topic 9: hate | sandwiches | we
Topic 10: hate | sandwiches | we
Topic 11: bergers | love | we
Topic 12: we
Topic 13: hate | sandwiches
Topic 14: we
Topic 15: we
Topic 16: bergers | love | we
Topic 17: sandwiches | we
Topic 18: we
Topic 19: bergers | love | we
Topic 20: hate | sandwiches | we
Topic 21: sandwiches | we
Topic 22: bergers | love | we
Topic 23: we
Topic 24: bergers | love | we
相比之下,LDA模型的結(jié)果十分穩(wěn)健。

In [21]:

print(find_topic(sample_texts["clearcut topics"], "lda", 25, vec_model="tf"))
Topic 0: bergers | love | we
Topic 1: bergers | love | we
Topic 2: hate | sandwiches | we
Topic 3: bergers | hate | love | sandwiches | we
Topic 4: bergers | love | we
Topic 5: bergers | love | we
Topic 6: bergers | love | we
Topic 7: bergers | love | we
Topic 8: bergers | hate | love | sandwiches | we
Topic 9: bergers | hate | love | sandwiches | we
Topic 10: bergers | hate | love | sandwiches | we
Topic 11: hate | sandwiches | we
Topic 12: bergers | hate | love | sandwiches | we
Topic 13: bergers | love | we
Topic 14: hate | sandwiches | we
Topic 15: bergers | love | we
Topic 16: bergers | love | we
Topic 17: bergers | hate | love | sandwiches | we
Topic 18: hate | sandwiches | we
Topic 19: bergers | love | we
Topic 20: bergers | love | we
Topic 21: bergers | hate | love | sandwiches | we
Topic 22: hate | sandwiches | we
Topic 23: bergers | love | we
Topic 24: hate | sandwiches | we
對于非平衡數(shù)據(jù)集,設(shè)置好合適的主題個數(shù),NMF 可以很好地提取出文檔中的主題信息。

In [22]:

print(find_topic(sample_texts["unbalanced topics"], "nmf", 5, vec_model="tfidf"))
Topic 0: hate | sandwiches | we
Topic 1: hate | sandwiches | we
Topic 2: hate | sandwiches | we
Topic 3: hate | sandwiches | we
Topic 4: bergers | love | we
值得注意的是,NMF 是本文提到的四個模型中唯一一個能夠較好地處理 noisy topics 數(shù)據(jù)的模型:

In [23]:

print find_topic(sample_texts["noisy topics"],"nmf",5, vec_model = "tfidf",)
Topic 0: bergerx | bergexs | bergxrs | bxrgers | love | we
Topic 1: bergxrs | hate | sandwichex | sandwxches | sandxiches | sanxwiches | saxdwiches | sxndwiches | we | xandwiches
Topic 2: bergexs | bergxrs | berxers | bxrgers | love | we
Topic 3: bergexs | bergxrs | bxrgers | love | we | xergers
Topic 4: hate | sandwixhes | sandwxches | sxndwiches | we | xandwiches
2.4 KMeans

類似于 KMeans 模型的聚類方法能夠根據(jù)文檔的向量形式對其進行分組。然而這個模型無法看成是主題模型,因為我們很難解釋聚類結(jié)果中的關(guān)鍵詞信息。

但是如果結(jié)合 TF或TFIDF方法,我們可以將 KMeans 模型的聚類中心視為一堆詞語的概率組合:

In [24]:

print find_topic(sample_texts["clearcut topics"],"kmeans",10, vec_model = "tf",)
Topic 0: hate | sandwiches | we
Topic 1: bergers | love | we
Topic 2: hate | sandwiches | we
Topic 3: bergers | love | we
Topic 4: bergers | love | we
Topic 5: bergers | love | we
Topic 6: bergers | love | we
Topic 7: bergers | love | we
Topic 8: bergers | love | we
Topic 9: bergers | love | we
In [25]:

print find_topic(sample_texts["unbalanced topics"],"kmeans",10, vec_model = "tf",)
Topic 0: hate | sandwiches | we
Topic 1: bergers | love | we
Topic 2: hate | sandwiches | we
Topic 3: hate | sandwiches | we
Topic 4: hate | sandwiches | we
Topic 5: hate | sandwiches | we
Topic 6: hate | sandwiches | we
Topic 7: hate | sandwiches | we
Topic 8: hate | sandwiches | we
Topic 9: hate | sandwiches | we
In [26]:

print find_topic(sample_texts["noisy topics"],"kmeans",10, vec_model = "tf",)
Topic 0: hate | sandwxches | sxndwiches | we | xandwiches
Topic 1: bergexs | berxers | bxrgers | love | we
Topic 2: bergerx | love | we
Topic 3: hate | sandxiches | we
Topic 4: love | we | xergers
Topic 5: hate | sandwixhes | we
Topic 6: hate | sandwichex | we
Topic 7: bergxrs | love | we
Topic 8: hate | sanxwiches | we
Topic 9: hate | saxdwiches | we
2.5 尋找具有高語義相關(guān)的主題

最后,我將簡單比較下不同的主題提取模型。大多數(shù)情況下,我們傾向于根據(jù)文檔的主題分布情況對其進行分組,并根據(jù)關(guān)鍵詞的分布情況來提取主題的信息。

大多數(shù)研究者都認為詞語的語義信息是由其上下文信息所決定的,比如 “l(fā)ove” 和 “hate”可以看成是語義相似的詞語,因為這兩個詞都可以用在 “I _ apples” 的語境中。事實上,詞向量最重要的一個研究就是如何構(gòu)建詞語、短語或者文檔的向量形式,使得新的向量空間中仍然保留著語義信息。

找尋語義相同的詞語不同于計算詞語的共現(xiàn)頻率。從下述的結(jié)果中可以看出,大多數(shù)主題提取模型只涉及到詞語的共現(xiàn)頻率,并沒有考慮詞語的語義信息,只有 SVD 模型簡單涉及到語義信息。

需要注意的是,本文所采用的數(shù)據(jù)集是根據(jù)一定的規(guī)則隨機生成的,所以下述結(jié)果更多的是用于說明不同模型之間的區(qū)別:

In [27]:

print(find_topic(sample_texts["semantic topics"], "svd", 4, vec_model="tfidf"))
Topic 0: bergers | hate | love | sandwiches | we
Topic 1: ^hate | love
Topic 2: bergers | ^sandwiches
Topic 3: ^bergers | ^hate | ^love | ^sandwiches | we
In [28]:

print(find_topic(sample_texts["semantic topics"], "nmf", 5, vec_model="tfidf"))
Topic 0: bergers | hate
Topic 1: love | sandwiches | we
Topic 2: hate | we
Topic 3: hate | sandwiches | we
Topic 4: bergers | love | we
In [29]:

print(find_topic(sample_texts["semantic topics"], "lda", 5, vec_model="tfidf"))
Topic 0: love | sandwiches | we
Topic 1: bergers | love | we
Topic 2: bergers | hate | we
Topic 3: bergers | love | we
Topic 4: bergers | love | we
In [30]:

print(find_topic(sample_texts["semantic topics"], "kmeans", 5, vec_model="tfidf"))
Topic 0: hate | sandwiches | we
Topic 1: bergers | hate | we
Topic 2: bergers | love | we
Topic 3: love | sandwiches | we
Topic 4: hate | sandwiches | we
3. 總結(jié)
短文本數(shù)據(jù)集具有其獨特的性質(zhì),建模時需要特別注意。
模型的選擇依賴于主題的定義(共現(xiàn)頻率高或者語義相似性)和主題提取的目的(文檔表示或者是異常值檢驗)
我們可以首先采用 KMeans 或者 NMF 模型來快速獲取文檔的結(jié)構(gòu)信息:
主題中詞語的分布情況
文檔中主題的分布情況
主題個數(shù)
每個主題中詞語的個數(shù)
LDA 模型具有很好的靈活性,可以處理多種類型的文本數(shù)據(jù)。但是調(diào)參過程需要很好地理解數(shù)據(jù)結(jié)構(gòu),因此如果你想構(gòu)建 LDA 模型,你最好先構(gòu)建一個基準(zhǔn)模型(KMEANS 或 NMF)
SVD 模型可以很好地提取出文本的主要信息。比如 SVD 模型可以很好地分析半結(jié)構(gòu)化的數(shù)據(jù)(模板數(shù)據(jù)、截圖或者html中的表格數(shù)據(jù))。

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }