一、基礎知識
假設有一份文本數據如下,數據量很大,現在要對整個語料庫進行文本分析,category代表新聞種類,theme代表新聞主題,URL代表新聞鏈接地址,content代表新聞主題內容

停用詞:在content這一列,在數據量很大的情況,很容易發現某些似乎與新聞本身意義不大的詞大量出現,而我們就把這些在語料庫中大量出現但是又沒啥大用的詞叫做停用詞,在數據集鏈接中包含一份常見的停用詞,如下所示:

TF-IDF:用於關鍵詞提取。比如在一篇名叫《中國的蜜蜂養殖》這篇文章中進行詞頻(Term Frequency,縮寫為TF)統計出現次數最多的詞是“的”、“是”、“在”等這一類最常用的詞(停用詞,一般來說是要去掉的),在刪除掉停用詞過后我們發現“中國”、“蜜蜂”、“養殖”這三個詞的出現次數一樣多,那么這三個詞的重要性是一樣的嗎?一般來說"中國"是很常見的詞,相對而言,"蜜蜂"和"養殖"不那么常見。這時就需要引入一個叫做逆文檔頻率來進行衡量。"逆文檔頻率"(Inverse Document Frequency,縮寫為IDF)如果某個詞相比較於整個語料庫來說比較少見,但是它在這篇文章中多次出現,那么它很可能就反映了這篇文章的特性,那它正是我們所需要的關鍵詞。
計算公式

TF-IDF = 詞頻(TF) * 逆文檔頻率(IDF)。還是在《中國的蜜蜂養殖》這篇文章中:假定該文長度為1000個詞,"中國"、"蜜蜂"、"養殖"各出現20次,則這三個詞的"詞頻"(TF)都為0.02。搜索Google發現,包含"的"字的網頁共有250億張,假定這就是中文網頁總數(也就是語料庫)。包含"中國"的網頁共有62.3億張,包含"蜜蜂"的網頁為0.484億張,包含"養殖"的網頁為0.973億張。

可以看出蜜蜂和養殖的TF-IDF值比中國這個詞大,那么這篇文章的關鍵詞重要性依次為蜜蜂、養殖和中國。
文本相似度:假設有如下兩個句子A、B,我們該怎么判斷這兩個句子的相似度呢
句子A:我喜歡看電視,不喜歡看電影。
句子B:我不喜歡看電視,也不喜歡看電影。
先進行分詞來看一下。
句子A:我/喜歡/看/電視,不/喜歡/看/電影。
句子B:我/不/喜歡/看/電視,也/不/喜歡/看/電影。
可以得到整個語料庫:我,喜歡,看,電視,電影,不,也。
然后進行詞頻的統計
句子A:我 1,喜歡 2,看 2,電視 1,電影 1,不 1,也 0。
句子B:我 1,喜歡 2,看 2,電視 1,電影 1,不 2,也 1。
這樣就可以得出詞頻向量
句子A:[1, 2, 2, 1, 1, 1, 0]
句子B:[1, 2, 2, 1, 1, 2, 1]
相似度計算方法:最常用通過余弦進行計算


二、任務簡介與數據預處理
現在我們手里一份新聞數據,數據里面包含新聞的內容以及新聞的種類等等,我們要做的就是對新聞進行一個分類任務,比如說汽車類時尚類等等。
數據集鏈接:https://pan.baidu.com/s/1fG_oagJT69bIgCZgasn_Ig 提取碼:yzd0
導入相關的python庫
import pandas as pd import jieba # 如果沒有這個庫可能需要手動安裝
讀取數據集並刪除缺失的數據集(缺失的數據很少,所以可以刪除)
# read_table()讀取以‘/t’分割的文件到DataFrame
# 在實際使用中可以通過對sep參數的控制來對任何文本文件讀取
df_news = pd.read_table('./data/val.txt',names=['category','theme','URL','content'],encoding='utf-8')
df_news = df_news.dropna() # 刪除缺失數據
df_news.head()
content為新聞的主體內容

查看數據集維度
df_news.shape
得到的結果
(5000, 4)
將新聞內容轉換為list方便進行分詞並查看第1000條數據內容
content = df_news.content.values.tolist() # 轉換為list 實際上是二維list print(content[1000])
內容為:
阿里巴巴集團昨日宣布,將在集團管理層面設立首席數據官崗位(Chief Data Officer),阿里巴巴B2B公
司CEO陸兆禧將會出任上述職務,向集團CEO馬雲直接匯報。>菹ぃ和6月初的首席風險官職務任命相同,首席數據官亦為阿
里巴巴集團在完成與雅虎股權談判,推進“one company”目標后,在集團決策層面新增的管理崗位。0⒗錛團昨日表示
,“變成一家真正意義上的數據公司”已是戰略共識。記者劉夏
下面使用python中的jieba庫進行分詞
content_S = []
for line in content:
# jieba分詞 精確模式。返回一個列表類型,建議使用
current_segment = jieba.lcut(line)
if len(current_segment) > 1 and current_segment != '\r\n':
content_S.append(current_segment)
查看第1000條數據分詞后的內容
content_S[1000]

轉為pandas支持的DataFrame格式
df_content = pd.DataFrame({'content_S':content_S}) # 轉換為DataFrame
df_content.head()
分完詞后的結果為:

可以發現數據里面包含很多無用的詞匯,所以我們需要對這些數據進行清洗,就是刪除掉里面包含的停用詞
三、 刪除停用詞
讀取停用詞表
# 讀取停詞表
stopwords = pd.read_csv('./data/stopwords.txt',index_col=False,sep='\t',quoting=3,names=['stopword'],encoding='utf-8')
stopwords.head()
結果為:

刪除語料庫中的停用詞,這里面的all_words是為了后面的詞雲展示。
# 刪除新聞中的停用詞
def drop_stopwords(contents, stopwords):
contents_clean = [] # 刪除后的新聞
all_words = [] # 構造詞雲所用的數據
for line in contents:
line_clean = []
for word in line:
if word in stopwords:
continue
line_clean.append(word)
all_words.append(str(word))
contents_clean.append(line_clean)
return contents_clean, all_words
contents = df_content.content_S.values.tolist()
stopwords = stopwords.stopword.values.tolist()
# 得到刪除停用詞后的新聞以及詞雲數據
contents_clean, all_words = drop_stopwords(contents, stopwords)
# df_content.content_S.isin(stopwords.stopword)
# df_content=df_content[~df_content.content_S.isin(stopwords.stopword)]
# df_content.head()
查看刪除停用詞后的新聞內容
df_content = pd.DataFrame({'contents_clean':contents_clean})
df_content.head()
從結果可以看出,這次的數據對比上面的數據來說質量提高了很多。

查看一下出現的所有的詞匯,也就是刪除停用詞后的all_words。
df_all_words = pd.DataFrame({'all_words':all_words})
df_all_words.head()
結果為:

統計all_words每個詞的詞頻,統計這個詞頻也是為了方便后面的詞雲展示。
import numpy
# 分組統計
words_count = df_all_words.groupby(by=['all_words'])['all_words'].agg({'count':numpy.size})
# 根據count排序
words_count = words_count.reset_index().sort_values(by=['count'],ascending=False)
words_count.head()
結果為:

四、詞雲展示
導入wordcloud庫以及畫圖展示
from wordcloud import WordCloud # 詞雲庫
import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib
matplotlib.rcParams['figure.figsize'] = (10.0,5.0)
wordcloud = WordCloud(font_path='./data/simhei.ttf',background_color='white',max_font_size=80)
word_frequence = {x[0]:x[1] for x in words_count.head(100).values} # 這里只顯示詞頻前100的詞匯
wordcloud = wordcloud.fit_words(word_frequence)
plt.imshow(wordcloud)
可視化結果為:

未完待續。。。
