1. 程式人生 > >軟工作業3:詞頻統計

軟工作業3:詞頻統計

tex split() 數據 復雜 all p s pro ioe 創建

一、案例程序分析

1.1、編譯環境

pycharm2017、python3.6

1.2、讀文件到緩沖區(process_file(dst))

 1 def process_file(dst):  # 讀文件到緩沖區
 2     try:  # 打開文件
 3         f = open(dst, r)  # dst為文本的目錄路徑
 4     except IOError as s:
 5         print(s)
 6         return None
 7     try:  # 讀文件到緩沖區
 8         bvffer = f.read()
9 except: 10 print(Read File Error!) 11 return None 12 f.close() 13 return bvffer

1.3、處理緩沖區,返回存有詞頻數據的字典(process_buffer(bvffer))

 1 def process_buffer(bvffer):
 2     if bvffer:
 3         word_freq = {}  # 下面添加處理緩沖區 bvffer代碼,統計每個單詞的頻率,存放在字典word_freq
 4         for
ch in “‘!;,.?”: # 將文本內容都改為小寫且除去文本中的中英文標點符號 5 bvffer = bvffer.lower().replace(ch, " ") 6 words = bvffer.strip().split() 7 # strip()刪除空白符(包括‘/n‘, ‘/r‘,‘/t‘);split()以空格分割字符串 8 for word in words: 9 word_freq[word] = word_freq.get(word, 0) + 1 10 return
word_freq

1.4、輸出詞頻前十的單詞(output_result(word_freq))

1 def output_result(word_freq):
2     if word_freq:
3         # 根據v[1]即詞頻數量排序
4         sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True) 
5         for item in sorted_word_freq[:10]:  # 輸出 Top 10 的單詞
6             print("詞:%-5s 頻:%-4d " % (item[0], item[1]))

1.5、主函數對之前的函數進行整合(main())

1 if __name__ == "__main__":
2     dst = src/Gone_with_the_wind.txt  # 《飄》文件的路徑
3     bvffer = process_file(dst)
4     word_freq = process_buffer(bvffer)
5     output_result(word_freq)

1.6、性能分析

(參考:https://www.cnblogs.com/btchenguang/archive/2012/02/03/2337112.html)

為了方便測試,將原來的運行詞頻的代碼寫在main函數中。

1 def main():
2     dst = src/Gone_with_the_wind.txt  # 《飄》文件的路徑
3     bvffer = process_file(dst)
4     word_freq = process_buffer(bvffer)
5     output_result(word_freq)

主函數入口改為性能分析的代碼。

1 if __name__ == "__main__":
2     cProfile.run("main()", "result")
3     # 把分析結果保存到文件中,不過內容可讀性差...需要調用pstats模塊分析結果
4     p = pstats.Stats("result")  # 創建Stats對象
5     p.strip_dirs().sort_stats("call").print_stats()  # 按照調用的次數排序
6     p.strip_dirs().sort_stats("cumulative").print_stats()  # 按執行時間次數排序
7     # 根據上面2行代碼的結果發現函數process_buffer最耗時間
8     p.print_callees("process_buffer")  # 查看process_buffer()函數中調用了哪些函數

二、python代碼風格說明

就塊註釋和行註釋而言:“最需要寫註釋的是代碼中那些技巧性的部分. 如果你在下次 代碼審查的時候必須解釋一下, 那麽你應該現在就給它寫註釋. 對於復雜的操作, 應該在其操作開始前寫上若幹行註釋. 對於不是一目了然的代碼, 應在其行尾添加註釋.”

# 編譯環境:Pycharm2017、Python3.6
# 項目名稱:詞頻統計和性能分析
# 作者:高昶
# 最後修改:2018/9/28

 f = open(dst, r)  # dst為文本的目錄路徑

三、程序運行命令、運行結果截圖

《飄》 文本文件的詞頻統計運行截圖

技術分享圖片

四、性能分析結果及改進

4.1、總運行時間:

技術分享圖片

4.2、執行次數最多的部分代碼(篇幅有限,截取部分)

技術分享圖片

即 word_freq[word] = word_freq.get(word, 0) + 1執行的次數最多

1     word_freq[word] = word_freq.get(word, 0) + 1

4.3、執行時間最多的部分代碼

技術分享圖片

4.4、根據4.2和4.3的結果發現函數 process_buffer()耗時占比最大,所以查看process_buffer()函數中 調用了哪些函數

技術分享圖片

4.5、改進

改進可以從二個方面入手,(1)減少耗時;(2)減少調用次數;但是發現其中調用最多的{method‘get‘ of ‘dict‘ objects}可以理解為是對文本中的詞的遍歷, 詞頻算法就是對文本的詞遍歷,所以該方面不好修改。所以可以從減少耗時入手。

可以將如下代碼:

1         for ch in “‘!;,.?”:  # 將文本內容都改為小寫且除去文本中的中英文標點符號
2             bvffer = bvffer.lower().replace(ch, " ")

改為:(即將bvffer.lower()放在for循環外,我個人理解:設改文本有N個單詞,前者的復雜度為O(N*N),後者復雜度為O(2N))

1     bvffer = bvffer.lower()  # 將文本內容都改為小寫
2     for ch in “‘!;,.?”:  # 將文本內容都改為小寫且除去文本中的中英文標點符號
3         bvffer = bvffer.replace(ch, " ")

修改前後的對比,發現後者比前者快0.2秒左右。(圖一是修改前,圖二是修改後)

技術分享圖片

圖 一

技術分享圖片

圖 二

軟工作業3:詞頻統計