您如何编写反抄袭网站的代码?

时间:2009-07-05 23:21:59

标签: php theory

首先,请注意,我对这样的事情是如何工作感兴趣,并且不打算为客户端等构建它,因为我确信可能已经存在开源实现。

算法如何在上传的文本中检测抄袭?它是否使用正则表达式将所有单词发送到索引,删除已知单词,如“the”,“a”等,然后查看不同文章中有多少单词相同?他们是否有一些神奇的相同单词将它标记为可能的副本?它使用levenshtein()吗?

我选择的语言是PHP。

更新

我正在考虑不在全球范围内检查抄袭,但更多的是在30个上传的论文中说。如果学生们一起完成了一个人的严格任务。

以下是一个声称这样做的在线网站:http://www.plagiarism.org/

5 个答案:

答案 0 :(得分:31)

良好的抄袭检测将根据文档类型(例如特定语言的文章或程序代码)应用启发式方法。

但是,您也可以应用一般解决方案。看看Normalized Compression Distance(NCD)。显然你无法准确计算文本的Kolmogorov complexity,但你可以简单地压缩文本。

较小的NCD表示两个文本更相似。一些压缩 算法将比其他算法提供更好的结果。幸运的是,PHP提供了支持 对于several压缩算法,您可以进行NCD驱动的抄袭 检测代码可以在任何时间运行。下面我将给出使用的示例代码 Zlib

PHP:

function ncd($x, $y) { 
  $cx = strlen(gzcompress($x));
  $cy = strlen(gzcompress($y));
  return (strlen(gzcompress($x . $y)) - min($cx, $cy)) / max($cx, $cy);
}   

print(ncd('this is a test', 'this was a test'));
print(ncd('this is a test', 'this text is completely different'));

的Python:

>>> from zlib import compress as c
>>> def ncd(x, y): 
...     cx, cy = len(c(x)), len(c(y))
...     return (len(c(x + y)) - min(cx, cy)) / max(cx, cy) 
... 
>>> ncd('this is a test', 'this was a test')
0.30434782608695654
>>> ncd('this is a test', 'this text is completely different')
0.74358974358974361

请注意,对于较大的文本(读取:实际文件),结果会更多 宣判。试一试并报告您的经历!

答案 1 :(得分:5)

我认为这个问题很复杂,并没有一个最好的解决方案。 您可以在整个文档级别(即,有人从网上下载整篇文章)一直到短语级别检测到单词的确切重复。在文档级别执行此操作非常简单 - 最简单的解决方案将采用提交的每个文档的校验和,并将其与已知文档的校验和列表进行比较。之后,您可以尝试检测想法的抄袭,或者找到直接复制然后稍微改变的句子,以便抛弃这样的软件。

要获得适用于短语级别的内容,如果需要任何级别的效率,您可能需要更加复杂。例如,您可以在段落之间寻找写作风格的差异,并将注意力集中在与纸张其他部分相比感觉“不合适”的段落上。

有很多关于这个主题的论文,所以我怀疑还没有一个完美的解决方案。例如,这两篇论文介绍了这类软件的一些一般性问题,并提供了大量参考资料,如果你愿意,可以深入研究。

http://ir.shef.ac.uk/cloughie/papers/pas_plagiarism.pdf

http://proceedings.informingscience.org/InSITE2007/IISITv4p601-614Dreh383.pdf

答案 2 :(得分:4)

这实际上取决于“从哪里开始”。 如果你在一个网站的背景下谈论,那与整个网络或会议图书馆或者......的差别很大......

http://www.copyscape.com/几乎证明可以做到。

基本概念似乎是

  • 做一些不寻常的谷歌搜索 单词序列
  • 对于每个结果,进行详细分析

详细的分析部分当然可以是相似的,因为它是1比1的比较,但定位和获取源文档是关键因素。

答案 3 :(得分:4)

为了在不那么大的字符串上获得更好的结果:

在字符串或小文本上直接使用NCD公式存在问题。 NCD(X,X)不为零(!)。要删除此工件,请减去自我比较。

请参阅http://leis.saocarlos.sp.gov.br/SIMILAR.php

上的similar_NCD_gzip()演示
function similar_NCD_gzip($sx, $sy, $prec=0, $MAXLEN=90000) {
# NCD with gzip artifact correctoin and percentual return.
# sx,sy = strings to compare. 
# Use $prec=-1 for result range [0-1], $pres=0 for percentual,
#     $pres=1 or =2,3... for better precision (not a reliable)  
# Use MAXLEN=-1 or a aprox. compress lenght. 
# For NCD definition see http://arxiv.org/abs/0809.2553
# (c) Krauss (2010).
  $x = $min = strlen(gzcompress($sx));
  $y = $max = strlen(gzcompress($sy));
  $xy= strlen(gzcompress($sx.$sy));
  $a = $sx;
  if ($x>$y) { # swap min/max
    $min = $y;
    $max = $x;
    $a = $sy;
  }
  $res = ($xy-$min)/$max; # NCD definition.

  # Optional correction (for little strings):
  if ($MAXLEN<0 || $xy<$MAXLEN) {
    $aa= strlen(gzcompress($a.$a));
    $ref = ($aa-$min)/$min;
    $res = $res - $ref; # correction
  }
  return ($prec<0)? $res: 100*round($res,2+$prec);
}

答案 4 :(得分:3)

嗯,首先你必须了解你的反对意见。

逐字抄袭应该是非常容易被发现的。最天真的方法是采用足够长度的单词元组,并将它们与你的语料库进行比较。足够的长度可以非常低。比较Google搜索结果:

"I think" => 454,000,000
"I think this" => 329,000,000
"I think this is" => 227,000,000
"I think this is plagiarism" => 5

所以,即使采用这种方法,你也很有机会找到一两场比赛(有趣的事实是:大多数罪犯都非常愚蠢)。

如果抄袭者使用同义词,改变了词序等,显然它会变得更加困难。您还必须存储同义词并尝试将语法结构标准化以保持相同的方法有效。当然,拼写也是如此(即尝试通过规范化进行匹配或尝试考虑匹配中的偏差,如在其他答案中发布的NCD方法)。

然而,最大的问题是概念性抄袭。这真的很难,如果没有解析每个句子的语义(即足够复杂的AI),就没有明显的解决方案。

但事实是,你只需要找到某种匹配。您无需查找完全匹配即可在语料库中查找相关文本。无论如何,最终的评估应该总是由人做出来,所以如果你找到一个不精确的匹配就没关系。

剽窃者大多是愚蠢和懒惰的,所以他们的副本也是愚蠢和懒惰的。有些人在他们的工作中投入了大量的精力,但这些作品一开始往往是非显而易见的剽窃,所以很难以编程方式进行追踪(即如果一个人难以识别抄袭,两个文本并排呈现,电脑很可能也会。对于所有其他80% - 或者如此,这种愚蠢的方法已经足够了。