譯者 | 布加迪
隨著數字內容越來越受歡迎,保護它們免受復制和濫用變得比以往更加重要。抄襲檢測工具可以幫助教師評估學生的作業,幫助機構審閱研究論文,幫助作家發現其知識產權被盜的現象。
構建抄襲檢測工具可以幫助您理解序列匹配、文件操作和用戶界面。您還可以探索自然語言處理(NLP)技術以改進您的應用程序。
Tkinter和Difflib模塊
要構建抄襲檢測器,您將使用Tkinter和Difflib模塊。Tkinter是一個簡單的跨平臺庫,可以用來快速創建圖形用戶界面。
Difflib模塊是Python/ target=_blank class=infotextkey>Python標準庫的一部分,它提供了用于比較字符串、列表和文件等序列的類和函數。有了它,您可以構建文本自動糾錯器、簡化版本控制系統或文本摘要工具之類的程序。
如何使用Python構建抄襲檢測器?
導入所需的模塊。定義一個方法load_file_or_display_contents(),它接受entry和text_widget作為參數。該方法將加載文本文件,并在文本組件中顯示內容。
使用get()方法提取文件路徑。如果用戶沒有輸入任何內容,使用askopenfilename()方法打開文件對話框窗口,選擇想要進行抄襲檢查的文件。如果用戶選擇了文件路徑,從頭到尾清除前一個條目(如果有的話),并插入所選擇的路徑。
復制
import tkinter as tk
from tkinter import filedialog
from difflib import SequenceMatcher
def load_file_or_display_contents(entry, text_widget):
file_path = entry.get()
if not file_path:
file_path = filedialog.askopenfilename()
if file_path:
entry.delete(0, tk.END)
entry.insert(tk.END, file_path)
以讀取模式打開文件,并將內容存儲在text變量中。清除text_widget的內容,并插入前面提取的文本。
復制
with open(file_path, 'r') as file:
text = file.read()
text_widget.delete(1.0, tk.END)
text_widget.insert(tk.END, text)
定義一個方法compare_text(),您將用它來比較兩段文本并計算它們的相似度百分比。使用Difflib的SequenceMatcher()類來比較序列并確定相似度。將自定義比較函數設置為None以使用默認比較,并傳遞想要比較的文本。
使用比率方法以浮點格式獲得相似度,可以用來計算相似度百分比。使用get_opcodes()方法檢索一組操作,可以用來高亮顯示文本的相似部分,并將其與相似度百分比一同返回。
復制
def compare_text(text1, text2):
d = SequenceMatcher(None, text1, text2)
similarity_ratio = d.ratio()
similarity_percentage = int(similarity_ratio * 100)
diff = list(d.get_opcodes())
return similarity_percentage, diff
定義一個方法show_similarity()。使用get()方法從兩個文本框中提取文本,并將它們傳遞給compare_text()函數。清除將顯示結果的文本框中的內容,插入相似度百分比。從之前的高亮顯示中刪除“same”標簽(如果有的話)。
復制
def show_similarity():
text1 = text_textbox1.get(1.0, tk.END)
text2 = text_textbox2.get(1.0, tk.END)
similarity_percentage, diff = compare_text(text1, text2)
text_textbox_diff.delete(1.0, tk.END)
text_textbox_diff.insert(tk.END, f"Similarity: {similarity_percentage}%")
text_textbox1.tag_remove("same", "1.0", tk.END)
text_textbox2.tag_remove("same", "1.0", tk.END)
get_opcode()方法返回五個元組:操作碼字符串、第一個序列的開始索引、第一個序列的結束索引、第二個序列的開始索引和第二個序列的結束索引。
操作碼字符串可以是四個可能的值之一:replace、delete、insert和equal。當兩個序列中的一部分文本不同,并且有人把一部分換成另一部分時,您將獲得replace。當文本的一部分存在于第一個序列而不存在于第二個序列時,您將獲得delete。
當文本的一部分在第一個序列中不存在但在第二個序列中存在時,您將獲得insert。當文本的部分相同時,您將獲得equal。將所有這些值存儲在適當的變量中。如果操作碼字符串是equal,向文本序列添加same標簽。
復制
for opcode in diff:
tag = opcode[0]
start1 = opcode[1]
end1 = opcode[2]
start2 = opcode[3]
end2 = opcode[4]
if tag == "equal":
text_textbox1.tag_add("same", f"1.0+{start1}c", f"1.0+{end1}c")
text_textbox2.tag_add("same", f"1.0+{start2}c", f"1.0+{end2}c")
初始化Tkinter根窗口。設置窗口的標題,并在其中定義一個框架。在兩個方向用適當的填充來組織框架。定義兩個標簽以顯示Text 1和Text 2。設置它應該駐留的父元素和它應該顯示的文本。
定義三個文本框,兩個用于要比較的文本,一個用于顯示結果。聲明父元素、寬度和高度,并將換行選項設置為tk.word,以確保程序在最近的邊界處對單詞換行,并且不中斷中間的任何單詞。
復制
root = tk.Tk()
root.title("Text Comparison Tool")
frame = tk.Frame(root)
frame.pack(padx=10, pady=10)
text_label1 = tk.Label(frame, text="Text 1:")
text_label1.grid(row=0, column=0, padx=5, pady=5)
text_textbox1 = tk.Text(frame, wrap=tk.WORD, width=40, height=10)
text_textbox1.grid(row=0, column=1, padx=5, pady=5)
text_label2 = tk.Label(frame, text="Text 2:")
text_label2.grid(row=0, column=2, padx=5, pady=5)
text_textbox2 = tk.Text(frame, wrap=tk.WORD, width=40, height=10)
text_textbox2.grid(row=0, column=3, padx=5, pady=5)
定義三個按鈕,兩個用于加載文件,一個用于比較。定義父元素、它應該顯示的文本,以及它在被點擊時應該執行的函數。創建兩個輸入組件來輸入文件路徑,并定義父元素及其寬度。
使用網格管理器以行和列的形式組織所有這些元素。使用pack來組織compare_button和text_textbox_diff。在必要的地方添加適當的填充。
復制
file_entry1 = tk.Entry(frame, width=50)
file_entry1.grid(row=1, column=2, columnspan=2, padx=5, pady=5)
load_button1 = tk.Button(frame, text="Load File 1", command=lambda: load_file_or_display_contents(file_entry1, text_textbox1))
load_button1.grid(row=1, column=0, padx=5, pady=5, columnspan=2)
file_entry2 = tk.Entry(frame, width=50)
file_entry2.grid(row=2, column=2, columnspan=2, padx=5, pady=5)
load_button2 = tk.Button(frame, text="Load File 2", command=lambda: load_file_or_display_contents(file_entry2, text_textbox2))
load_button2.grid(row=2, column=0, padx=5, pady=5, columnspan=2)
compare_button = tk.Button(root, text="Compare", command=show_similarity)
compare_button.pack(pady=5)
text_textbox_diff = tk.Text(root, wrap=tk.WORD, width=80, height=1)
text_textbox_diff.pack(padx=10, pady=10)
用黃色背景和紅色字體高亮顯示標記為相同的文本。
復制
text_textbox1.tag_configure("same", foreground="red", background="lightyellow")
text_textbox2.tag_configure("same", foreground="red", background="lightyellow")
mAInloop()函數告訴Python運行Tkinter事件循環并監聽事件,直到您關閉窗口。
復制
root.mainloop()
把它們放在一起,然后運行代碼以檢測抄襲。
抄襲檢測器的輸出示例
當您運行這個程序時,它會顯示一個窗口。點擊Load File 1按鈕后,將打開文件對話框,要求您選擇一個文件。選擇一個文件后,程序在第一個文本框內顯示內容。在輸入路徑并點擊Load File 2后,程序將在第二個文本框內顯示內容。在點擊Compare按鈕后,您得到的相似度為100%,它高亮顯示相似度100%的整個文本。
如果您為其中一個文本框添加另一行并點擊Compare,程序將高亮顯示相似的部分,并忽略其余部分。
如果幾乎沒有相似度,程序會高亮顯示一些字母或單詞,但相似度百分比非常低。
使用NLP進行抄襲檢測
雖然Difflib是一種功能強大的文本比較方法,但它對微小的變化很敏感,對上下文的理解有限,并且對于龐大文本而言通常無效。這時候您應該考慮探究自然語言處理,因為它可以執行文本的語義分析,提取有意義的特征,而且能夠理解上下文。
此外,您可以針對不同的語言訓練模型,并對其進行優化以提高效率。可以用于抄襲檢測的一些技術包括Jaccard相似性、余弦相似性、單詞嵌入、潛在序列分析以及序列到序列模型。
您可以在這個Github代碼倉庫中找到使用Python構建抄襲檢測器的全部源代碼:https://github.com/makeuseofcode/Plagiarism-Detector-using-Python
原文標題:How to Build a Plagiarism Detector Using Python,作者:Sai Ashish Konchada