文本表示

文本向量化是文本表示的一種重要方式,其中詞袋 Bag of Words(BOW) 和詞向量Word Embedding是最常見的兩種類型。

詞袋模型

       是n-gram語法模型的特例1元模型。該模型忽略掉文本的語法和語序等要素,將其僅僅看作是若干個詞彙的集合,文檔中每個單詞的出現都是獨立的。BOW使用一組無序的單詞(words)來表達一段文字或一個文檔。常見表示方法:one-hot,詞頻,tf-idf 等

import jieba
from gensim import corpora
from pprint import pprint

text = ['我喜歡吃蘋果',
        '我愛吃香蕉,不喜歡吃蘋果',
        '他不想吃桃子',
        '我想去上海玩',
        '她遊玩的地點在重慶',
        '他正在北京玩']
category = [1,1,1,2,2,2]
corpus = []
for t in text:
    corpus.append(list(jieba.cut(t)))
print('分詞後 :')
pprint(corpus)
print()

# 構造詞典
dic = corpora.Dictionary(corpus)
print('詞典: ',dic)
print('詞典token2id: ',dic.token2id)
print()

#向量化
corpus_vec= [dic.doc2bow(word) for word in corpus]
print('向量化:')
pprint(corpus_vec)
print()

outpt:

分詞後 :
[['我', '喜歡', '吃', '蘋果'],
 ['我', '愛', '吃', '香蕉', ',', '不', '喜歡', '吃', '蘋果'],
 ['他', '不想', '吃', '桃子'],
 ['我', '想', '去', '上海', '玩'],
 ['她', '遊玩', '的', '地點', '在', '重慶'],
 ['他', '正在', '北京', '玩']]

詞典:  Dictionary(23 unique tokens: ['吃', '喜歡', '我', '蘋果', ',']...)
詞典token2id:  {'吃': 0, '喜歡': 1, '我': 2, '蘋果': 3, ',': 4, '不': 5, '愛': 6, '香蕉': 7, '不想': 8, '他': 9, '桃子': 10, '上海': 11, '去': 12, '想': 13, '玩': 14, '在': 15, '地點': 16, '她': 17, '遊玩': 18, '的': 19, '重慶': 20, '北京': 21, '正在': 22}

向量化:
[[(0, 1), (1, 1), (2, 1), (3, 1)],
 [(0, 2), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)],
 [(0, 1), (8, 1), (9, 1), (10, 1)],
 [(2, 1), (11, 1), (12, 1), (13, 1), (14, 1)],
 [(15, 1), (16, 1), (17, 1), (18, 1), (19, 1), (20, 1)],
 [(9, 1), (14, 1), (21, 1), (22, 1)]]

從上面的例子,可以看到:

  • 向量中每個元素順序與原來文本中單詞出現的順序沒有關係,與詞典中的順序一一對應
  • 每個元組中的第一個元素對應字典中的詞彙ID,第二個元素對應該詞彙的計數
  • 向量的維度根據詞典中不重複詞的個數確定

One Hot表示,可以使用keras進行處理

from keras.preprocessing.text import Tokenizer
import jieba
from pprint import pprint

text = ['我喜歡吃蘋果',
        '我愛吃香蕉,不喜歡吃蘋果',
        '他不想吃桃子',
        '我想去上海玩',
        '她遊玩的地點在重慶',
        '他正在北京玩']
category = [1,1,1,2,2,2]
corpus = []
for t in text:
    corpus.append(" ".join(list(jieba.cut(t))))

tokenizer = Tokenizer()  # 創建一個分詞器(tokenizer),設置爲只考慮前1000個最常見的單詞
tokenizer.fit_on_texts(corpus)   # 構建索引單詞

sequences = tokenizer.texts_to_sequences(corpus)   # 將字符串轉換爲整數索引組成的列表
print('sequences :')
pprint(sequences)
print()

one_hot_results = tokenizer.texts_to_matrix(corpus, mode='binary') 
print('one hot :')
pprint(one_hot_results)
print()

word_index = tokenizer.word_index 
print('word index : ')
print(sorted(word_index.items(),key=lambda item:item[1]))

從上面的例子可知,一旦數據量上來了,詞袋模型的高維、稀疏、離散性,就會給模型的造成很大的困擾,矩陣的計算量非常龐大。改進的方式:採用詞的分佈式表示,如word2vec,Glove等

word2vec

        word2vec作爲神經概率語言模型的輸入,其本身其實是神經概率模型的副產品,是爲了通過神經網絡學習某個語言模型而產生的中間結果。具體來說,“某個語言模型”指的是“CBOW”和“Skip-gram”。

詳情原理,請參考一下鏈接

https://blog.csdn.net/itplus/article/details/37969979

實現

from gensim.models.word2vec import Word2Vec
import jieba
from pprint import pprint

text = ['我喜歡吃蘋果',
        '我愛吃香蕉,不喜歡吃蘋果',
        '他不想吃桃子',
        '我想去上海玩',
        '她遊玩的地點在重慶',
        '他正在北京玩']
corpus = []
for t in text:
    corpus.append(list(jieba.cut(t)))

cbow_model = Word2Vec(corpus,min_count=1,sg=0,iter=5,hs=1)    
skip_gram_model = Word2Vec(corpus,min_count=1,sg=1,iter=5,hs=1)

推薦文章:

https://zhuanlan.zhihu.com/p/53302305

推薦理由:深入淺出,一步步引導

 

 

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