1.總結(jié)
預(yù)測(cè)類數(shù)據(jù)分析項(xiàng)目
流程 | 具體操作 |
---|---|
基本查看 | 查看缺失值(可以用直接查看方式isnull、圖像查看方式查看缺失值missingno)、查看數(shù)值類型特征與非數(shù)值類型特征、一次性繪制所有特征的分布圖像 |
預(yù)處理 | 缺失值處理(填充)拆分?jǐn)?shù)據(jù)(獲取有需要的值) 、統(tǒng)一數(shù)據(jù)格式、特征工程(特征編碼、0/1字符轉(zhuǎn)換、自定義) 、特征衍生、降維(特征相關(guān)性、PCA降維) |
數(shù)據(jù)分析 | groupby分組求最值數(shù)據(jù)、seaborn可視化 |
預(yù)測(cè) | 拆分?jǐn)?shù)據(jù)集、建立模型(機(jī)器學(xué)習(xí):RandomForestRegressor、LogisticRegression、GradientBoostingRegressor、RandomForest)、訓(xùn)練模型、預(yù)測(cè)、評(píng)估模型(ROC曲線、MSE、MAE、RMSE、R2)、調(diào)參(GridSearchCV) |
數(shù)量查看:條形圖
占比查看:餅圖
數(shù)據(jù)分區(qū)分布查看:概率密度函數(shù)圖
查看相關(guān)關(guān)系:條形圖、熱力圖
分布分析:分類直方圖(countplot)、分布圖-帶有趨勢(shì)線的直方圖(distplot)
自然語(yǔ)言處理項(xiàng)目:
流程 | 具體操作 |
---|---|
基本查看 | 導(dǎo)入數(shù)據(jù) 、獲取數(shù)據(jù)轉(zhuǎn)換為列表、 |
預(yù)處理 | 刪除空值、關(guān)鍵詞抽?。ɑ?TF-IDF、基于TextRank )、分詞(jieba) 、關(guān)鍵詞匹配(詞袋模型)、處理分詞結(jié)果(刪除特殊字符、去除停用詞) |
數(shù)據(jù)可視化(繪制詞云圖) | 分組統(tǒng)計(jì)數(shù)量、訓(xùn)練模型(學(xué)習(xí)詞頻信息)、使用自定義背景圖、繪制詞云圖 |
建模(文本分類) | 文本分類(LDA模型)、機(jī)器學(xué)習(xí)(樸素貝葉斯)、深度學(xué)習(xí)(cnn、LSTM、GRU) |
2.項(xiàng)目介紹
前置知識(shí)
了解自然語(yǔ)言處理,熟悉相關(guān)自然語(yǔ)言處理包,TF-IDF算法、LDA主題模型、CNN、LSTM等深度學(xué)習(xí)知識(shí)
主要內(nèi)容
- 自然語(yǔ)言處理(NLP)
分詞、詞袋模型、機(jī)器學(xué)習(xí)、深度學(xué)習(xí) - 講解順序
詞云、文本分析、文本分類
注意
本項(xiàng)目的文本是針對(duì)中文處理,所以難度上比英文處理大。因?yàn)橛⑽氖强靠崭穹珠_每個(gè)詞語(yǔ),但是中文并沒有這樣的規(guī)律。
3.詞云介紹
“詞云”就是對(duì)文本中出現(xiàn)頻率較高的“關(guān)鍵詞”予以視覺上的突出,形成“關(guān)鍵詞云層”或“關(guān)鍵詞渲染”,從而過濾掉大量的文本信息,使瀏覽者只要一眼掃過文本就可以領(lǐng)略文本的主旨
中文文本處理
- 分詞
通過中文分詞包進(jìn)行分詞,其中jieba是優(yōu)秀的中文分詞第三方庫(kù)
安裝方式:pip install jieba - 處理分詞結(jié)果
刪除特殊字符、去除停用詞等 - 統(tǒng)計(jì)詞頻
- 做詞云
wordcloud是優(yōu)秀的詞云展示第三方庫(kù),以詞語(yǔ)為基本單位,
通過圖形可視化的方式,更加直觀和藝術(shù)的展示文本
安裝方式:pip install wordcloud - 自定義背景圖做詞云
通過imageio讀取背景圖
安裝方式:pip install imageio
4.數(shù)據(jù)預(yù)處理
4.1 分詞
import warnings
warnings.filterwarnings("ignore") # 忽略警告信息
import jieba # 分詞包
from wordcloud import WordCloud # 詞云包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib
matplotlib.rcParams['figure.figsize'] = (10.0,5.0)
# 1.讀取數(shù)據(jù)
df = pd.read_csv('./data/entertainment_news.csv',encoding='gbk')
# 解決報(bào)錯(cuò):ParserError: Error tokenizing data. C error: Expected 1 fields in line 12, saw 2
# 當(dāng)我們使用read_csv讀取txt文本文件時(shí)候,需要添加quoting=3和names指定列的參數(shù),若還是不行則error_bad_lines=False
stopwords = pd.read_csv('./data/stopwords.txt',quoting=3, names=['stopword'],error_bad_lines=False)
# 2.數(shù)據(jù)查看
df
stopwords
# 2.數(shù)據(jù)預(yù)處理
# 刪除空數(shù)據(jù)
df = df.dropna()
content = df.content.values.tolist()
content[0]
# 測(cè)試分詞
jieba.lcut(content[0])
# 測(cè)試后發(fā)現(xiàn),存在一些空格、換行、標(biāo)點(diǎn)符號(hào)等是不需要的
# 正式開始分詞
segment = []
# 遍歷每一行娛樂新聞數(shù)據(jù)
for line in content:
try:
segs = jieba.lcut(line) # 對(duì)每一條娛樂新聞進(jìn)行分詞
for seg in segs:
# 只有長(zhǎng)度大于1的字符并且該字符不能為空格換行,這樣的詞語(yǔ)才認(rèn)為是有效分詞
if len(seg) > 1 and seg!='\r\n':
segment.append(seg)
except:
print(line)
continue
# 新建DataFrame,存儲(chǔ)原始的分詞結(jié)果
words_df = pd.DataFrame({'segment':segment})
# 去除停用詞語(yǔ)
words_df = words_df[~words_df.segment.isin(stopwords.stopword)]
words_df.head(100)
4.2 統(tǒng)計(jì)詞頻
words_stat = words_df.groupby(by='segment')['segment'].agg([('計(jì)數(shù)','count')])
words_stat = words_stat.reset_index().sort_values(by=['計(jì)數(shù)'],ascending=False)
words_stat
4.3 關(guān)鍵詞抽取
4.3.1 基于 TF-IDF 算法的關(guān)鍵詞抽取
TF-IDF的思想:如果一個(gè)詞或短語(yǔ)在一篇文章中出現(xiàn)的概率高,并且在其他文章中很少出現(xiàn),則認(rèn)為該詞或短語(yǔ)具有很好的類別區(qū)分能力,適合用來分類
TF-IDF的作用:評(píng)估一個(gè)詞語(yǔ)對(duì)于語(yǔ)料庫(kù)中的某個(gè)文檔的重要程度
詞頻:(term frequency,tf):某個(gè)詞語(yǔ)在文檔中的出現(xiàn)頻率? 逆文檔頻率(inverse document frequency,idf)某個(gè)詞的普遍重要性的度量。由總文檔數(shù)量除以包含該詞的文檔數(shù)量,再將得到的商取以10為底的對(duì)數(shù) TF-IDF = TF x IDF
import jieba.analyse
jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
參數(shù):
- sentence 為待提取的文本
- topK 為返回幾個(gè) TF-IDF 權(quán)重最大的關(guān)鍵詞,默認(rèn)值為 20
- withWeight 是否一并返回關(guān)鍵詞權(quán)重值,默認(rèn)值為 False
- allowPOS 僅包括指定詞性的詞,默認(rèn)值為空,即不篩選
import jieba.analyse as analyse
df = pd.read_csv('data/technology_news.csv',encoding='gbk')
df = df.dropna()
# 獲取每一行信息,轉(zhuǎn)化為列表
lines = df.content.values.tolist()
# 使用空字符串連接列表中的每一行內(nèi)容
content = "".join(lines)
# 打印前30個(gè)TF-IDF得到的關(guān)鍵詞
print(analyse.extract_tags(content, topK=30))
4.3.2 基于 TextRank 算法的關(guān)鍵詞抽取
jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) 直接使用,接口相同,注意默認(rèn)過濾詞性
算法論文: TextRank: Bringing Order into Texts
基本思想:
- 將待抽取關(guān)鍵詞的文本進(jìn)行分詞
- 以固定窗口大小(默認(rèn)為5,通過span屬性調(diào)整),詞之間的共現(xiàn)關(guān)系,構(gòu)建圖
- 計(jì)算圖中節(jié)點(diǎn)的PageRank
import jieba.analyse as analyse
# 讀取軍事新聞數(shù)據(jù)
df = pd.read_csv('data/military_news.csv')
# 刪除空行
df = df.dropna()
# 將新聞的每一行內(nèi)容提取到列表中
lines = df.content.values.tolist()
# 將列表中的內(nèi)容使用空字符串進(jìn)行連接
content = "".join(lines)
# allowPOS參數(shù)可以用來限定返回的關(guān)鍵詞次性,比如:'n'代表名稱,'v'代表動(dòng)詞
print(" ".join(analyse.textrank(content, topK=20, allowPOS=('v','n'))))
print('----------------------------------------------------------')
print(" ".join(analyse.textrank(content, topK=20, allowPOS=('v'))))
4.4 關(guān)鍵詞匹配——詞袋模型(BOW,bag of words)
例句: Jane wants to go to Shenzhen.
Bob wants to go to Shanghai.
將所有詞語(yǔ)裝進(jìn)一個(gè)袋子里,不考慮其詞法和語(yǔ)序的問題,即每個(gè)詞語(yǔ)都是獨(dú)立的。例如上面2個(gè)例句,就可以構(gòu)成一個(gè)詞袋,袋子里包括Jane、wants、to、go、Shenzhen、Bob、Shanghai。假設(shè)建立一個(gè)數(shù)組(或詞典)用于映射匹配
[Jane, wants, to, go, Shenzhen, Bob, Shanghai]
那么上面兩個(gè)例句就可以用以下兩個(gè)向量表示,對(duì)應(yīng)的下標(biāo)與映射數(shù)組的下標(biāo)相匹配,其值為該詞語(yǔ)出現(xiàn)的次數(shù)
[1,1,2,1,1,0,0]
[0,1,2,1,0,1,1]
這兩個(gè)詞頻向量就是詞袋模型,可以很明顯的看到語(yǔ)序關(guān)系已經(jīng)完全丟失
注意
在實(shí)際應(yīng)用中,很多python包會(huì)分別處理每個(gè)句子,查找該句子中每個(gè)單詞出現(xiàn)的次數(shù),將每個(gè)句子轉(zhuǎn)換為對(duì)應(yīng)的向量(這種情況下,向量的長(zhǎng)度可能不同)
import jieba
# 將數(shù)據(jù)集轉(zhuǎn)換成合適的格式
df = pd.read_csv('data/technology_news.csv',encoding='gbk')
df = df.dropna()
lines = df.content.values.tolist()
# 存儲(chǔ)每一行的分詞列表
sentences = []
for line in lines:
try:
segs = jieba.lcut(line) # 對(duì)當(dāng)前行分詞
segs = list(filter(lambda x:len(x)>1, segs))# 過濾:只保留長(zhǎng)度大于1的詞語(yǔ)
segs = list(filter(lambda x:x not in stopwords, segs)) # 去除停用詞
sentences.append(segs) # 將當(dāng)前行分詞列表添加到sentences列表中
except:
print(line)
continue
# 詞袋模型處理
# gensim是應(yīng)該python的自然語(yǔ)言處理庫(kù)
from gensim import corpora
import gensim
# 將sentences交給Dictionary對(duì)象
dictionary = corpora.Dictionary(sentences)
# 分別對(duì)每一行的文本分詞列表轉(zhuǎn)化為詞袋模型
corpus = [dictionary.doc2bow(sentence) for sentence in sentences]
# 觀察結(jié)果
print(sentences[3])
print(corpus[3])
corpus # (第幾個(gè)詞語(yǔ),出現(xiàn)的次數(shù))
5.繪制詞云圖
5.1 不使用背景圖
wordcloud = WordCloud(font_path='data/simhei.ttf', background_color='white', max_font_size=80)
# 統(tǒng)計(jì)頻率最高的1000個(gè)詞語(yǔ)
word_frequence = {x[0]:x[1] for x in words_stat.head(1000).values}
# 對(duì)詞語(yǔ)進(jìn)行訓(xùn)練
wordcloud = wordcloud.fit_words(word_frequence)
# 繪制詞云圖
plt.imshow(wordcloud)
plt.show()
5.2 自定義背景圖
當(dāng)我們使用自定義背景圖時(shí),效果就是:讓詞云的排版樣式仿照我們背景圖的排版,同樣的,對(duì)于顏色的使用也是根據(jù)背景圖去排版
背景圖
import imageio
# 設(shè)置圖像大小
matplotlib.rcParams['figure.figsize'] = (15.0, 15.0)
# 讀取詞云背景圖: 背景圖的含義是根據(jù)背景圖的展示布局、顏色,繪制出類似效果的詞云圖
bimg = imageio.imread('image/entertainment.jpeg')
# 通過WordCloud的mask參數(shù)指定詞云背景圖
wordcloud = WordCloud(background_color="white", mask=bimg,
font_path='data/simhei.ttf',max_font_size=100)
# 將詞頻信息轉(zhuǎn)換為字典
word_frequence = {x[0]:x[1] for x in words_stat.head(1000).values}
# 學(xué)習(xí)詞頻信息
wordcloud = wordcloud.fit_words(word_frequence)
from wordcloud import ImageColorGenerator
# 從背景圖提取顏色信息
bimgColors = ImageColorGenerator(bimg)
# 關(guān)閉坐標(biāo)軸
plt.axis('off')
plt.imshow(wordcloud.recolor(color_func=bimgColors))
plt.show()
6.建模
6.1 LDA建?!谋痉诸愔黝}
LDA簡(jiǎn)介
- LDA(Latent Dirichlet Allocation),也成為"隱狄利克雷分布"。 LDA 在主題模型中占有非常重要的地位,常用來文本分類。
- LDA根據(jù)一篇已有的文章,去尋找這篇文章的若干個(gè)主題,以及這些主題對(duì)應(yīng)的詞語(yǔ)
LDA建模注意事項(xiàng):
用LDA主題模型建模首先要把文本內(nèi)容處理成固定的格式,一個(gè)包含句子的list,list中每個(gè)元素是一句話分詞后的詞list。類似下面這個(gè)樣子:
[[第,一,條,新聞,在,這里],[第,二,條,新聞,在,這里],[這,是,在,做, 什么],…]
# gensim是應(yīng)該python自然語(yǔ)言處理庫(kù),能夠?qū)⑽臋n根據(jù)TF-IDF等模型轉(zhuǎn)換成向量模式
from gensim import corpora, models, similarities
import gensim
# 存儲(chǔ)每一行的分詞列表 sentences [[, , ,],[, , ,],[, , ,]]
# 將sentences交給DIctionary對(duì)象
dictionary = corpora.Dictionary(sentences)
# 分別對(duì)每一行的文本分詞列表轉(zhuǎn)化為詞袋模型(向量)
corpus = [dictionary.doc2bow(sentence) for sentence in sentences]
# 創(chuàng)建LdaModel對(duì)象,設(shè)置主題個(gè)數(shù),詞袋模型(向量)
# corpus:文本分詞轉(zhuǎn)化為詞袋模型的列表;id2word:將分詞列表傳遞給Dictionary對(duì)象;num_topics:包含的主題數(shù)量
lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=20)
# 把所有的主題都打印出來,設(shè)置要大于的主題數(shù)量,主題包含的詞語(yǔ)數(shù)量
for topic in lda.print_topics(num_topics=20,num_words=8):
print(topic[0],'=====>',topic[1])
7.用機(jī)器學(xué)習(xí)的方法完成中文文本分類
7.1 準(zhǔn)備數(shù)據(jù)
import jieba
import pandas as pd
df_technology = pd.read_csv("./data/technology_news.csv", encoding='gbk')
df_technology = df_technology.dropna()
df_car = pd.read_csv("./data/car_news.csv")
df_car = df_car.dropna()
df_entertainment = pd.read_csv("./data/entertainment_news.csv", encoding='gbk')
df_entertainment = df_entertainment.dropna()
df_military = pd.read_csv("./data/military_news.csv")
df_military = df_military.dropna()
df_sports = pd.read_csv("./data/sports_news.csv")
df_sports = df_sports.dropna()
technology = df_technology.content.values.tolist()[1000:21000]
car = df_car.content.values.tolist()[1000:21000]
entertainment = df_entertainment.content.values.tolist()[:20000]
military = df_military.content.values.tolist()[:20000]
sports = df_sports.content.values.tolist()[:20000]
# 讀取停用詞
# stopwords=pd.read_csv("data/stopwords.txt",quoting=3,names=['stopword'])
# 解決報(bào)錯(cuò):ParserError: Error tokenizing data. C error: Expected 1 fields in line 12, saw 2
# 當(dāng)我們使用read_csv讀取txt文本文件時(shí)候,需要添加quoting=3和names指定列的參數(shù),若還是不行則error_bad_lines=False
stopwords = pd.read_csv('./data/stopwords.txt',quoting=3, names=['stopword'],error_bad_lines=False)
stopwords=stopwords['stopword'].values
# 去停用詞
def preprocess_text(content_lines, sentences, category):
for line in content_lines:
try:
segs=jieba.lcut(line) # jieba中文分詞
segs = filter(lambda x:len(x)>1, segs) # 將文本長(zhǎng)度大于1的留下
segs = filter(lambda x:x not in stopwords, segs) # 去除分詞中包含停用詞的分詞
# 這次也記錄了每個(gè)文本的所屬分類
sentences.append((" ".join(segs), category))
except Exception as e:
print(line)
continue
#生成訓(xùn)練數(shù)據(jù)
sentences = []
preprocess_text(technology, sentences, 'technology')
preprocess_text(car, sentences, 'car')
preprocess_text(entertainment, sentences, 'entertainment')
preprocess_text(military, sentences, 'military')
preprocess_text(sports, sentences, 'sports')
# 打亂一下順序,生成更可靠的訓(xùn)練集
import random
random.shuffle(sentences)
# 觀察一下
for sentence in sentences[:10]:
print(sentence[0], sentence[1])
# 為了一會(huì)兒檢測(cè)一下分類器效果怎么樣,需要一份測(cè)試集。
# 所以把原數(shù)據(jù)集分成訓(xùn)練集的測(cè)試集,用sklearn自帶的分割函數(shù)
from sklearn.model_selection import train_test_split
x, y = zip(*sentences)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1234)
len(x_train)
7.2 樸素貝葉斯使用簡(jiǎn)介
7.2.1 簡(jiǎn)介
- 樸素貝葉斯(na?ve Bayes)法是基于貝葉斯定理與特征條件獨(dú)立假設(shè)的分類方法。
- "樸素"的含義:樣本的各特征之間相互獨(dú)立。
- 算法原理:對(duì)于待分類樣本,計(jì)算在此待分類樣本出現(xiàn)的條件下各個(gè)類別出現(xiàn)的概率,哪個(gè)最大,就認(rèn)為此樣本屬于哪個(gè)類別
7.2.2 對(duì)文本抽取詞袋模型特征簡(jiǎn)介
對(duì)于文本來說,預(yù)處理時(shí)需要把文本轉(zhuǎn)換為數(shù)字類型
CountVectorizer
**作用:**用來統(tǒng)計(jì)樣本中特征詞出現(xiàn)的個(gè)數(shù),將單詞作為特征(特征詞)
例子:
data = ["i like python,and python like me",
"python is a good good good language"]
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer()
transform_data = cv.fit_transform(data) # 擬合+轉(zhuǎn)換文本
print(transform_data.toarray())
print(cv.get_feature_names()) # 提取的特征詞
7.2.3 使用MultinomialNB實(shí)現(xiàn)樸素貝葉斯
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB()
classifier.fit(訓(xùn)練樣本集特征,訓(xùn)練樣本集標(biāo)簽) # 擬合訓(xùn)練
# 在測(cè)試集上測(cè)試準(zhǔn)確率
classifier.score(測(cè)試樣本集特征,測(cè)試樣本集標(biāo)簽)
7.3 模型訓(xùn)練
# 1.對(duì)文本抽取詞袋模型特征
from sklearn.feature_extraction.text import CountVectorizer
# 設(shè)置最大的特征數(shù)量為4000
vec = CountVectorizer(max_features=4000)
vec.fit(x_train) # 擬合訓(xùn)練
# 2.使用樸素貝葉斯進(jìn)行文本分類
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB()
# 擬合進(jìn)行分類訓(xùn)練,注意:傳遞的樣本特征一定要先轉(zhuǎn)化為詞袋模型(數(shù)字向量)
classifier.fit(vec.transform(x_train),y_train)
# 3.評(píng)價(jià)分類結(jié)果
classifier.score(vec.transform(x_test),y_test)
0.8442394629891776
7.4 自定義文本分類器(模型)完成中文文本分類
本質(zhì)上還是調(diào)用樸素貝葉斯算法,只是單獨(dú)制作成了一個(gè)類
import re
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
class TextClassifier:
def __init__(self, classifier=MultinomialNB()):
# 自定義初始化,默認(rèn)使用分類器時(shí)樸素貝葉斯
self.classifier = classifier # 分類器對(duì)象
self.vectorizer = CountVectorizer(max_features=4000) # 詞袋實(shí)現(xiàn)對(duì)象
# 詞袋實(shí)現(xiàn),文本轉(zhuǎn)換成數(shù)字向量
def features(self, X):
return self.vectorizer.transform(X)
# 訓(xùn)練模型
def fit(self, X, y):
# 詞袋擬合模型
self.vectorizer.fit(X)
# 分類訓(xùn)練(特征轉(zhuǎn)換為數(shù)字向量)
self.classifier.fit(self.features(X),y)
# 對(duì)某個(gè)文本預(yù)測(cè)
def predict(self, x):
return self.classifier.predict(self.features([x]))
# 準(zhǔn)確率
def score(self,X,y):
return self.classifier.score(self.features(X),y)
# 實(shí)例化對(duì)象
text_classifier = TextClassifier()
# 擬合訓(xùn)練
text_classifier.fit(x_train,y_train)
# 在測(cè)試集上查看準(zhǔn)確率
print(text_classifier.score(x_test,y_test))
# 預(yù)測(cè)
print(text_classifier.predict("多年 百變 歌喉 海燕 這位 酷愛 鄧麗君 歌曲 并視 歌唱 生命 歌者"))
8.用深度學(xué)習(xí)的方法完成中文文本分類
8.1 CNN做文本分類
卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,CNN)也適合做的是文本分類,由于卷積和池化會(huì)丟失句子局部字詞的排列關(guān)系,所以純cnn不太適合序列標(biāo)注和命名實(shí)體識(shí)別之類的任務(wù)。
? nlp任務(wù)的輸入都不再是圖片像素,而是以矩陣表示的句子或者文檔。矩陣的每一行對(duì)應(yīng)一個(gè)單詞或者字符。也即每行代表一個(gè)詞向量,通常是像 word2vec 或 GloVe 詞向量。在圖像問題中,卷積核滑過的是圖像的一“塊”區(qū)域,但在自然語(yǔ)言領(lǐng)域里我們一般用卷積核滑過矩陣的一“行”(單詞)。文章來源:http://www.zghlxwxcb.cn/news/detail-773944.html
8.2 LSTM文本分類
能捕捉時(shí)序信息的長(zhǎng)短時(shí)記憶神經(jīng)網(wǎng)絡(luò)LSTM,畢竟,對(duì)于長(zhǎng)文的信息捕捉,憑借自帶的Memory屬性,它還是有比較強(qiáng)的能力的文章來源地址http://www.zghlxwxcb.cn/news/detail-773944.html
"""
使用RNN完成文本分類
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import sys
import numpy as np
import pandas
from sklearn import metrics
import tensorflow as tf
from tensorflow.contrib.layers.python.layers import encoders
learn = tf.contrib.learn
FLAGS = None
MAX_DOCUMENT_LENGTH = 15
MIN_WORD_FREQUENCE = 1
EMBEDDING_SIZE = 50
global n_words
# 處理詞匯
vocab_processor = learn.preprocessing.VocabularyProcessor(MAX_DOCUMENT_LENGTH, min_frequency=MIN_WORD_FREQUENCE)
x_train = np.array(list(vocab_processor.fit_transform(train_data)))
x_test = np.array(list(vocab_processor.transform(test_data)))
n_words = len(vocab_processor.vocabulary_)
print('Total words: %d' % n_words)
def bag_of_words_model(features, target):
"""先轉(zhuǎn)成詞袋模型"""
target = tf.one_hot(target, 15, 1, 0)
features = encoders.bow_encoder(
features, vocab_size=n_words, embed_dim=EMBEDDING_SIZE)
logits = tf.contrib.layers.fully_connected(features, 15, activation_fn=None)
loss = tf.contrib.losses.softmax_cross_entropy(logits, target)
train_op = tf.contrib.layers.optimize_loss(
loss,
tf.contrib.framework.get_global_step(),
optimizer='Adam',
learning_rate=0.01)
return ({
'class': tf.argmax(logits, 1),
'prob': tf.nn.softmax(logits)
}, loss, train_op)
model_fn = bag_of_words_model
classifier = learn.SKCompat(learn.Estimator(model_fn=model_fn))
# Train and predict
classifier.fit(x_train, y_train, steps=1000)
y_predicted = classifier.predict(x_test)['class']
score = metrics.accuracy_score(y_test, y_predicted)
print('Accuracy: {0:f}'.format(score))
def rnn_model(features, target):
"""用RNN模型(這里用的是GRU)完成文本分類"""
# Convert indexes of words into embeddings.
# This creates embeddings matrix of [n_words, EMBEDDING_SIZE] and then
# maps word indexes of the sequence into [batch_size, sequence_length,
# EMBEDDING_SIZE].
word_vectors = tf.contrib.layers.embed_sequence(
features, vocab_size=n_words, embed_dim=EMBEDDING_SIZE, scope='words')
# Split into list of embedding per word, while removing doc length dim.
# word_list results to be a list of tensors [batch_size, EMBEDDING_SIZE].
word_list = tf.unstack(word_vectors, axis=1)
# Create a Gated Recurrent Unit cell with hidden size of EMBEDDING_SIZE.
cell = tf.contrib.rnn.GRUCell(EMBEDDING_SIZE)
# Create an unrolled Recurrent Neural Networks to length of
# MAX_DOCUMENT_LENGTH and passes word_list as inputs for each unit.
_, encoding = tf.contrib.rnn.static_rnn(cell, word_list, dtype=tf.float32)
# Given encoding of RNN, take encoding of last step (e.g hidden size of the
# neural network of last step) and pass it as features for logistic
# regression over output classes.
target = tf.one_hot(target, 15, 1, 0)
logits = tf.contrib.layers.fully_connected(encoding, 15, activation_fn=None)
loss = tf.contrib.losses.softmax_cross_entropy(logits, target)
# Create a training op.
train_op = tf.contrib.layers.optimize_loss(
loss,
tf.contrib.framework.get_global_step(),
optimizer='Adam',
learning_rate=0.01)
return ({
'class': tf.argmax(logits, 1),
'prob': tf.nn.softmax(logits)
}, loss, train_op)
model_fn = rnn_model
classifier = learn.SKCompat(learn.Estimator(model_fn=model_fn))
# Train and predict
classifier.fit(x_train, y_train, steps=1000)
y_predicted = classifier.predict(x_test)['class']
score = metrics.accuracy_score(y_test, y_predicted)
print('Accuracy: {0:f}'.format(score))
到了這里,關(guān)于5.Python數(shù)據(jù)分析項(xiàng)目之文本分類-自然語(yǔ)言處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!