通過文本挖掘看歷史
一次無意中瀏覽到一個網站,上面有從1954年到2016年的政府工作報告,於是寫爬蟲下載之,相信從中可以提煉出大新聞。
用Python的結巴分詞包對1960年的政府工作報告進行分詞並統計詞頻,發現平平無奇,詞頻靠前的都是一些官方的套話,比如「農業」出現了97次,「發展」出現了82次,「綱要」出現了59次,「全國」出現了43次,根本無法提取出當年工作報告的特殊之處。
於是換一個方法,不只統計詞頻,而是統計每個詞語的TF-IDF的值,把TF-IDF靠前的詞語作為工作報告的關鍵詞,出來的效果立刻不一樣了。依舊是1960年的報告,出來的靠前的詞是「社辦」、「人民公社」、「養豬」、「棉田」、「畝產」,一看就知道人民公社是1960年的大新聞。
一股腦對全部報告都分析了,於是得到這樣一張歷史圖譜:
我是怎麼做的?
首先解釋一下TF-IDF,TF-IDF的使用場景一是搜索引擎,用於計算網頁的相似性並與搜索關鍵詞匹配,二是新聞聚合,一般是門戶網站用以計算新聞報道的相似程度並用以歸類。
TF-IDF涉及到2個參數,TF是詞頻,即該詞語在該篇文章中出現的頻率,IDF是文件頻率,即出現了該詞語的文章數量佔總文章數量的比例。理解了它的定義,再聯繫回我所爬下的48篇政府工作報告,舉個栗子,對1954年的工作報告進行分詞,得到的詞頻最高的詞是「國家」,在該篇報告中共出現116次,而該篇報告的詞語數(把重複的詞語也計入)是7775個,那麼「國家」這個詞的詞頻是116/7775在1.5%左右,那麼能不能說因為「國家」這個詞的詞頻高就說它是該篇報告的關鍵詞?不能,因為在48篇報告里,「國家」這個詞頻繁地出現,因此它不能算是該篇報告的特徵詞。那麼「國家」這個詞的IDF怎麼算呢?它在48篇報告里都出現,因此它的IDF值是48/48=1。我是用最簡單的歸一方式來算TF-IDF的,即TF/IDF,對於」國家「這個詞來說它的TF-IDF就是0.015/1=0.015,跟該篇報告的其他詞相比它排在20名開外,因此不能算是該篇報告的關鍵詞。
用Python實現起來非常簡單,我是這樣做的。首先把48篇報告進行分詞,統計出詞語和詞頻並存在48個CSV文件里【1】,再將48篇報告合成1個txt文件進行分詞並去重,統計出所有出現的詞語並存在1個CSV文件里【2】,由【2】對【1】逐一遍歷計算出【2】中每個詞的IDF值並存回【2】,再將【1】中每個文件每個詞語對【2】遍歷計算出每個文件每個詞的TF-IDF值。
最後,覺得有趣的話請關注我哦 *( ^ v ^ )/*
計算IDF值的代碼
import jiebaimport pandas as pdimport numpy as npidf_temp2={"word":[],"idf":[]}f1=pd.read_csv("d:/jieba/tf/word_all.csv",names=["word"])page1=1for x in f1["word"]: idf_temp2["word"].append(x) idf_temp=0 for page in range(1954,2017): try: f2=pd.read_csv("d:/jieba/tf/book/"+str(page)+".csv",names=["word","count"]) for y in f2["word"]: if x==y: idf_temp+=0.02083 else: pass except: pass idf_temp2["idf"].append(idf_temp) print u"計算完第"+str(page1)+u"個詞" page1+=1idf_final=pd.DataFrame(idf_temp2)idf_final.to_csv("d:/jieba/tf/idf_final.csv",mode="w",index=False,encoding="UTF-8")
計算TF-IDF的代碼
import jiebaimport pandas as pdimport numpy as npdef main(): read_all=pd.read_csv("D:/jieba/tf/idf_final.csv") for page in range(2015,2016): try: final={"word":[],"tfidf":[]} read_page=pd.read_csv("D:/jieba/tf/book/"+str(page)+".csv") for index_1 in read_page.index: final["word"].append(read_page.ix[index_1,"word"]) for index_2 in read_all.index: if read_page.ix[index_1,"word"]==read_all.ix[index_2,"word"]: tfidf_1=float(read_page.ix[index_1,"count"])/read_page["count"].sum() tfidf_2=tfidf_1/read_all.ix[index_2,"idf"] final["tfidf"].append(tfidf_2) break else: pass final2=pd.DataFrame(final) final2.to_csv("d:/jieba/tf/book_tfidf/"+str(page)+".csv",mode="w",index=False,encoding="UTF-8") print u"處理完"+str(page)+u"年的報告" except: passif __name__=="__main__": main()
推薦閱讀: