慣例三件套
軟件工程 | 班級地址 |
---|---|
這個作業要求在哪里 | 點擊 |
這個作業的目標 | 完成個人編程練習,學習git和github的聯動使用,學習去重算法simhash的原理與實現 |
Github 此項目鏈接 | 點擊 |
- 基本情況:
- simhash算法實現:
- 分詞算法:jieba
- 調用庫:jieba、re
- 核心算法:getfile()、simhashalgo()、haiming()
- 相似度:采用simhash值相除后取精確值 - 測試單元:
- 算法:unittest
- 測試用例:祖傳六份orig.txt - 待優化地方:
- 初始的測試用例是包含html文本的,由於文本關鍵詞提取必須去除html文本標簽內的英文的緣故,此處設計的simhash算法只針對中文,后可通過更改停詞庫和更改正則表達式進行修改
- simhash算法實現:
PSP
PSP2.1 | Personal Software Process Stages | 預估耗時(分鍾) | 實際耗時(分鍾) |
---|---|---|---|
Planning | 計划 | 20 | 15 |
Estimate | · 估計這個任務需要多少時間 | 40 | 30 |
Development | 開發 | 400 | 540 |
Analysis | 需求分析 (包括學習新技術) | 120 | 90 |
Design Spec | 生成設計文檔 | 50 | 40 |
Design Review | 設計復審 | 20 | 15 |
Coding Standard | · 代碼規范 (為目前的開發制定合適的規范) | 20 | 15 |
Design | 具體設計 | 50 | 60 |
Coding | 具體編碼 | 30 | 20 |
Code Review | 代碼復審 | 30 | 50 |
Test | 測試(自我測試,修改代碼,提交修改 | 30 | 80 |
Reporting | 報告 | 90 | 90 |
Test Repor | 測試報告 | 40 | 30 |
Size Measurement | 計算工作量 | 15 | 15 |
Postmortem & Process Improvement Plan | 事后總結, 並提出過程改進計划 | 30 | 25 |
合計 | 985 | 1115 |
核心步驟
一.分詞
此處我合並了打開文本、提取文本、清洗文本的步驟,由於jieba庫中能直接調用jieba.analyse.extract_tags,返回一個經過tf-idf處理結果后的列表。此列表包含了能自定義個數n的最高權重排名前n個關鍵詞,以及關鍵詞對應的權重值,能非常方便后續結果的處理,因此我使用了jieba庫,通過這個getfile()函數我實現了導入、清洗、分詞與獲得權重,返回一個{關鍵詞:權重}的字典以及字典長度
二.hash
此處的hash算法較為復雜,主要的思路就是把漢字對應的ASCII碼進行hash運算,通過盡量確保每個詞對應的hash編碼不同來確保最后數組運算時各數據能代表原先的漢字,最后轉化為一個64位長度的二進制序列來進行之后的運算。
三.加權、降維操作
此處我定義的simhashalgo()函數就是最關鍵的步驟,通過前面的getfile()以及hash函數返回來的權重與特征向量的hash值,我們能通過各關鍵詞加權、關鍵詞的相加與最后降維成單列10序列,能把原本分散於64位的漢字特征值最后特征式地降維到單列數字中,具體數學公式還有待推導,但最后得到的simhash值就是該文本關鍵詞加權后的降維特征詞(簡單說就是通過把n個特征詞加權后同一列的數字相加,得到一個偏向於1或0的代表值),通過與simhash值的比較,就能實現推斷文本在關鍵詞上是否存在相似性,以及相似性的大致估計。由於相似的文章關鍵詞權重應該都相差不大,因此有差別的位數也只會有少數幾位,simhash算法又因此被稱作“局部敏感hash算法”
(我的代碼實現就是普通地進行加權、相加、判斷大小后取值、整合成單行的01序列,最后返回對應的列表)
四.haiming和相似
沒啥好講的,就是從定義出發,比較simhash值中不同的位數來推斷相似性
單元測試
使用unittest:
就是非常簡單的拼接地址+調用上面設計好的simhash算法,簡單易操作。感謝廖雪峰老師的簡要文檔
測試效果圖:
性能分析
使用pycharm自帶的profile方法
個人總結
1.這次實驗用到了我一直很感興趣的去重算法,因此在算法的琢磨與研究上花費了出乎意外的時間,導致后面的報告部分被相應地壓縮了,這點得反省。
2.參考了網上的大量文獻后,我弄懂了關於simhash的大部分內容,但對於諸如海明距離用於關鍵詞判斷的閾值、關鍵詞選取個數對最后結果的影響、相似度如何運算(除法個人覺得不大妥當)、關鍵詞如何降維到二維的01序列也就是string_hash算法的設計(這個參考了專業博客的算法,並非完全原創)這些問題都有待思考和解決
3.過於執着於算法實現而忽略了其他更簡便也更適合少規模對比的算法(gensim,余弦,動態規划等),思維模式應該要更加靈活