初識gensim


介紹

Gensim是一個用於從文檔中自動提取語義主題的Python庫,足夠智能,堪比無 痛人流。
Gensim可以處理原生,非結構化的數值化文本(純文本)。Gensim里面的算法,比如Latent Semantic Analysis(潛在語義分析LSA),Latent Dirichlet Allocation,Random Projections,通過在語料庫的訓練下檢驗詞的統計共生模式(statistical co-occurrence patterns)來發現文檔的語義結構。這些算法是非監督的,也就是說你只需要一個語料庫的文檔集。
當得到這些統計模式后,任何文本都能夠用語義表示(semantic representation)來簡潔的表達,並得到一個局部的相似度與其他文本區分開來。

核心概念

Corpus

數字化文檔的集合,被用於自動推斷文檔的結構和主題等。由此,corpus也稱作training corpus,被推斷的這些潛在結構用於給新的文檔分配主題,無需人為介入,比如給文檔打標簽,不存在的。

Vector

在向量空間模型中,每個文檔被表示成了一組特征,比如,一個單一的特征可能被視為一個問答對。

1.How many times does the word splonge appear in the document? Zero.
2.How many paragraphs does the document consist of? Two.
3.How many fonts does the document use? Five.
問題通常被表示成整數ID,在這里就是1,2,3.所以這篇文檔就表示成了(1, 0.0), (2, 2.0), (3, 5.0). 如果我們提前知道所有問題,那我們可能會省略他們,然后簡單的寫成(0.0, 2.0, 5.0).答案的序列被視為一個向量(這個例子里是三維向量),出於實際考慮,我們只考慮那些答案可以轉換成一個單一實數的問題。

Sparse Vector

通常,大部分問題的答案都是0,為了節約空間,我們會從文檔表示中省略他們,只寫成(2, 2.0), (3, 5.0) (去掉 (1, 0.0)). 既然問題提前知道,那文檔中所有稀疏表示的丟失特征都是0.
Gensim不會指定任何特定的Corpus格式,不管Corpus是怎樣的格式,迭代時回一次產生這些Sparse Vector

Model

我們用model將一個文檔的表示轉換成另一個。Gensim中文檔表示成向量,所以model可以看成是兩個向量空間的轉換。轉換的細節從training corpus中學習

語料(Corpus):一組原始文本的集合,用於無監督地訓練文本主題的隱層結構。語料中不需要人工標注的附加信息。在Gensim中,Corpus通常是一個可迭代的對象(比如列表)。每一次迭代返回一個可用於表達文本對象的稀疏向量。
向量(Vector):由一組文本特征構成的列表。是一段文本在Gensim中的內部表達。
稀疏向量(Sparse Vector):通常,我們可以略去向量中多余的0元素。此時,向量中的每一個元素是一個(key, value)的tuple。
模型(Model):是一個抽象的術語。定義了兩個向量空間的變換(即從文本的一種向量表達變換為另一種向量表達)。

學習Gensim

學習gensim首先得安裝:

pip install gensim

接下來我們結合案例做一個簡單的學習

import jieba
# 語料庫
from gensim import corpora
# 導入語言模型
from gensim import models
# 稀疏矩陣相識度
from gensim import similarities
# 語料庫
l1 = ["你的名字是什么", "你今年幾歲了", "你有多高你手多大", "你手多大"]
# 用戶問的問題
a = "你今年多大了"
all_doc_list = []  #
for doc in l1:
    # 利用jieba分詞將語料庫中的每一個問題切割
    doc_list = [word for word in jieba.cut(doc)]
    all_doc_list.append(doc_list)
print(all_doc_list)
# [['你', '的', '名字', '是', '什么'], ['你', '今年', '幾歲', '了'], ['你', '有', '多', '高', '你', '手多大'], ['你', '手多大']]

# 利用jieba分詞將要問的問題切割
doc_test_list = [word for word in jieba.cut(a)]
print(doc_test_list)
# ['你', '今年', '多大', '了']  ==>1685

# 制作語料庫
dictionary = corpora.Dictionary(all_doc_list)  # 制作詞袋
# 詞袋:是根據當前所有的問題即列表all_doc_list中每一個列表中的每一個元素(就是字)為他們做一個唯一的標志,形成一個key:velue的字典
print("token2id", dictionary.token2id)
# print("dictionary", dictionary, type(dictionary))
# token2id {'什么': 0, '你': 1, '名字': 2, '是': 3, '的': 4, '了': 5, '今年': 6, '幾歲': 7, '多': 8, '手多大': 9, '有': 10, '高': 11}

# ['你', '的', '名字', '是', '什么'] ==>14230
# ['你', '今年', '幾歲', '了']  ==>1675

# 制作語料庫
# 這里是將all_doc_list 中的每一個列表中的詞語 與 dictionary 中的Key進行匹配
# doc2bow文本變成id,這個詞在當前的列表中出現的次數
# ['你', '的', '名字', '是', '什么'] ==>(1,1),(4,1),(2,1),(3,1),(0,1)
# 1是你 1代表出現一次, 4是的  1代表出現了一次, 以此類推 2是名字 , 3是是,0是什么
corpus = [dictionary.doc2bow(doc) for doc in all_doc_list]
print("corpus", corpus, type(corpus))
# corpus [[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1)], [(1, 1), (5, 1), (6, 1), (7, 1)], [(1, 2), (8, 1), (9, 1), (10, 1), (11, 1)], [(1, 1), (9, 1)]] <class 'list'>

# ['你', '今年', '多大', '了']  詞袋中沒有多大165
# 所以需要詞向量化

# 將需要尋找相似度的分詞列表 做成 語料庫 doc_test_vec
# ['你', '今年', '多大', '了']  (1, 1), (5, 1), (6, 1)
doc_test_vec = dictionary.doc2bow(doc_test_list)
print("doc_test_vec", doc_test_vec, type(doc_test_vec))
# doc_test_vec [(1, 1), (5, 1), (6, 1)] <class 'list'>

# 將corpus語料庫(初識語料庫) 使用Lsi模型進行訓練,將語料庫變成計算機可識別可讀的數字
lsi = models.LsiModel(corpus)
print("lsi", lsi, type(lsi))
# lsi[corpus] <gensim.interfaces.TransformedCorpus object at 0x000001D92EEB43C8>
# 語料庫corpus的訓練結果
print("lsi[corpus]", lsi[corpus])
# lsi[corpus] <gensim.interfaces.TransformedCorpus object at 0x000001D92EEB43C8>

# 將問題放到放到已經訓練好的語料庫模型一個一個匹配,獲取匹配分值
# 獲得語料庫doc_test_vec 在 語料庫corpus的訓練結果 中的 向量表示
print("lsi[doc_test_vec]", lsi[doc_test_vec])
# lsi[doc_test_vec] [(0, 0.9910312948854694), (1, 0.06777365757876067), (2, 1.1437866478720622), (3, -0.015934342901802588)]
# 排過序,數字表示相識度,負數表示無限不接近

# 文本相似度
# 稀疏矩陣相似度 將 主 語料庫corpus的訓練結果 作為初始值

# 舉例:匹配5*5的正方形
# 目前有[(3,3),(3,5),(4,5),(6,6)]
# 設定-(1形狀相似2.周長相識3面積相似),根據選定設定好的條件匹配最相似的,涉及算法

# lsi[corpus]==>Lsi訓練好的語料庫模型
# index是設定的匹配相識度的條件
index = similarities.SparseMatrixSimilarity(lsi[corpus], num_features=len(dictionary.keys()))
print("index", index, type(index))

# 將 語料庫doc_test_vec 在 語料庫corpus的訓練結果 中的 向量表示 與 語料庫corpus的 向量表示 做矩陣相似度計算
gongyinshi = lsi[doc_test_vec]
print(gongyinshi)
sim = index[gongyinshi]

print("sim", sim, type(sim))

# 對下標和相似度結果進行一個排序,拿出相似度最高的結果
# cc = sorted(enumerate(sim), key=lambda item: item[1],reverse=True)
cc = sorted(enumerate(sim), key=lambda item: -item[1])
print(cc)

text = l1[cc[0][0]]
if cc[0][1] > 0:
    print(a, text)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM