Какой лучший алгоритм для проверки процента сходства среди представленных заданий? - PullRequest
0 голосов
/ 26 февраля 2019

Я планирую построить проект для последнего года, который похож на проверку сходства.В проекте я планирую проверить процент сходства среди представленных заданий, т.е. в автономном режиме.

Например:

  1. Когда первый студент отправляет задание, этоне проверяется с другими заданиями.

  2. Когда второй студент отправляет задание, оно проверяется с первым заданием.

  3. Когда третийстудент отправляет задание, оно проверяется с помощью первого и второго отправленных заданий.

  4. Аналогичным образом, если имеется 35 учеников, то 36 представленное задание проверяется с остальными из 35 представленных заданий.

Теперь возникает вопрос о том, как сравнить два назначения.В этом случае сравнение сходства между текстами в документах.Я хочу, чтобы результат был похож на этот:

Similarity checking between the documents

Я просто хочу показать процент похожих предложений и их значения?

Что я сделал:

Я изучил различные алгоритмы, такие как td-idf, алгоритм косинусного сходства, но я не могу правильно интерполировать результаты алгоритма.

Итак, я хочу знать, какой алгоритмлучший в этой ситуации, и я хочу знать, как это делается.Есть ли ссылки на какие-либо сайты, блоги, которые мне помогли бы?

1 Ответ

0 голосов
/ 27 февраля 2019

Это зависит от того, как используемый вами алгоритм возвращает результаты сравнения.

Например, следующая функция сравнивает список содержимого документа и возвращает словарь пар документов, сопоставленных списку общих последовательностей слов между ними.,Он не делает различий между последовательностями слов, которые включены друг в друга, потому что может быть различное количество вхождений более длинных и коротких последовательностей слов, которые перекрываются.

import re
from itertools import combinations

def wordList(document): return re.findall("(\w+|\d+)",document.lower())

def compareDocs(documents, minSize=2, maxSize=25):
    result  = dict() # { (documentIndex,documentIndex) : [CommonExpressions] }
    def tallyDuplicates(expressionDocs):
        for expression,docIndexes in expressionDocs.items():
            for docIndex,otherDoc in combinations(docIndexes,2):
                result.setdefault((docIndex,otherDoc),[]).append(expression)

    documentWords    = [ wordList(document) for document in documents ]
    wordCounts       = [ len(words) for words in documentWords ]
    expressionRanges = dict()
    for docIndex,words in enumerate(documentWords):
        for wordIndex,word in enumerate(words):
            expressionRanges.setdefault(word,[]).append((docIndex,wordIndex))

    size = 1    
    while size == 1 or expressionDocs and size <= maxSize:        
        nextExpressions   = dict()
        expressionDocs    = dict()
        for expression,starts in expressionRanges.items():
            for docIndex,startIndex in starts:
                endIndex = startIndex+size
                if endIndex >= wordCounts[docIndex]: continue
                extended = " ".join([expression,documentWords[docIndex][endIndex]])
                expressionDocs.setdefault(extended,set()).add(docIndex)
                nextExpressions.setdefault(extended,[]).append( (docIndex,startIndex) )
        expressionDocs   = { expression:docIndexes for expression,docIndexes in expressionDocs.items() if len(docIndexes) > 1 }
        expressionRanges = { expression:ranges for expression,ranges in nextExpressions.items() if expression in expressionDocs }  
        if size >= minSize: tallyDuplicates(expressionDocs)
        size += 1

    return result

На основе этих результатов сравнения необходимо проанализироватьсодержимое каждой пары документов для подсчета слов, охватываемых общими выражениями (последовательностями слов).Учитывая, что выражение содержит несколько слов, каждое выражение будет учитывать несколько слов в соотношении сходства: слова-выражения-совпадения / слова-в-документе.

[РЕДАКТИРОВАТЬ] I Поместил анализ результатов в свою собственную функцию и добавил вывод html для выделения выражений в текстах документов:

def analyzeComparison(doc1,doc2,commonExpr):
    words1  = wordList(doc1)
    words2  = wordList(doc2)
    normalizedDoc1 = " ".join(words1)
    normalizedDoc2 = " ".join(words2)
    expressions.sort(key=lambda s:len(s),reverse=True)
    matches = []
    for expression in expressions:
        count1 = len(re.findall(expression,normalizedDoc1))
        count2 = len(re.findall(expression,normalizedDoc2))
        commonCount = min(count1,count2)
        if commonCount == 0: continue
        expressionId = "<#"+str(len(matches))+"#>"
        normalizedDoc1 = re.sub(expression,expressionId,normalizedDoc1,commonCount)
        normalizedDoc2 = re.sub(expression,expressionId,normalizedDoc2,commonCount)
        matches.append((expression,commonCount))
    commonWords = sum( count*len(expr.split(" ")) for expr,count in matches)
    percent1 = 100*commonWords/len(words1)
    percent2 = 100*commonWords/len(words2)
    for index,match in enumerate(matches):
        expressionId = "<#"+str(index)+"#>"
        expressionHighlight = "<span style='background-color:yellow'>"+match[0]+"</span>"
        normalizedDoc1 = re.sub(expressionId,expressionHighlight,normalizedDoc1)
        normalizedDoc2 = re.sub(expressionId,expressionHighlight,normalizedDoc2)
    return (percent1,percent2,matches,normalizedDoc1,normalizedDoc2)

Например: если у вас есть следующие 3документы (как правило, вы читаете их из файлов):

doc1 = """
Plagiarism, one of the main scourges of the academic life, is quite an easy concept, but, nonetheless, harmful. In short, to plagiarize means to steal someone else’s idea or part of work and use it as your own. But why exactly it is considered to be so bad and immoral? And it is really considered immoral and a serious offence. In case it is discovered, it may lead to very unpleasant consequences; the higher the position of the offender is, the more unpleasant they are.
copy and paste
There are two major kinds of harm plagiarism causes. First, it is something as simple as stealing and lying – you just steal someone else’s work and trick somebody into believing it was you who had written it, which is as immoral as any other kind of theft is. It means that somebody had actually spent time and effort in order to create something, while you did nothing but ripping it off and submitting it.
copy and paste function
Second, it is a crime you commit against yourself. If you study at an educational institution, there are certain tasks copy and paste you are given in order to ensure that you learn something. When you resort to plagiarism, you undo all these efforts for, instead of actually doing something and understanding it in process, you use someone else’s work and the certain amount of experience that you were supposed to get just misses you.
"""
doc2 = """
Plagiarism has always been a problem in schools. However, with the invention of the internet,copy and paste  it has made plagiarism even more of a challenge. Plagiarism.org, “estimates that nearly 30 percent of all students may be plagiarizing on all their written assignments and that the use of the Internet has made plagiarism much worse.” [1] The act of plagiarism can be defined as, “To steal and pass off (the ideas or words of another) as one’s own, to use (another’s production) without crediting the source, to commit literary theft, to present as new and original as idea or product derived from an existing source”2. Plagiarism has become such a concern for colleges that almost all the sites on this topic are sponsored by schools. The three main topics with plagiarism are the copy and paste function, “paper mills” and the ways that can be used to prevent students from doing this. 
it is quite an easy concept
The first major concern with the internet would be the copy and paste function. Wittenberg copy and paste function lists that “Widespread availability of the internet and increased access to full text databases has made cut and paste plagiarism very easy”.3 While the function is actually very nice to have, people are using it the wrong way. Instead of just using it to copy quotes from websites, than pasting it to their word document and giving it the proper credit, people are passing it off as their own. This is where the problem occurs.
"""

doc3 = """
Plagiarism has always been a problem in schools. However, it is something as simple as stealing and lying
it is a crime you. some other text
"""

Сначала вы должны вызвать compareDocs () в списке содержимого документа, и для каждой пары документов (возвращаемых функцией) вы быиспользуйте analyComparison (), чтобы получить проценты, счетчики и выделения:

documents   = [doc1,doc2,doc3]
comparisons = compareDocs( documents )
for documentPair,expressions in comparisons.items():
    docIndex1,docIndex2 = documentPair
    doc1 = documents[docIndex1]
    doc2 = documents[docIndex2]        
    pct1,pct2,matches,doc1,doc2 = analyzeComparison(doc1,doc2,expressions)

    # print result on console ...
    print(int(pct1//1)," % of document #",docIndex1," is same as document #", docIndex2)
    print(int(pct2//1)," % of document #",docIndex2," is same as document #", docIndex1)
    print("Common expressions are:")
    for expression,count in matches:
        print( "    ",expression,"(",count,"times )")
    print("")

    # output comparison result to an HTML file...
    htmlPage = "<html><body><table border='1'>"
    htmlPage += "<tr><th>#" + str(docIndex1) + ": Source " + str(int(pct1//1)) + "% duplicate</th>"
    htmlPage += "<th>#" + str(docIndex2) + ": Target  " + str(int(pct2//1)) + "% duplicate</th></tr>"
    htmlPage += "<tr><td width='50%' valign='top'>" + doc1 + "</td><td valign='top'>" + doc2 + "</td></tr>"
    htmlPage +="</table></body></html>"        
    fileName = str(docIndex1)+"-"+str(docIndex2)+".html"
    with open(fileName,"w") as f: f.write(htmlPage)       

Это распечатывает следующую информацию и создает группу файлов HTML, которые выглядят аналогично желаемому результату:

3.0  % of document # 1  is same as document # 2
34.0  % of document # 2  is same as document # 1
Common expressions are:
     plagiarism has always been a problem in schools however ( 1 times )

6.0  % of document # 0  is same as document # 1
5.0  % of document # 1  is same as document # 0
Common expressions are:
     is quite an easy concept ( 1 times )
     copy and paste function ( 1 times )
     copy and paste ( 2 times )

5.0  % of document # 0  is same as document # 2
53.0  % of document # 2  is same as document # 0
Common expressions are:
     it is something as simple as stealing and lying ( 1 times )
     it is a crime you ( 1 times )

Подводя итог, можно сказать, что весь процесс работает следующим образом:

1) запустить функцию сравнения, чтобы определить выражения (последовательность слов), которые являются общими для каждой пары документов.

  • Функция CompareDocs делает это за один вызов, учитывая список текстов документов.
  • Если вы используете другой алгоритм сравнения, он может быть разработанчтобы выполнить сравнение только между двумя документами или, в случае классификаторов, он может просто вернуть список частот слов / терминов для одного документа.
  • , в зависимости от входных и выходных данных алгоритма, вам нужно будет обернутьлогика в более или менее вашем собственном коде для получения желаемого результата
  • На этом этапе вы должны искать список общих выражений (словосочетаний) между различными парами документов.
  • Если вы работаете с алгоритмом, который извлекает только частоты терминов (например, td-idf), у вас возникнет проблема высокой сложности, связанная с перекрестным совпадением частот терминов между парами документов.

    Например, классификатор может возвращать частоты: "вырезать" = 25 раз, а "= 97 раз" вставить "= 31 раз для данного документа.Это не дает никаких указаний на то, что выражение «вырезать и вставить» действительно присутствует в документе или сколько раз оно будет там.В документе может быть речь о зубной пасте, и эти три слова никогда не должны быть в последовательности.Сравнение документов, основанных только на частотах слов, обнаружит высокую корреляцию между эссе по той же теме, но это не означает, что был плагиат.

    Кроме того, даже если вашему классификатору удастся вернуть все выражения двух или более словкаждый документ будет генерировать выражения, близкие к w * 2 ^ n, где w - количество слов в документе, а n - максимальная длина выражений в количестве слов (максимум, который вам нужно будет решить).Это легко достигнет миллионов на документы, а затем вам нужно будет сопоставить их с миллионами в других документах.Это может не быть проблемой, если у вас есть ресурсы Google, но это было бы для остальных из нас.

2) Чтобы измерить% сходства между документами, вам нужно найтиобщие выражения с обеих сторон и измерьте, сколько слов каждого документа покрыто общими выражениями.

  • Определение местоположения выражений - это простой процесс поиска текста
  • Однако вам необходимо избегать подсчета любого данного слова более одного раза, поскольку знаменателем вашего процента является количество слов в документе (и вы не хотите переоценивать или превышать 100%)
  • Этого можно достичь, обработав сначала более длинные выражения и удалив их из текста (или замаскировав их), чтобы их слова не учитывались снова последующими (более короткими) выражениями
  • Функция analysisComparison () маскирует выражениякоторые найдены в тексте, заменив их заполнителем, который впоследствии будет использоваться для повторного введения текста с подсветкой тегов (HTML).

3) Используйте анализ сравнения документов в своемсобственная программа.Это зависит от того, как вы хотите представить информацию и нужно ли вам сохранять результаты или нет (на ваше усмотрение).Например, вы можете выбрать порог сходства и выводить только подозрительные пары документов.Этот порог может основываться на процентах, количестве общих выражений, максимальной или средней длине общих выражений и т. Д.

[EDIT2] Как работает CompareDocs ...

  • Функция создает словарь выражений, который сопоставляет их с позицией их первого слова в каждом документе.Это хранится в переменной expressionRanges.

    • пример: {"копировать и вставить": [(0,57), (1,7), (1,32)] ....}
    • Это означает, что выражение из трех слов «копировать и вставить» находится в документе № 0 в позиции 57 (позиция слова «копировать») и в документе № 1 в позициях 7 и 32.
  • Словарь выражений (expressionRanges) начинается с выражений, состоящих из одного слова, и использует его для перехода к выражениям из 2 слов, затем к 3 словам и т. Д.

  • Прежде чем перейти к следующему размеру выражения, словарь выражений очищается путем удаления всех выражений, найденных только в одном документе.

    • размер 1==> {"copy": [(0,57), (0,72), (1,7), (1,32), (1,92)] ...}
    • clean-вверх ...
    • размер 2 ==> {"копировать и": [(0,57), (1,7), (1,32), (1,92)] ...}
    • очистка ...
    • size 3 ==> {"копирование и вставка": [(0,57), (1,7), (1,32)]...}
  • Эта очистка достигается путем создания отдельного словаря (expressionDocs), который отображает выражения в набор индексов документов, которые содержат выражение.Выражения, которые заканчиваются только одним документом в своем наборе, удаляются из обоих словарей.

  • Словарь expressionDocs также используется для создания выходных данных функции.Выражения, которые появляются в более чем одном документе, отображаются в пары документов (комбинации по 2), образуя словарь, содержащий: {(пара документов): [список выражений]} (который является результатом функции)
  • Подфункция tallyDuplicates выполняет преобразование из {Выражение: [список индексов документов]} в {(пара документов): [список выражений]}, добавляя выражение к каждой комбинации из 2 в списке индексов документов.

Последовательное уточнение expressionRanges значительно сокращает количество совпадений слов для выполнения.Каждый проход просто добавляет одно слово к каждому выражению и немедленно очищается перед переходом к следующему размеру выражения.Словарь expressionRanges начинается с такого количества записей, как в документах есть отдельные слова, но быстро уменьшается до гораздо меньшего размера (если документы практически не идентичны).

Одним из недостатков этого подхода является то, что документы, которые имеют большое количество очень длинных совпадающих выражений, приведут к тому, что словарь будет расти, а не сокращаться, а цикл while будет работать намного дольше.В худшем случае будут два идентичных документа.Этого можно избежать, введя максимальный размер выражения, чтобы цикл останавливался раньше.Например, если вы установили максимальный размер 25, функция будет сообщать только общее выражение из 25 слов и общее выражение из 5 слов вместо выражения из 30 слов, если оно есть.Это может быть приемлемым компромиссом, чтобы избежать очень длительного времени обработки, которое может повлечь за собой почти идентичные документы.Что касается процента подобия, разница будет минимальной.(т.е. одно общее слово может быть проигнорировано, если есть общее выражение из 26 слов, а максимальное - 25, но выражение из 27 слов будет выглядеть как совпадение 25 слов и 2 слов)

...