個人項目:論文查重


作業所屬課程 https://edu.cnblogs.com/campus/gdgy/Networkengineering1834
作業要求 https://edu.cnblogs.com/campus/gdgy/Networkengineering1834/homework/11146
這個作業的目標 實現論文查重算法,熟練使用PSP表格,熟練使用單元測試,熟練使用代碼質量檢測工具,熟練使用性能分析工具

一、GitHub

https://github.com/birdaaron/Cosine-Similarity

二、PSP表格

PSP2.1 Personal Software Process Stages 預估耗時(分鍾) 實際耗時(分鍾)
Planning 計划 10 10
· Estimate 估計這個任務需要多少時間 10 10
Development 開發 290 470
· Analysis 需求分析 (包括學習新技術) 60 120
· Design Spec 生成設計文檔 0 0
· Design Review 設計復審 0 0
· Coding Standard 代碼規范 (為目前的開發制定合適的規范) 0 0
· Design 具體設計 20 20
· Coding 具體編碼 120 200
· Code Review 代碼復審 60 60
· Test 測試(自我測試,修改代碼,提交修改) 30 70
Reporting 報告 120 330
·Test Report 測試報告 90 300
·Size Measurement 計算工作量 0 0
·Postmortem & Process Improvement Plan 事后總結, 並提出過程改進計划 30 30
Total 合計 420 810

三、接口的設計與實現過程

1.算法原理

參考文章:https://www.cnblogs.com/airnew/p/9563703.html

簡單起見,先從兩個句子着手:

句子A:我喜歡分詞!你喜歡嗎?
句子B:我討厭分詞,你討厭嗎?

判斷這兩個句子的相似度的基本思路是:如果兩句話的用詞相似,它們的內容也就越相似。所以可以通過詞頻來計算兩個句子的相似度。
既然要計算詞頻,就應該讓計算機把所有用詞都識別出來。

所以第一步就是分詞。

分詞A:我/喜歡/分詞/!/你/喜歡/嗎/?/
分詞B:我/討厭/分詞/,/你/討厭/嗎/?/

第二部,將分詞都放在一個集合里,方便統計

集合:我/你/喜歡/討厭/嗎/!/?/,/

第三步,計算詞頻

詞頻A:我(1)/你(1)/喜歡(2)/討厭(0)/嗎(1)/!(1)/?(1)/,(0)/
詞頻B:我(1)/你(1)/喜歡(0)/討厭(2)/嗎(1)/!(0)/?(1)/,(1)/

第四步,得出向量(詞頻數組)

句子A [1,1,2,0,1,1,1,0]
句子B [1,1,0,2,1,0,1,1]

得到詞頻后就可以開始計算相似度:如果把兩個句子的向量看成是空間中的兩條從原點[0,0,0,0,0,0,0,0]出發,指向[1,1,2,0,1,1,1,0]和[1,1,0,2,1,0,1,1]的線段,就可以通過計算線段夾角大小來判斷兩條線段是否重合/相似。
也就是說,這個角的余弦值越大,就越相似。

2.接口設計

· 我將實現的功能大體分為兩個部分:

1.文件處理TextSimilarity.java:用於讀取txt文件中的字符串和創造輸出文件,是程序的入口

2.相似度計算Core.java:用於將讀入的文章分詞,記錄詞頻和計算相似度

· 關系圖

3.關鍵算法

· 由於有了分詞頻數計算余弦值是非常簡單的,那么關鍵就在於收集分詞和統計分詞頻數

· 收集分詞的集合是一個以分詞字符串(String word)為Key,分詞頻數數組(int[2] count)為Value的HashMap(HashMap<String,int[]> wordMap),其中count[0]代表articleA的分詞頻數,count[1]則代表articleB的分詞頻數。

· 代碼中用到的是分詞器是jieba-analysis

四、接口部分的性能改進

1.使用SonarLint改進代碼質量

· 已消除所有警告

2.使用JProfier分析性能

內存泄漏

· Overview
Memory的下降代表垃圾回收

· Live memory
手動GC前,各對象占用內存

手動GC后,各對象占用內存,可見大部分HashMap被留在了內存里

· Heap walker
可見這些HashMap都是由我使用的分詞器所帶來的,不方便優化

時間花費

· CallTree,可見大部分時間花費在分詞上,很小部分時間花費在文件的讀寫

· 花費時間最多的函數

五、單元測試展示

1.測試覆蓋率

2.單元測試

· TextSimilarityTest.java

該類主要是用於處理文件,所以主要測試是否成功從文件中讀取文章和是否成功創建輸出文件

· 參數化測試
JUnit4允許開發人員使用不同的值反復運行相同的測試,initData()函數中objects包含5組數據,它們會在構造函數中被接收,相當於進行5次不同數據的測試,每組數據的第一個元素是對比文章的絕對地址,第二個元素是對比文章的第一句話(由於每篇文章的第一句話都是“活着前言”的不同變句,由此用來測試對應文章是否成功被讀取到List中)

· void testArticleBFirstSentence() 測試對比文章是否被成功讀取到List中

· void testCreateOutputFile() 測試輸出文件是否成功創建

· 測試結果

· CoreTest.java

該類主要用於分詞、統計詞頻和計算相似度,其中計算相似度比較簡單,重點在於測試前兩個功能。

· 測試數據

· void testTextSegment()測試分詞結果和詞頻統計結果

· 測試結果

· 文章相似度測試

· orig.txtorig_0.8_add.txt

· orig.txt與orig_0.8_del.txt

· orig.txt與orig_0.8_dis_1.txt

· orig.txt與orig_0.8_dis_10.txt

· orig.txt與orig_0.8_dis_15.txt

六、異常處理

· FileNotFoundException
在從文件中讀取字符串和創造輸出文件時,如果給出的文件地址不正確,就會產生該異常

異常測試


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM