the second
作業要求
* 題目:論文查重
1. 描述如下:
設計一個論文查重算法,給出一個原文文件和一個在這份原文上經過了增刪改的抄襲版論文的文件,在答案文件中輸出其重復率。
2.樣例:
原文示例:今天是星期天,天氣晴,今天晚上我要去看電影。
抄襲版示例:今天是周天,天氣晴朗,我晚上要去看電影。
3.額外要求:
要求輸入輸出采用文件輸入輸出,規范如下:
從命令行參數給出:論文原文的文件的絕對路徑。 從命令行參數給出:抄襲版論文的文件的絕對路徑。 從命令行參數給出:輸出的答案文件的絕對路徑。
作業
我的思路
- 首先肯定是要處理好從命令行讀取路徑和結尾輸出指定路徑
將輸入輸出更改:
- 做文件處理工作,可以先把這一部分當做黑箱
- 最后按照規定寫入數據,並且返回文件的地址(自定義一個文件,如果沒有就在指定的路徑下新建;但是在自己測試的時候沒有這樣,是直接返回重復率)
附上我的github的代碼:021800626(完整代碼、requirements.txt)
(在倉庫里文件,命名的時候是隨意的然后會有說明每個文件的作用以及自己的感受之類的,和最后一個總的代碼)
談一下我的黑箱:
提前說明:因為是按照自己的想法然后找的資料完成這次作業,沒有很按照軟工實踐的理論上數據結構,數據操作,描述性語句這三部分。基本上是混合起來。這個是有點遺憾的!
我的想法:
其實很簡單:靈感來源於一位老師上課講的文章的特征向量,
然后就想先求出原文件和抄襲文件兩個特征向量,
最后一比較就得到重復率(這里的“比較”是余弦相似性)
具體的步驟:
第一步是划定每一個特征向量的坐標也就是后面的stat和stat1要具有一定的可比性(防止有的“漢字”沒有同時出現在兩個文件)
第二步是根據選取的文件分別構建stat和stat1
第三步是余弦相似性公式利用即可
bug可能的出現:
在用python寫完所有的步驟后,其實會有很多隱藏的bug:列表,向量和字典這三個數據類型
由於最終的比較是用向量,所以就必需化字典(stat和stat1)為向量,
但是,但是本人能力不足,不會直接字典到向量,所以采用先字典到列表,再列表到向量(基本上也復習了之前學的python的基礎)
很顯然基本數據類型里面沒有向量,所以調用numpy.array(這是找資料得到的)
做完上述的工作基本上沒有什么bug(其實也是自己實際運行中出現的)
補充:
數據結構的定義:
測試
說明:是通過terminal的窗口進入輸入直接結果,測試十次用的是給的樣本然后輸入是絕對路徑
基本上應該是可以,但還是存在問題就是了,結果如下:
測試性能
分為兩步一個時間還有就是覆蓋率
時間&內存:
取的是任意一個實例
性能測試補充:
改進方法:
jaccard的距離來衡量
0和異常處理:
不知道題目上結尾輸出0是什么意思
雖然已經有如下圖
但是我還是print
下面異常:
很簡單的方法,執行過程中出現任何異常都會拋出來。
但都是英文相當於沒做
psp表
補充一下最后發現要求的輸出文件自定義然后改為:
收獲:
- 一開始覺得自己不可能獨立的完成作業,或者比價早地完成作業(比預期要早)
- 第一次將自己的想法可以表述出來,當然其實我也是知道自己的代碼還存在問題:
在划分的時候我是每一個字計算,在已知抄襲的情況下肯定正確,但是很多時候我們可以幾個詞連在一起來判斷,這樣會避免誤判(也查了資料,但是好像需要jieba庫等等)
- 這次項目的難點我覺得每一步都是難點!,什么github的倉庫建立還有release,
- 希望下次可以做到將函數封裝起來。
附上代碼
import os
import copy
import numpy as np
import sys
from scipy.spatial.distance import pdist
x1 = sys.argv[0]
x2 = sys.argv[1]
x3 = sys.argv[2]
try:
fr = open(x1, 'r', encoding="utf-8")
fd = open(x2, 'r', encoding="utf-8")
# 從命令行讀取絕對路徑,打開文件fr和fd,文件內容為中文,采用gbk
# 中間為查重算法
# 預處理
content2 = fd.readlines()
contentLines2 = ''
characers = [] # 列表
stat = {} # 字典
content1 = fr.readlines()
contentLines1 = ''
characers1 = [] # 列表
stat1 = {} # 字典,items是鍵值對,keys是鍵,values是值
tochar = [] # 列表
for line in content1:
line = line.strip()
if len(line) == 0:
continue
contentLines1 = contentLines1 + line
for x in range(0, len(line)):
if not line[x] in tochar:
tochar.append(line[x]) ##所有的漢字種類
stat1[line[x]] = 0
stat[line[x]] = 0
for line in content2:
line = line.strip()
if len(line) == 0:
continue
contentLines2 = contentLines2 + line
for x in range(0, len(line)):
if not line[x] in tochar:
tochar.append(line[x])
stat1[line[x]] = 0
stat[line[x]] = 0
for line in content1:
line = line.strip() # 去空格
if len(line) == 0:
continue
contentLines1 = contentLines1 + line
for x in range(0, len(line)):
if not line[x] in characers1:
characers1.append(line[x])
if line[x] not in stat1:
stat1[line[x]] = 1
stat1[line[x]] += 1
##同理抄襲文件
for line in content2:
line = line.strip() # 去空格
if len(line) == 0:
continue
contentLines2 = contentLines2 + line
for x in range(0, len(line)):
if not line[x] in characers:
characers.append(line[x])
if line[x] not in stat:
stat[line[x]] = 1
stat[line[x]] = stat[line[x]] + 1
# 第二步按照排序(不知道后面的特征值是否需要)
##同理先原文件
# e[0]是按鍵划分,e[1]是按值划分
stat1 = sorted(stat1.items(), key=lambda e: e[0], reverse=True)
##之后的抄襲文件
stat = sorted(stat.items(), key=lambda e: e[0], reverse=True)
lis = []
# bug 修改 dic到list
for i in stat:
lis.append(i[1])
vec1 = np.array(lis)
vec1 = vec1.reshape(-1)
lis1 = []
for i in stat1:
lis1.append(i[1])
vec2 = np.array(lis1)
vec2 = vec2.reshape(-1)
""""
核心部分
fz = float(np.dot(vec1, vec2))
fz = round(fz, 6)
fm = float(np.linalg.norm(vec1) * np.linalg.norm(vec2))
fm = round(fm, 6)
result = float(fz / fm)
result = result * 7 - 6
result = round(result, 2)
"""
vec3 = np.vstack([vec1, vec2])
dist1 = pdist(vec3, 'jaccard')
fr.close()
fd.close()
with open(x3, 'w') as f:
f.write(str(dist1))
f.close()
except Exception as err:
print(err)
print("0")