自然語言學習05-非結構化詞袋和詞向量模型 筆記

詞袋模型(Bag of Words Model)

詞袋模型把文本(段落或者文檔)被看作是無序的詞彙集合,忽略語法甚至是單詞的順序,把每一個單詞都進行統計,同時計算每個單詞出現的次數,常常被用在文本分類中,如貝葉斯算法、LDA 和 LSA 等。

引入 jieba 分詞器、語料和停用詞(標點符號集合,自己可以手動添加或者用一個文本字典代替)。

import jieba
#定義停用詞、標點符號
punctuation = [",","。", ":", ";", "?"]
#定義語料
content = ["機器學習帶動人工智能飛速的發展。",
            "深度學習帶動人工智能飛速的發展。",
            "機器學習和深度學習帶動人工智能飛速的發展。"
            ]

先對語料進行分詞操作

#分詞
segs_1 = [jieba.lcut(con) for con in content]
print(segs_1)

因爲中文語料帶有停用詞和標點符號,所以需要去停用詞和標點符號,這裏是去掉標點符號

    tokenized = []
    for sentence in segs_1:
        words = []
        for word in sentence:
            if word not in punctuation:          
                words.append(word)
        tokenized.append(words)
    print(tokenized)

把所有的分詞結果放到一個袋子(List)裏面,也就是取並集,再去重,獲取對應的特徵詞。

    #求並集
    bag_of_words = [ x for item in segs_1 for x in item if x not in punctuation]
    #去重
    bag_of_words = list(set(bag_of_words))
    print(bag_of_words)

完成詞袋化

#詞袋化
bag_of_word2vec = []
for sentence in tokenized:
    tokens = [1 if token in sentence else 0 for token in bag_of_words]
    bag_of_word2vec.append(tokens)
print(bag_of_word2vec)
['飛速', '發展', '的', '人工智能', '深度', '和', '機器', '學習', '帶動']
[[1, 1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 0, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1]]

(2)Gensim 構建詞袋模型

from gensim import corpora
import gensim
import jieba
#定義停用詞、標點符號
punctuation = [",","。", ":", ";", "?"]
#定義語料
content = ["機器學習帶動人工智能飛速的發展。",
            "深度學習帶動人工智能飛速的發展。",
            "機器學習和深度學習帶動人工智能飛速的發展。"
            ]
#分詞
segs_1 = [jieba.lcut(con) for con in content]
print(segs_1)
#去標點符號
tokenized = []
for sentence in segs_1:
    words = []
    for word in sentence:
        if word not in punctuation:
            words.append(word)
    tokenized.append(words)
print(tokenized)
# tokenized是去標點之後的
dictionary = corpora.Dictionary(tokenized)
# 保存詞典
dictionary.save('deerwester.dict')
print(dictionary)

查看所有詞,可以查看到所有詞和對應的下標

#查看詞典和下標 id 的映射
print(dictionary.token2id)
{'人工智能': 0, '發展': 1, '學習': 2, '帶動': 3, '機器': 4, '的': 5, '飛速': 6, '深度': 7, '和': 8}

根據得到的結果,可以得到詞袋模型的特徵向量。函數 doc2bow()作用是計算每個不同單詞的出現次數,將單詞轉換爲其整數單詞 id 並將結果作爲稀疏向量返回。

corpus = [dictionary.doc2bow(sentence) for sentence in segs_1]
print(corpus )
[[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1)], [(0, 1), (1, 1), (2, 1), (3, 1), (5, 1), (6, 1), (7, 1)], [(0, 1), (1, 1), (2, 2), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1), (8, 1)]]

 

詞向量 (Word Embedding)

詞向量技術是將詞語轉化成爲稠密向量。

Word2Vec 可以將獨熱編碼 One-Hot Encoder 轉化爲低維度的連續值,也就是稠密向量,並且其中意思相近的詞也將被映射到向量空間中相近的位置。經過降維,在二維空間中,相似的單詞在空間中的距離也很接近。

詞向量就是要用某個固定維度的向量去表示單詞。也就是說要把單詞變成固定維度的向量,作爲機器學習(Machine Learning)或深度學習模型的特徵向量輸入。

(1)Word2Vec

Word2Vec 主要包含兩種模型:Skip-Gram 和 CBOW,Word2Vec 詞向量可以較好地表達不同詞之間的相似和類比關係。

pip install gensim

先導入 Gensim 中的 Word2Vec 和 jieba 分詞器,再引入語料:

from gensim.models import Word2Vec
import jieba

# 定義停用詞、標點符號
punctuation = [",", "。", ":", ";", ".", "'", '"', "’", "?", "/", "-", "+", "&", "(", ")"]
sentences = [
    "長江是中國第一大河,幹流全長6397公里(以沱沱河爲源),一般稱6300公里。流域總面積一百八十餘萬平方公里,年平均入海水量約九千六百餘億立方米。以幹流長度和入海水量論,長江均居世界第三位。",
    "黃河,中國古代也稱河,發源於中華人民共和國青海省巴顏喀拉山脈,流經青海、四川、甘肅、寧夏、內蒙古、陝西、山西、河南、山東9個省區,最後于山東省東營墾利縣注入渤海。幹流河道全長5464千米,僅次於長江,爲中國第二長河。黃河還是世界第五長河。",
    "黃河,是中華民族的母親河。作爲中華文明的發祥地,維繫炎黃子孫的血脈.是中華民族民族精神與民族情感的象徵。",
    "黃河被稱爲中華文明的母親河。公元前2000多年華夏族在黃河領域的中原地區形成、繁衍。",
    "在蘭州的“黃河第一橋”內蒙古托克托縣河口鎮以上的黃河河段爲黃河上游。",
    "黃河上游根據河道特性的不同,又可分爲河源段、峽谷段和沖積平原三部分。 ",
    "黃河,是中華民族的母親河。"
]

分詞,去標點符號操作(未去停用詞)

    sentences = [jieba.lcut(sen) for sen in sentences]
    tokenized = []
    for sentence in sentences:
        words = []
        for word in sentence:
            if word not in punctuation:          
                words.append(word)
        tokenized.append(words)

模型訓練

model = Word2Vec(tokenized, sg=1, size=100,  window=5,  min_count=2,  negative=1, sample=0.001, hs=1, workers=4)

參數解釋如下:

  • sg=1 是 skip-gram 算法,對低頻詞敏感;默認 sg=0 爲 CBOW 算法。
  • size 是輸出詞向量的維數,值太小會導致詞映射因爲衝突而影響結果,值太大則會耗內存並使算法計算變慢,一般值取爲100到200之間。
  • window 是句子中當前詞與目標詞之間的最大距離,3表示在目標詞前看3-b 個詞,後面看 b 個詞(b 在0-3之間隨機)。
  • min_count 是對詞進行過濾,頻率小於 min-count 的單詞則會被忽視,默認值爲5。
  • negative 和 sample 可根據訓練結果進行微調,sample 表示更高頻率的詞被隨機下采樣到所設置的閾值,默認值爲 1e-3。
  • hs=1 表示層級 softmax 將會被使用,默認 hs=0 且 negative 不爲0,則負採樣將會被選擇使用。
  • 詳細參數說明可查看 Word2Vec 源代碼。

訓練後的模型可以保存與加載

    model.save('model')  #保存模型
    model = Word2Vec.load('model')   #加載模型

使用模型,可以用來計算句子或者詞的相似性、最大匹配程度等。

判斷一下黃河和黃河自己的相似度:

print(model.similarity('黃河', '黃河'))

預測與黃河和母親河最接近,而與長江不接近的詞

print(model.most_similar(positive=['黃河', '母親河'], negative=['長江']))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章