[Python人工智能] 二十一.Word2Vec+CNN中文文本分類詳解及與機器學習算法對比(Python人工智能需要學什么)

      網友投稿 1112 2025-04-01

      TF-:https://github.com/eastmountyxz/AI-for-TensorFlow

      Keras-:https://github.com/eastmountyxz/AI-for-Keras

      博客-:https://github.com/eastmountyxz/CSDNBlog-AI-for-Python

      https://www.bilibili.com/video/BV1Zk4y1r7Gd

      文章目錄

      一.文本分類

      二.基于隨機森林的文本分類

      1.文本分類

      2.算法評價

      3.算法對比

      三.基于CNN的文本分類

      1.數據預處理

      2.特征提取及Word2Vec詞向量轉換

      3.CNN構建

      4.測試可視化

      四.總結

      華為云社區前文賞析:

      [Python人工智能] 一.TensorFlow2.0環境搭建及神經網絡入門

      [Python人工智能] 二.TensorFlow基礎及一元直線預測案例

      [Python人工智能] 三.TensorFlow基礎之Session、變量、傳入值和激勵函數

      [Python人工智能] 四.TensorFlow創建回歸神經網絡及Optimizer優化器

      [Python人工智能] 五.Tensorboard可視化基本用法及繪制整個神經網絡

      [Python人工智能] 六.TensorFlow實現分類學習及MNIST手寫體識別案例

      [Python人工智能] 七.什么是過擬合及dropout解決神經網絡中的過擬合問題

      [Python人工智能] 八.卷積神經網絡CNN原理詳解及TensorFlow編寫CNN

      [Python人工智能] 九.gensim詞向量Word2Vec安裝及《慶余年》中文短文本相似度計算

      [Python人工智能] 十.Tensorflow+Opencv實現CNN自定義圖像分類及與KNN圖像分類對比

      [Python人工智能] 十一.Tensorflow如何保存神經網絡參數

      [Python人工智能] 十二.循環神經網絡RNN和LSTM原理詳解及TensorFlow編寫RNN分類案例

      [Python人工智能] 十三.如何評價神經網絡、loss曲線圖繪制、圖像分類案例的F值計算

      [Python人工智能] 十四.循環神經網絡LSTM RNN回歸案例之sin曲線預測 丨【百變AI秀】

      [Python人工智能] 十五.無監督學習Autoencoder原理及聚類可視化案例詳解

      [Python人工智能] 十六.Keras環境搭建、入門基礎及回歸神經網絡案例

      [Python人工智能] 十七.Keras搭建分類神經網絡及MNIST數字圖像案例分析

      [Python人工智能] 十八.Keras搭建卷積神經網絡及CNN原理詳解

      [Python人工智能] 十九.Keras搭建循環神經網絡分類案例及RNN原理詳解

      [Python人工智能] 二十.基于Keras+RNN的文本分類vs基于傳統機器學習的文本分類

      [Python人工智能] 二十一.Word2Vec+CNN中文文本分類詳解及與機器學習算法對比

      一.文本分類

      文本分類旨在對文本集按照一定的分類體系或標準進行自動分類標記,屬于一種基于分類體系的自動分類。文本分類最早可以追溯到上世紀50年代,那時主要通過專家定義規則來進行文本分類;80年代出現了利用知識工程建立的專家系統;90年代開始借助于機器學習方法,通過人工特征工程和淺層分類模型來進行文本分類?,F在多采用詞向量以及深度神經網絡來進行文本分類。

      牛亞峰老師將傳統的文本分類流程歸納如下圖所示。在傳統的文本分類中,基本上大部分機器學習方法都在文本分類領域有所應用。主要包括:

      Naive Bayes

      KNN

      SVM

      隨機森林 \ 決策樹

      集合類方法

      最大熵

      神經網絡

      利用Keras框架進行文本分類的基本流程如下:

      步驟 1:文本的預處理,分詞->去除停用詞->統計選擇top n的詞做為特征詞

      步驟 2:為每個特征詞生成ID

      步驟 3:將文本轉化成ID序列,并將左側補齊

      步驟 4:訓練集shuffle

      步驟 5:Embedding Layer 將詞轉化為詞向量

      步驟 6:添加模型,構建神經網絡結構

      步驟 7:訓練模型

      步驟 8:得到準確率、召回率、F1值

      注意,如果使用TFIDF而非詞向量進行文檔表示,則直接分詞去停后生成TFIDF矩陣后輸入模型。本文將采用詞向量、TFIDF兩種方式進行實驗。

      在知乎史老師的“https://zhuanlan.zhihu.com/p/34212945”里總結歸類來說,基于深度學習的文本分類主要有5個大類別:

      詞嵌入向量化:word2vec, FastText等

      卷積神經網絡特征提取:TextCNN(卷積神經網絡)、Char-CNN等

      上下文機制:TextRNN(循環神經網絡)、BiRNN、BiLSTM、RCNN、TextRCNN(TextRNN+CNN)等

      記憶存儲機制:EntNet, DMN等

      注意力機制:HAN、TextRNN+Attention等

      推薦牛亞峰老師的文章:

      基于 word2vec 和 CNN 的文本分類 :綜述 & 實踐

      二.基于隨機森林的文本分類

      該部分主要圍繞常見的文本分類案例進行講解,由于隨機森林效果較好,故主要分享該方法。具體步驟包括:

      讀取CSV中文文本

      調用Jieba庫實現中文分詞及數據清洗

      特征提取采用TF-IDF或Word2Vec詞向量表示

      基于機器學習的分類

      準確率、召回率、F值計算及評估

      1.文本分類

      (1).數據集

      本文的數據為近期貴州黃果樹瀑布的旅游評論文本,來自大眾點評網,共有240條數據,其中差評數據114條,好評數據126條,如下圖所示:

      (2) 隨機森林文本分類

      本文不再詳細敘述代碼實現過程,前面很多文章都介紹過,并且源代碼有詳細的注釋供大家參考。

      # -*- coding:utf-8 -*- import csv import numpy as np import jieba import jieba.analyse from sklearn import feature_extraction from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfTransformer from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report from sklearn.ensemble import RandomForestClassifier #----------------------------------第一步 讀取文件-------------------------------- file = "data.csv" with open(file, "r", encoding="UTF-8") as f: # 使用csv.DictReader讀取文件中的信息 reader = csv.DictReader(f) labels = [] contents = [] for row in reader: # 數據元素獲取 if row['label'] == '好評': res = 0 else: res = 1 labels.append(res) content = row['content'] seglist = jieba.cut(content,cut_all=False) #精確模式 output = ' '.join(list(seglist)) #空格拼接 #print(output) contents.append(output) print(labels[:5]) print(contents[:5]) #----------------------------------第二步 數據預處理-------------------------------- # 將文本中的詞語轉換為詞頻矩陣 矩陣元素a[i][j] 表示j詞在i類文本下的詞頻 vectorizer = CountVectorizer() # 該類會統計每個詞語的tf-idf權值 transformer = TfidfTransformer() #第一個fit_transform是計算tf-idf 第二個fit_transform是將文本轉為詞頻矩陣 tfidf = transformer.fit_transform(vectorizer.fit_transform(contents)) for n in tfidf[:5]: print(n) #tfidf = tfidf.astype(np.float32) print(type(tfidf)) # 獲取詞袋模型中的所有詞語 word = vectorizer.get_feature_names() for n in word[:5]: print(n) print("單詞數量:", len(word)) # 將tf-idf矩陣抽取出來,元素w[i][j]表示j詞在i類文本中的tf-idf權重 X = tfidf.toarray() print(X.shape) # 使用 train_test_split 分割 X y 列表 # X_train矩陣的數目對應 y_train列表的數目(一一對應) -->> 用來訓練模型 # X_test矩陣的數目對應 (一一對應) -->> 用來測試模型的準確性 X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.3, random_state=1) #----------------------------------第三步 機器學習分類-------------------------------- # 隨機森林分類方法模型 # n_estimators:森林中樹的數量 clf = RandomForestClassifier(n_estimators=20) # 訓練模型 clf.fit(X_train, y_train) # 使用測試值 對 模型的準確度進行計算 print('模型的準確度:{}'.format(clf.score(X_test, y_test))) print("\n") # 預測結果 pre = clf.predict(X_test) print('預測結果:', pre[:10]) print(len(pre), len(y_test)) print(classification_report(y_test, pre))

      輸出結果如下圖所示,隨機森林的平均準確率為0.86,召回率為0.86,F值也為0.86。

      2.算法評價

      由于本文主要針對2分類問題,其實驗評估主要分為0和1兩類,完整代碼如下:

      # -*- coding:utf-8 -*- import csv import numpy as np import jieba import jieba.analyse from sklearn import feature_extraction from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfTransformer from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report from sklearn.ensemble import RandomForestClassifier #----------------------------------第一步 讀取文件-------------------------------- file = "data.csv" with open(file, "r", encoding="UTF-8") as f: # 使用csv.DictReader讀取文件中的信息 reader = csv.DictReader(f) labels = [] contents = [] for row in reader: # 數據元素獲取 if row['label'] == '好評': res = 0 else: res = 1 labels.append(res) content = row['content'] seglist = jieba.cut(content,cut_all=False) #精確模式 output = ' '.join(list(seglist)) #空格拼接 #print(output) contents.append(output) print(labels[:5]) print(contents[:5]) #----------------------------------第二步 數據預處理-------------------------------- # 將文本中的詞語轉換為詞頻矩陣 矩陣元素a[i][j] 表示j詞在i類文本下的詞頻 vectorizer = CountVectorizer() # 該類會統計每個詞語的tf-idf權值 transformer = TfidfTransformer() #第一個fit_transform是計算tf-idf 第二個fit_transform是將文本轉為詞頻矩陣 tfidf = transformer.fit_transform(vectorizer.fit_transform(contents)) for n in tfidf[:5]: print(n) #tfidf = tfidf.astype(np.float32) print(type(tfidf)) # 獲取詞袋模型中的所有詞語 word = vectorizer.get_feature_names() for n in word[:5]: print(n) print("單詞數量:", len(word)) # 將tf-idf矩陣抽取出來,元素w[i][j]表示j詞在i類文本中的tf-idf權重 X = tfidf.toarray() print(X.shape) # 使用 train_test_split 分割 X y 列表 # X_train矩陣的數目對應 y_train列表的數目(一一對應) -->> 用來訓練模型 # X_test矩陣的數目對應 (一一對應) -->> 用來測試模型的準確性 X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.3, random_state=1) #----------------------------------第三步 機器學習分類-------------------------------- # 隨機森林分類方法模型 # n_estimators:森林中樹的數量 clf = RandomForestClassifier(n_estimators=20) # 訓練模型 clf.fit(X_train, y_train) # 使用測試值 對 模型的準確度進行計算 print('模型的準確度:{}'.format(clf.score(X_test, y_test))) print("\n") # 預測結果 pre = clf.predict(X_test) print('預測結果:', pre[:10]) print(len(pre), len(y_test)) print(classification_report(y_test, pre)) #----------------------------------第四步 評價結果-------------------------------- def classification_pj(name, y_test, pre): print("算法評價:", name) # 正確率 Precision = 正確識別的個體總數 / 識別出的個體總數 # 召回率 Recall = 正確識別的個體總數 / 測試集中存在的個體總數 # F值 F-measure = 正確率 * 召回率 * 2 / (正確率 + 召回率) YC_B, YC_G = 0,0 #預測 bad good ZQ_B, ZQ_G = 0,0 #正確 CZ_B, CZ_G = 0,0 #存在 #0-good 1-bad 同時計算防止類標變化 i = 0 while i

      輸出結果如下圖所示,其中好評的準確率、召回率、F值分別為0.9268、0.9268、0.9268,差評的準確率、召回率、F值分別為0.9032、0.9032、0.9032。

      3.算法對比

      # -*- coding:utf-8 -*- import csv import numpy as np import jieba import jieba.analyse from sklearn import feature_extraction from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfTransformer from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report from sklearn.ensemble import RandomForestClassifier from sklearn.tree import DecisionTreeClassifier from sklearn import svm from sklearn import neighbors from sklearn.naive_bayes import MultinomialNB from sklearn.linear_model import LogisticRegression #----------------------------------第一步 讀取文件-------------------------------- file = "data.csv" with open(file, "r", encoding="UTF-8") as f: # 使用csv.DictReader讀取文件中的信息 reader = csv.DictReader(f) labels = [] contents = [] for row in reader: # 數據元素獲取 if row['label'] == '好評': res = 0 else: res = 1 labels.append(res) content = row['content'] seglist = jieba.cut(content,cut_all=False) #精確模式 output = ' '.join(list(seglist)) #空格拼接 #print(output) contents.append(output) print(labels[:5]) print(contents[:5]) #----------------------------------第二步 數據預處理-------------------------------- # 將文本中的詞語轉換為詞頻矩陣 矩陣元素a[i][j] 表示j詞在i類文本下的詞頻 vectorizer = CountVectorizer() # 該類會統計每個詞語的tf-idf權值 transformer = TfidfTransformer() #第一個fit_transform是計算tf-idf 第二個fit_transform是將文本轉為詞頻矩陣 tfidf = transformer.fit_transform(vectorizer.fit_transform(contents)) for n in tfidf[:5]: print(n) #tfidf = tfidf.astype(np.float32) print(type(tfidf)) # 獲取詞袋模型中的所有詞語 word = vectorizer.get_feature_names() for n in word[:5]: print(n) print("單詞數量:", len(word)) # 將tf-idf矩陣抽取出來,元素w[i][j]表示j詞在i類文本中的tf-idf權重 X = tfidf.toarray() print(X.shape) # 使用 train_test_split 分割 X y 列表 # X_train矩陣的數目對應 y_train列表的數目(一一對應) -->> 用來訓練模型 # X_test矩陣的數目對應 (一一對應) -->> 用來測試模型的準確性 X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.3, random_state=1) #----------------------------------第四步 評價結果-------------------------------- def classification_pj(name, y_test, pre): print("算法評價:", name) # 正確率 Precision = 正確識別的個體總數 / 識別出的個體總數 # 召回率 Recall = 正確識別的個體總數 / 測試集中存在的個體總數 # F值 F-measure = 正確率 * 召回率 * 2 / (正確率 + 召回率) YC_B, YC_G = 0,0 #預測 bad good ZQ_B, ZQ_G = 0,0 #正確 CZ_B, CZ_G = 0,0 #存在 #0-good 1-bad 同時計算防止類標變化 i = 0 while i

      輸出結果如下所示,發現貝葉斯算法在文本分類中的效果還是很棒;同時隨機森林、邏輯回歸、SVM效果都還不錯。

      完整結果如下:

      隨機森林分類 precision recall f1-score support 0 0.92 0.88 0.90 41 1 0.85 0.90 0.88 31 accuracy 0.89 72 macro avg 0.89 0.89 0.89 72 weighted avg 0.89 0.89 0.89 72 算法評價: RandomForest 28 36 33 39 31 41 Precision Good 0:0.9231 Precision Bad 1:0.8485 Avg_precision:0.8858 Recall Good 0:0.8780 Recall Bad 1:0.9032 Avg_recall:0.8906 F-measure Good 0:0.9000 F-measure Bad 1:0.8750 Avg_fmeasure:0.8875 決策樹分類 precision recall f1-score support 0 0.81 0.73 0.77 41 1 0.69 0.77 0.73 31 accuracy 0.75 72 macro avg 0.75 0.75 0.75 72 weighted avg 0.76 0.75 0.75 72 算法評價: DecisionTree 24 30 35 37 31 41 Precision Good 0:0.8108 Precision Bad 1:0.6857 Avg_precision:0.7483 Recall Good 0:0.7317 Recall Bad 1:0.7742 Avg_recall:0.7530 F-measure Good 0:0.7692 F-measure Bad 1:0.7273 Avg_fmeasure:0.7483 支持向量機分類 最近鄰分類 樸素貝葉斯分類 邏輯回歸分類 ......

      三.基于CNN的文本分類

      接著我們開始通過CNN實現文本分類,該方法可以應用于很多領域,只要有數據集即可分析。這里僅給出最基礎且可用的方法及源碼,希望對您有所幫助。

      1.數據預處理

      上一部分我在寫機器學習文本分類時,已經介紹了中文分詞等預處理操作,為什么這部分還要介紹呢?因為這里我要增加兩個新的操作:

      去停用詞

      詞性標注

      這兩個操作在文本挖掘過程中非常重要,它一方面能提升我們的分類效果,另一方面能過濾掉無關的特征詞,詞性標注也能輔助我們進行其他的分析,如情感分析、輿情挖掘等。

      [Python人工智能] 二十一.Word2Vec+CNN中文文本分類詳解及與機器學習算法對比(python人工智能需要學什么)

      該部分代碼如下:

      # -*- coding:utf-8 -*- import csv import numpy as np import jieba import jieba.analyse import jieba.posseg as pseg from sklearn import feature_extraction from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfTransformer from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report #----------------------------------第一步 數據預處理-------------------------------- file = "data.csv" # 獲取停用詞 def stopwordslist(): #加載停用詞表 stopwords = [line.strip() for line in open('stop_words.txt', encoding="UTF-8").readlines()] return stopwords # 去除停用詞 def deleteStop(sentence): stopwords = stopwordslist() outstr = "" for i in sentence: # print(i) if i not in stopwords and i!="\n": outstr += i return outstr # 中文分詞 Mat = [] with open(file, "r", encoding="UTF-8") as f: # 使用csv.DictReader讀取文件中的信息 reader = csv.DictReader(f) labels = [] contents = [] for row in reader: # 數據元素獲取 if row['label'] == '好評': res = 0 else: res = 1 labels.append(res) # 中文分詞 content = row['content'] #print(content) seglist = jieba.cut(content,cut_all=False) #精確模式 #print(seglist) # 去停用詞 stc = deleteStop(seglist) #注意此時句子無空格 # 空格拼接 seg_list = jieba.cut(stc,cut_all=False) output = ' '.join(list(seg_list)) #print(output) contents.append(output) # 詞性標注 res = pseg.cut(stc) seten = [] for word,flag in res: if flag not in ['nr','ns','nt','mz','m','f','ul','l','r','t']: seten.append(word) Mat.append(seten) print(labels[:5]) print(contents[:5]) print(Mat[:5]) # 文件寫入 fileDic = open('wordCut.txt', 'w', encoding="UTF-8") for i in Mat: fileDic.write(" ".join(i)) fileDic.write('\n') fileDic.close() words = [line.strip().split(" ") for line in open('WordCut.txt',encoding='UTF-8').readlines()] print(words[:5])

      運行結果如下圖所示,可以看到原文本被分詞,并且過濾掉了“還”、“,”、“常?!钡韧S迷~,并且以兩種形式呈現,讀者可以結合自己的需要進行后續分析。同時,將分詞后的文本也寫入到wordCut.txt文件中。

      contents:顯示已分詞且以列表形式存在的句子

      Mat:顯示已分詞且以列表形式存在的詞序列

      2.特征提取及Word2Vec詞向量轉換

      (1) 特征詞編號

      首先,我們先調用Tokenizer和fit_on_texts函數將文本中的每個詞編號,詞頻出現越高其編號越小。如下圖所示,“瀑布”、“景區”、“排隊”、“水簾洞”等特征詞出現較多,注意空格、“評論”、“收起”可以繼續過濾掉,在停用詞表中添加即可。

      #fit_on_texts函數可以將輸入的文本每個詞編號 編號根據詞頻(詞頻越大編號越小) tokenizer = Tokenizer() tokenizer.fit_on_texts(Mat) vocab = tokenizer.word_index #停用詞已過濾,獲取每個詞的編號 print(vocab)

      輸出結果如下圖所示:

      (2) Word2Vec詞向量訓練

      獲取了特征詞編號即將特征矩陣的表頭定義好了,接下來我們需要將每一行文本轉換成一維詞向量,最終構建特征矩陣,用于訓練和分類。注意,利用pad_sequences方法將CNN訓練的長度統一,更好地進行訓練。比如設置為100,如果句子超過100后面的單詞會被切掉;如果句子未超過100,則會在句子前面補0,下圖展示了補0過程。同時,分類結果[0,1]表示類標是好評0,[1,0]表示類標是差評1。

      此時的完整代碼如下:

      # 使用 train_test_split 分割 X y 列表 X_train, X_test, y_train, y_test = train_test_split(Mat, labels, test_size=0.3, random_state=1) print(X_train[:5]) print(y_train[:5]) #----------------------------------第三步 詞向量構建-------------------------------- # Word2Vec訓練 maxLen = 100 #詞序列最大長度 num_features = 100 #設置詞語向量維度 min_word_count = 3 #保證被考慮詞語的最低頻度 num_workers = 4 #設置并行化訓練使用CPU計算核心數量 context = 4 #設置詞語上下文窗口大小 # 設置模型 model = word2vec.Word2Vec(Mat, workers=num_workers, size=num_features, min_count=min_word_count,window=context) # 強制單位歸一化 model.init_sims(replace=True) # 輸入一個路徑保存訓練模型 其中./data/model目錄事先存在 model.save("CNNw2vModel") model.wv.save_word2vec_format("CNNVector",binary=False) print(model) # 加載模型 如果word2vec已訓練好直接用下面語句 w2v_model = word2vec.Word2Vec.load("CNNw2vModel") # 特征編號(不足的前面補0) trainID = tokenizer.texts_to_sequences(X_train) print(trainID) testID = tokenizer.texts_to_sequences(X_test) print(testID) # 該方法會讓CNN訓練的長度統一 trainSeq = pad_sequences(trainID, maxlen=maxLen) print(trainSeq) # 標簽獨熱編碼 轉換為one-hot編碼 trainCate = to_categorical(y_train, num_classes=2) #二分類問題 print(trainCate) testCate = to_categorical(y_test, num_classes=2) #二分類問題 print(testCate)

      輸出結果如下:

      [['景色', ' ', '景區', '太', '成熟', '從', '大', '瀑布', '景區', '出發', '景區', '觀光車', '足足', '游客', '半小時', '世博會', '路上', '摩肩接踵', '欣賞', '美景', '心情', '觀光車', '上車', '處', '標明', '目的地', '入口處', '引導', '走', '冤枉路', '稀里糊涂', '上車', '問', '司機', '到達', '司機', '含糊地', '說', '開出', '景區', '客運站', '七孔', '景區', '開發', '完美', '收起', '評論'], ['淡季', '瀑布', '人', '少', '景美', '機票', '便宜', '值得', '去'], ['瀑布', '體驗', '差', '五星', '好評', '全', '是', '刷', '道路', '很窄', '導致', '大面積', '堵塞', '排隊', '崩潰', '景區', '指引', '清晰', '排隊', '大雨', '遮雨', '設計', '搞', '大人', '小孩', '老人', '淋雨', '景區', '接待', '能力差', '瀑布', '真的', '徒有虛名', '七孔', '收起', '評論'], ['老爸', '分', '瀑布', '瀑布', '瀑布', '游覽', '瀑布', '門票', '反正', '超過', ' ', '來到', '熟悉', '告知', '只能', '出', '進入', '口', '回到', '高速', '出口', '直行', '回去', '倒', '指示', '清晰', '隔離', '欄桿', '自駕車', '導進', '停車場', '停車場', '收費', '且', '時間', ' ', '停車場', '經查', '景區', '門票', '單人', '含', '交通', '車費', '交通車', '需', '另付', '從外', '圍繞', '路', '花', '不到', '分鐘', '車費', '真心', '接受', ' ', '全家人', '不想', '┐', '(', '─', '__', '─', ')', '┌', '利益', '勾結', '劇烈', '漲費', '個金', '瀑布', '好看', '差', '評', ' ', '圖片', '未', '開發', '瀑布', '天坑', '瀑布', '壯觀', '壯觀', '有', '靈秀', '景區', '膨脹', '成', '收起', '評論'], ['全家', '票', '居民', '專享', '優惠', '票']] [1, 0, 1, 1, 1] Word2Vec(vocab=718, size=100, alpha=0.025) [[ 0 0 0 ... 2481 5 4] [ 0 0 0 ... 570 52 90] [ 0 0 0 ... 187 5 4] ... [ 0 0 0 ... 93 5 4] [ 0 0 0 ... 30 5 4] [ 0 0 0 ... 81 18 78]] [[0. 1.] [1. 0.] [0. 1.] [0. 1.] [0. 1.] [0. 1.] [1. 0.]

      3.CNN構建

      接下來我們開始將構建好的特征矩陣拿去訓練,計算不同文本或一維矩陣的相似度,這樣會將好評和差評的不同句子按相似度分成兩類。這里同樣使用Word2Vec實現核心代碼如下:

      model = word2vec.Word2Vec( Mat, workers=num_workers, size=num_features, min_count=min_word_count, window=context );

      訓練模型的結果為“Word2Vec(vocab=718, size=100, alpha=0.025)”,這里設置的過濾頻度為3,相當于出現頻率低于3的被過濾,最終得到718個特征詞。num_features值為100,表示是100維的詞向量。sg默認為連續詞袋模型,也可以設置為1跳字模型。默認的優化方法負采樣,更多參數解釋請讀者百度。

      [Python人工智能] 九.gensim詞向量Word2Vec安裝及《慶余年》中文短文本相似度計算

      如果我們存在一個訓練集、一個測試集,如果測試集中不存在某個特征詞,怎么解決呢?這里我們在獲取某個特征詞的詞向量,并轉換為訓練矩陣時,使用了try-except異常捕獲,如果未找到特征詞則跳過即可,它會自動補0。

      該部分代碼如下所示:

      #----------------------------------第四步 CNN構建-------------------------------- # 利用訓練后的Word2vec自定義Embedding的訓練矩陣 每行代表一個詞(結合獨熱編碼和矩陣乘法理解) embedding_matrix = np.zeros((len(vocab)+1, 100)) #從0開始計數 加1對應之前特征詞 for word, i in vocab.items(): try: #提取詞向量并放置訓練矩陣 embedding_vector = w2v_model[str(word)] embedding_matrix[i] = embedding_vector except KeyError: #單詞未找到跳過 continue # 訓練模型 main_input = Input(shape=(maxLen,), dtype='float64') # 詞嵌入 使用預訓練Word2Vec的詞向量 自定義權重矩陣 100是輸出詞向量維度 embedder = Embedding(len(vocab)+1, 100, input_length=maxLen, weights=[embedding_matrix], trainable=False) #不再訓練 # 建立模型 model = Sequential() model.add(embedder) #構建Embedding層 model.add(Conv1D(256, 3, padding='same', activation='relu')) #卷積層步幅3 model.add(MaxPool1D(maxLen-5, 3, padding='same')) #池化層 model.add(Conv1D(32, 3, padding='same', activation='relu')) #卷積層 model.add(Flatten()) #拉直化 model.add(Dropout(0.3)) #防止過擬合 30%不訓練 model.add(Dense(256, activation='relu')) #全連接層 model.add(Dropout(0.2)) #防止過擬合 model.add(Dense(units=2, activation='softmax')) #輸出層 # 模型可視化 model.summary() # 激活神經網絡 model.compile(optimizer = 'adam', #優化器 loss = 'categorical_crossentropy', #損失 metrics = ['accuracy'] #計算誤差或準確率 ) #訓練(訓練數據、訓練類標、batch—size每次256條訓練、epochs、隨機選擇、驗證集20%) history = model.fit(trainSeq, trainCate, batch_size=256, epochs=6, validation_split=0.2) model.save("TextCNN") #----------------------------------第五步 預測模型-------------------------------- # 預測與評估 mainModel = load_model("TextCNN") result = mainModel.predict(testSeq) #測試樣本 #print(result) print(np.argmax(result,axis=1)) score = mainModel.evaluate(testSeq, testCate, batch_size=32) print(score)

      構建的模型如下:

      Model: "sequential_1" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding_2 (Embedding) (None, 100, 100) 290400 _________________________________________________________________ conv1d_1 (Conv1D) (None, 100, 256) 77056 _________________________________________________________________ max_pooling1d_1 (MaxPooling1 (None, 34, 256) 0 _________________________________________________________________ conv1d_2 (Conv1D) (None, 34, 32) 24608 _________________________________________________________________ flatten_1 (Flatten) (None, 1088) 0 _________________________________________________________________ dropout_1 (Dropout) (None, 1088) 0 _________________________________________________________________ dense_1 (Dense) (None, 256) 278784 _________________________________________________________________ dropout_2 (Dropout) (None, 256) 0 _________________________________________________________________ dense_2 (Dense) (None, 2) 514 ================================================================= Total params: 671,362 Trainable params: 380,962 Non-trainable params: 290,400

      4.測試可視化

      最后增加可視化代碼,繪制圖形如下圖所示。再次強調,該算法效果確實不理想,誤差不是逐漸遞減,正確率也不是不斷升高。如果讀者發現原因或優化方法也懇請您告知,謝謝。

      最后附上完整代碼:

      # -*- coding:utf-8 -*- import csv import numpy as np import jieba import jieba.analyse import jieba.posseg as pseg from sklearn import feature_extraction from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfTransformer from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report from keras import models from keras import layers from keras import Input from gensim.models import word2vec from keras.preprocessing.text import Tokenizer from keras.utils.np_utils import to_categorical from keras.preprocessing.sequence import pad_sequences from keras.models import Model from keras.models import Sequential from keras.models import load_model from keras.layers import Flatten, Dense, Dropout, Conv1D, MaxPool1D, Embedding #----------------------------------第一步 數據預處理-------------------------------- file = "data.csv" # 獲取停用詞 def stopwordslist(): #加載停用詞表 stopwords = [line.strip() for line in open('stop_words.txt', encoding="UTF-8").readlines()] return stopwords # 去除停用詞 def deleteStop(sentence): stopwords = stopwordslist() outstr = "" for i in sentence: # print(i) if i not in stopwords and i!="\n": outstr += i return outstr # 中文分詞 Mat = [] with open(file, "r", encoding="UTF-8") as f: # 使用csv.DictReader讀取文件中的信息 reader = csv.DictReader(f) labels = [] contents = [] for row in reader: # 數據元素獲取 if row['label'] == '好評': res = 0 else: res = 1 labels.append(res) # 中文分詞 content = row['content'] #print(content) seglist = jieba.cut(content,cut_all=False) #精確模式 #print(seglist) # 去停用詞 stc = deleteStop(seglist) #注意此時句子無空格 # 空格拼接 seg_list = jieba.cut(stc,cut_all=False) output = ' '.join(list(seg_list)) #print(output) contents.append(output) # 詞性標注 res = pseg.cut(stc) seten = [] for word,flag in res: if flag not in ['nr','ns','nt','mz','m','f','ul','l','r','t']: #print(word,flag) seten.append(word) Mat.append(seten) print(labels[:5]) print(contents[:5]) print(Mat[:5]) #----------------------------------第二步 特征編號-------------------------------- # fit_on_texts函數可以將輸入的文本每個詞編號 編號根據詞頻(詞頻越大編號越小) tokenizer = Tokenizer() tokenizer.fit_on_texts(Mat) vocab = tokenizer.word_index #停用詞已過濾,獲取每個詞的編號 print(vocab) # 使用 train_test_split 分割 X y 列表 X_train, X_test, y_train, y_test = train_test_split(Mat, labels, test_size=0.3, random_state=1) print(X_train[:5]) print(y_train[:5]) #----------------------------------第三步 詞向量構建-------------------------------- # Word2Vec訓練 maxLen = 100 #詞序列最大長度 num_features = 100 #設置詞語向量維度 min_word_count = 3 #保證被考慮詞語的最低頻度 num_workers = 4 #設置并行化訓練使用CPU計算核心數量 context = 4 #設置詞語上下文窗口大小 # 設置模型 model = word2vec.Word2Vec(Mat, workers=num_workers, size=num_features, min_count=min_word_count,window=context) # 強制單位歸一化 model.init_sims(replace=True) # 輸入一個路徑保存訓練模型 其中./data/model目錄事先存在 model.save("CNNw2vModel") model.wv.save_word2vec_format("CNNVector",binary=False) print(model) # 加載模型 如果word2vec已訓練好直接用下面語句 w2v_model = word2vec.Word2Vec.load("CNNw2vModel") # 特征編號(不足的前面補0) trainID = tokenizer.texts_to_sequences(X_train) print(trainID) testID = tokenizer.texts_to_sequences(X_test) print(testID) # 該方法會讓CNN訓練的長度統一 trainSeq = pad_sequences(trainID, maxlen=maxLen) print(trainSeq) testSeq = pad_sequences(testID, maxlen=maxLen) print(testSeq) # 標簽獨熱編碼 轉換為one-hot編碼 trainCate = to_categorical(y_train, num_classes=2) #二分類問題 print(trainCate) testCate = to_categorical(y_test, num_classes=2) #二分類問題 print(testCate) #----------------------------------第四步 CNN構建-------------------------------- # 利用訓練后的Word2vec自定義Embedding的訓練矩陣 每行代表一個詞(結合獨熱編碼和矩陣乘法理解) embedding_matrix = np.zeros((len(vocab)+1, 100)) #從0開始計數 加1對應之前特征詞 for word, i in vocab.items(): try: #提取詞向量并放置訓練矩陣 embedding_vector = w2v_model[str(word)] embedding_matrix[i] = embedding_vector except KeyError: #單詞未找到跳過 continue # 訓練模型 main_input = Input(shape=(maxLen,), dtype='float64') # 詞嵌入 使用預訓練Word2Vec的詞向量 自定義權重矩陣 100是輸出詞向量維度 embedder = Embedding(len(vocab)+1, 100, input_length=maxLen, weights=[embedding_matrix], trainable=False) #不再訓練 # 建立模型 model = Sequential() model.add(embedder) #構建Embedding層 model.add(Conv1D(256, 3, padding='same', activation='relu')) #卷積層步幅3 model.add(MaxPool1D(maxLen-5, 3, padding='same')) #池化層 model.add(Conv1D(32, 3, padding='same', activation='relu')) #卷積層 model.add(Flatten()) #拉直化 model.add(Dropout(0.3)) #防止過擬合 30%不訓練 model.add(Dense(256, activation='relu')) #全連接層 model.add(Dropout(0.2)) #防止過擬合 model.add(Dense(units=2, activation='softmax')) #輸出層 # 模型可視化 model.summary() # 激活神經網絡 model.compile(optimizer = 'adam', #優化器 loss = 'categorical_crossentropy', #損失 metrics = ['accuracy'] #計算誤差或準確率 ) #訓練(訓練數據、訓練類標、batch—size每次256條訓練、epochs、隨機選擇、驗證集20%) history = model.fit(trainSeq, trainCate, batch_size=256, epochs=6, validation_split=0.2) model.save("TextCNN") #----------------------------------第五步 預測模型-------------------------------- # 預測與評估 mainModel = load_model("TextCNN") result = mainModel.predict(testSeq) #測試樣本 print(result) print(np.argmax(result,axis=1)) score = mainModel.evaluate(testSeq, testCate, batch_size=32) print(score) #----------------------------------第五步 可視化-------------------------------- import matplotlib.pyplot as plt plt.plot(history.history['accuracy']) plt.plot(history.history['val_accuracy']) plt.title('Model accuracy') plt.ylabel('Accuracy') plt.xlabel('Epoch') plt.legend(['Train','Valid'], loc='upper left') plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('Model loss') plt.ylabel('Loss') plt.xlabel('Epoch') plt.legend(['Train','Valid'], loc='upper left') plt.show()

      四.總結

      寫道這里,這篇文章就結束了。希望對您有所幫助,同時文章中不足或錯誤的地方,歡迎讀者提出。這些實驗都是我在做論文研究或項目評價常見的一些問題,希望讀者帶著這些問題,結合自己的需求進行深入的思考,更希望大家能學以致用。最后如果文章對您有幫助,請、評論、,這將是我分享最大的動力。

      總之,本文通過Keras實現了一個CNN文本分類學習的案例,并詳細介紹了文本分類原理知識及與機器學習對比。最后,作為人工智能的菜鳥,我希望自己能不斷進步并深入,后續將它應用于圖像識別、網絡安全、對抗樣本等領域,指導大家撰寫簡單的學術論文,一起加油!感謝這些年遇到很多以前進步的博友,共勉~

      感恩能與大家在華為云遇見!

      希望能與大家一起在華為云社區共同成長。原文地址:https://blog.csdn.net/Eastmount/article/details/107004660

      (By:娜璋之家 Eastmount 2021-12-29 夜于武漢)

      Python 機器學習 深度學習 神經網絡

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:wps如何制作行業統計圖表
      下一篇:excel2003制作甘特圖的方法圖解步驟
      相關文章
      91精品国产亚洲爽啪在线观看| 无码欧精品亚洲日韩一区夜夜嗨| 亚洲精品美女久久久久久久| 亚洲精品福利网泷泽萝拉| 亚洲AV午夜成人影院老师机影院| 亚洲中文字幕无码一区| 亚洲精品国产精品乱码不卞| 伊人久久亚洲综合影院| 爱情岛亚洲论坛在线观看| 国产大陆亚洲精品国产| 亚洲?V无码乱码国产精品| 一本久到久久亚洲综合| 亚洲欧洲中文日韩av乱码| 亚洲区不卡顿区在线观看| 国外亚洲成AV人片在线观看| 久久久久国产亚洲AV麻豆| 亚洲无线码在线一区观看| 久久精品国产亚洲av成人| 亚洲毛片在线观看| 亚洲精品欧洲精品| 国产成人精品亚洲2020| 亚洲乱妇熟女爽到高潮的片 | 亚洲日本在线电影| 亚洲欧美日韩久久精品| 亚洲依依成人亚洲社区| 亚洲av乱码一区二区三区按摩| 久久无码av亚洲精品色午夜| 亚洲A∨午夜成人片精品网站| 久久久久亚洲av成人无码电影| 国产gv天堂亚洲国产gv刚刚碰| 亚洲精品无码高潮喷水在线| 亚洲av片劲爆在线观看| 亚洲精品动漫在线| 一区二区亚洲精品精华液| 日韩国产欧美亚洲v片| 亚洲精品无码你懂的网站| 亚洲码国产精品高潮在线| 亚洲视频在线播放| 亚洲av一本岛在线播放| 亚洲JLZZJLZZ少妇| 久久亚洲精品无码观看不卡|