Видел Ваш твит ранее. От дисплея этих 327 973 ссылок кажется, что Вы уже имеете в распоряжении одноэтапную разность. На основе этого я сфокусируюсь на составе мультиредактирования:
А, исходный плакат владеет 100% сообщения.
, Когда B, второй плакат, делает редактирования таким образом, что, например, 90% текста неизменно, владение является % A:90, % B:10.
Теперь C, третье лицо, изменяется на 50% текста. (% A:45, % B:5, % C:50)
, Другими словами, то, когда плакат делает редактирования таким образом, что x % изменяется и y = (100-x) %, неизменно, тогда тот плакат теперь владеет x % текста, и все предыдущее владение умножается на y %.
Для создания этого интересным теперь предположите...
А делает 20%-е редактирование. Тогда A владеет "новыми" 20%, и остаточные владения теперь умножаются на 80%, уезжая (% A:36, % B:4, % C:40). "Сетевое" владение поэтому (% A:56, % B:4, % C:40).
Применение этого к Вашему экземпляру (327973) со всем округленным к ближайшему проценту:
Версия 0: исходное сообщение.
Версия 1: Ваш текущий различный инструмент показывает чистое добавление текста, таким образом, все те символы принадлежат второму плакату.
Версия 2: разность показывает замену слова. Новое слово принадлежит третьему плакату, и оставшийся текст принадлежит предшествующим плакатам.
Версия 3: редактирование только для тега. Так как Ваш вопрос был о тексте, я игнорирую теги.
Версия 4: Добавление текста.
я надеюсь, что этого достаточно для предоставления смысла этого предложения. Это действительно имеет несколько ограничений, но я задвигаю их под Вашим оператором, что приближение приемлемо.;-)
Это скот вынужденно распределяет эффект изменения через всех предшествующих владельцев. Если сообщения, B делает чистое дополнение, и C редактирует половину того, какой добавленный B, этот упрощенный подход просто применяет владение C через все сообщение, не пытаясь проанализировать, какое предшествующее владение было изменено больше всего.
Это составляет дополнения или изменения, но не дает кредита владения на удаление, потому что средство удаления добавляет 0% к оставшемуся тексту. Можно или рассматривать это как ошибку или функцию. Я выбрал дверное Обновление номер 2.
: [еще 1143] о выпуске № 1 выше. Я полагаю, что полностью отслеживающий владение части сообщения, которое редактируется, потребовало бы одной из двух вещей (Поле веб-страницы не является достаточно большим для формального доказательства;-):
Изменение путем текст хранится для отражения владения отдельных частей текста (например, A владеет Word 1-47, B, владеет Word 48-59, A, владеет Word 60-94...), применяясь, "сколько остается" подходом в моем предложении к каждой части и обновлением данных владения части.
Рассмотрение всех версий от сначала до текущего (в действительности, повторно вычисляя данные владения части на лету).
, Таким образом, это - хороший пример компромисса между быстрым-и-грязным приближением (за счет точности), изменение во всей базе данных (за счет пространства), или каждое вычисление, имеющее необходимость смотреть на всю историю (за счет времени).
Начальному понятию нужно дать вес. Исправлениям орфографических ошибок нужно дать вес. Грамматике/структуре нужно дать вес. Формулировке нужно дать вес. Краткости нужно дать вес. И т.д.
Веса являются единственным справедливым способом сделать это, но также и невозможный определить.
Не уверенный, если это возможно, но Вы могли бы считать количество символов добавленным.
Пример:
, Если Вы возвращаетесь, необходимо также вернуться предыдущему пользователю/счетчику символов.
, Но... , возможно, это просто более просто и более справедливо назвать исходный плакат...
В долгом размышлении, я редактирую много, но я никогда не считаю меня "владельцем" tekst, потому что я просто изменяю представление (формат и грамматика), но не содержание.
Ключ к наличию хорошего решения этой проблемы должен получить дополнительную информацию о том, что продолжает редактирование. Дополнительной информацией, доступной в этом носителе, является голосование и показатель отклика к вопросам. Таким образом, если кто-то делает редактирование, которое приводит к вопросу, получая много upvotes, комментариев и ответов, их редактирование было очень ценно. Особые случаи, вероятно, существуют для совершенно нового оставшегося без ответа вопроса, который редактируется, прежде чем это было на сайте в течение очень долгого времени.
необходимо посмотреть на то, насколько сообщение изменило использование алгоритма расстояния Левенштейна и затем взвешивает их редактирование количеством голосов, комментариев, и отвечает на вопрос, получает после их редактирования.
Let n = total revisions
Let m = the revision number of a poster
Let post[it] = array with text of post at revision 'it'
Let votes[it] = votes that revision 'it' received (also add bonus for comments/answers)
value = 0
for (it = m; it < n; ++it) {
value += (Levenshtein(post[it-1], post[m]) / average_length_post) * (votes[it])
}
при вычислении значения для каждого сообщения владение сообщения является итоговым значением всех редактирований тем пользователем, разделенным на сумму всех значений редактирования для того сообщения.
Количество символов хитро, мне кажется.
Как насчет:
Break latest revision into a set of sentences.
//Sentence is any text fragment surrounded by punctuation
For each Sentence
Find which user created that sentence.
Add 1 to the user who created the sentence
Add 1 to the number of sentences
For Each user
% ownership = Count for that user / Number of sentences.
Открытие, какой пользователь создал то предложение.
Соответствие предложению к пересмотру легко, если бы Вы хотите точное совпадение, но я был бы более доволен частичным соответствием.
, Чтобы сделать это частичное соответствие...
Общие слова Полосы от части предложения и поиск, который разделил фрагмент в лишенной версии каждого пересмотра. Самый ранний хит является предложением, записанным владельцем.
Опции: (вместо разделения общего слова)
общие слова Разделения
, Вы уже делаете это для поиска, таким образом, библиотеки, и т.д. уже там. Даже при использовании кого-то elses формула Вы должны, возможно, CommonWordStrip каждый пересмотр перед запуском.
Как насчет этой идеи?
Дело в том, что после определенного количества изменения действительно не имеет значения, кто владеет им. Я соглашаюсь с пользователями, говорящими, что попытка присвоить "владельцам" содержанию Wiki контрпродуктивна.
Вопрос состоит в том, допустимо ли удаление символов так же как добавление их. Используя Разность может работать хорошо, но она не всегда следует за этим человек, который добавил, больше всего самый допустимый редактор (некоторые люди могут записать в 10 символах, что другие берут страницу для записи).
, Таким образом, я думаю, что у Вас есть два фактора здесь:
Следовательно я испытал бы желание записать что-то, что просто отображается, слова добавили/удалили к счету точек. Добавление к этой некоторой добротности (это должно было бы быть внешним параметром) и общей стоимости могло тогда использоваться в сортировке.
Вы могли возможно генерировать некоторую примитивную "добротность" на основе расстояния, которое она взяла, прежде чем объект был отредактирован. Таким образом, если что-то, что я записал, не было изменено до 12-го редактирования тогда это, возможно, не было также неправильно (относительно чего-то вроде меньшего качества, измененного, как только это было добавлено).
Это - wiki—, почему бы не позволить каждому редактору выбрать значение его изменения? Предоставьте выпадающему что-то как...
квалифицируйте свое редактирование:
Тогда используют объединенные ответы для оценки владения.
Это будет работать, если Вы захотите реализовать/усилить различное крыло алгоритма Python difflib
- необходимо будет, вероятно, сделать некоторую разность в любом случае. Этот отрывок называет пользователя с большей частью текстовой маслобойки победителем.
Оправдание мое жесткое кодирование.
#!/usr/bin/env python
import collections
import difflib
import logging
import pprint
import urllib2
import re
class OwnageDeterminer(object):
add_coefficient = 1
remove_coefficient = .5
def __init__(self, edits):
self.edits = edits
self.counts_by_username = {}
def __call__(self):
edits, counts_by_username = self.edits, self.counts_by_username
for i, edit in enumerate(edits):
username = edit['username']
unique_counts = {'added': 0, 'removed': 0}
existing_text = edits[i-1]['text'] if i > 0 else ''
new_text = edits[i]['text']
for char_diff in difflib.ndiff(existing_text, new_text):
if char_diff.startswith('+'):
unique_counts['added'] += 1
elif char_diff.startswith('-'):
unique_counts['removed'] += 1
user_counts = counts_by_username.get(username, collections.defaultdict(int))
user_counts['removed'] += self.remove_coefficient * unique_counts['removed']
user_counts['added'] += self.add_coefficient * unique_counts['added']
counts_by_username[username] = user_counts
winner = None
winning_score = 0
score_by_username = {}
for username, counts in counts_by_username.iteritems():
score = counts['removed'] + counts['added']
if score > winning_score:
winner = username
winning_score = score
score_by_username[username] = score
logging.debug('Scores: %s', pprint.pformat(score_by_username))
return winner
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
site = urllib2.urlopen('http://stackoverflow.com/revisions/327973/list')
contents = site.read()
regex = re.compile(r'(/revisions/viewmarkup/\d+).*?/users/\d+/([\w-]+)',
re.MULTILINE|re.DOTALL)
revisions = regex.findall(contents)
print revisions
edits = []
for reluri, username in sorted(revisions, key=lambda t: t[0]):
text = urllib2.urlopen('http://stackoverflow.com{0}'.format(reluri)).read()
edit = {'username': username, 'text': text}
edits.append(edit)
od = OwnageDeterminer(edits)
print od()
вывод:
DEBUG:root:Scores: {'blorgbeard': 0.5,
'dave-markle': 0.5,
'dbr': 1172.0,
'gatekiller': 69.5,
'joseph-ferris': 0.0,
'lkessler': 0.0,
'mark-harrison': 592.0,
'mdb': 3.0,
'onebyone-livejournal-com': 0.0,
'paul-oyster': 482.0,
'rob-wells': 0.0,
'simucal': 1070.5,
'skiphoppy': 0.0,
'thesoftwarejedi': 701.0}
dbr
документы Difflib на сложности:
Синхронизация: основной алгоритм Ratcliff-Obershelp является кубическим временем в худшем случае и квадратичное время в ожидаемом случае. SequenceMatcher является квадратичным временем для худшего случая и имеет зависимого поведения ожидаемого случая сложным способом на том, сколько элементов последовательности имеют общего; лучшее время случая линейно.
Другая хорошая вещь состоит в том, что это вычисление победителя линейно, таким образом, можно кэшировать исходные результаты и сделать инкрементные обновления на новых редактированиях, несмотря на большую загрузку инициализации.
Что относительно того, чтобы просто вычислить расстояние Левенштейна из редактирования каждого человека к предыдущей версии. Тогда суммируйте очки расстояния к каждому пользователю и вычислите процент пользователя суммы очков расстояния всех пользователей.
Никто не владеет им. Вознаграждение владения нарушает дух "общественной Wiki" и может привести к контрпродуктивным войнам правок.
Если я понимаю Ваш вопрос правильно, похоже, что Вы пытаетесь сделать то, что IBM действительно некоторое время поддерживала исследовательским проектом Википедии. А именно, наблюдение, кто изменения текста где наиболее принятый другими пользователями и как полный текст, изменяемый со временем. Название проекта было поток истории и поток истории - как это работает , дает довольно хороший обзор того, как их алгоритм работал.
Первое, что пришло на ум я сделал бы что-то вроде этого:
Я думаю, что идея существенно испорчена.
, Если кто-то пишет блестящий анализ с ужасным написанием и неясными примерами, и я копирую, редактируют его экстенсивно, я создал 60% работы? Очевидно нет; результатом является производная, куда большая часть значения прибывает из первоначального плаката. Полезная мера не возможна на основе счетчиков символов или подсчетов слов, но требует сильного семантического анализа уровня AI.
Вполне кроме этого, ища кредит на основе “ownership” статей, вероятно, было бы совершенно бесполезно и анти-Wiki. На Википедию, например, люди, которые действуют, как будто они владеют статьями, являются одним из самых разрушительных влияний.
Вот то, как я вижу владение сообщения в качестве примера (примечание, я забыл добавлять теги к тексту вообще, таким образом, простые изменения тега не считаются в этом примере здесь, но могут легко быть добавлены):
лоб Удара : Человек, я использовал числа пересмотра вместо кодов пользователя. Результаты, восстановленные ниже:
User 38193 owns 42% (922 / 2171) of the final post
User 2635 owns 28% (625 / 2171) of the final post
User 116 owns 24% (529 / 2171) of the final post
User 745 owns 3% (76 / 2171) of the final post
User 13005 owns 0% (11 / 2171) of the final post
User 18941 owns 0% (5 / 2171) of the final post
User 8562 owns 0% (3 / 2171) of the final post
53 ms
Так согласно моему алгоритму, пользователь 38193 ( Paul Oyster ) владеет 42% сообщения, тогда как сообщение 2635 ( Simucal) имело 28%, и у пользователя 116 ( Mark Harrison ) есть 24%, остальное незначительно.
От эти изменения , мы видим, что Paul, который является исходным автором, все еще владеет большей частью вопроса, и Simucal и Mark входят на хорошем номере 2 и 3. Они соответствуют изменениям номер 1 (исходное сообщение), номер 14, который является большим редактированием Simucal, и который похож на него, показывает дефект в моем алгоритме вполне приятно (см. ниже), и номер 5, где Mark добавил сценарий удара.
Поэтому, как я достигал этого ответа? Ну, алгоритм имеет дефект, но я возвращусь к нему, но сюда - как он идет:
В основном каждому байту в исходном сообщении присваивают идентификатор пользователя пользователя, который записал это. Тогда я использую различный алгоритм, который может обработать копии не в порядке, которые тогда возьмут с собой идентификатор пользователя байтов, скопированных новым автором. Чему-либо добавленному новым автором присваивают идентификатор пользователя нового автора.
, Например, если исходный автор пишет два предложения, они будут отмечены с его идентификатором пользователя. Тогда другой автор пересматривает его и добавляет третье предложение между исходными двумя. К различному алгоритму это похоже на нового автора, скопировали первое предложение, добавили новые данные и скопировали второе предложение. Предложения будут таким образом правильно приписаны своим авторам.
Начиная с различных работ алгоритма над байтами, незначительные текстовые изменения как добавление недостающей пунктуации или букв должны оказать незначительное влияние на владение, и почти весь оригинальный текст должен все еще быть приписан исходному автору. Однако в некоторых случаях это будет использовать, "добавил данные" операция даже при том, что просто единственный байт был добавлен, из-за внутренней оптимизации. Алгоритм и его реализация были первоначально созданы для обработки файла diffs и создания самых маленьких патчей между версиями файла, и будут иногда оптимизировать далеко незначительные шаги в пользу объединения его в одноуровневую операцию, если это уменьшит размер файла.
дефект в алгоритме прибывает из откатов. Я отмечаю, что у Jeff есть запись в комментарии, что откаты не рассмотрят, но если пользователь редактирует сообщение вместо того, чтобы откатывать ее и просто вставляет в старом материале, в действительности обращая изменение предыдущим автором, то весь текст приписывается человеку, "откатывающему" вместо исходного автора, который придумал информацию.
исходный код для этой реализации может быть найден здесь для Visual Studio 2008. Обратите внимание, что решение не делает ничего как screenscrape или что-либо, и содержание сообщения является hardcoded в источник в классе TestData, которого правильно оставляют для кавычек, и т.д. Для замены текста, необходимо изменить тот файл или реализовать способ считать содержание из за пределами программы.
Так или иначе, вот алгоритм в немного большем количестве деталей.
<час>На данном этапе, у Вас есть список идентификатора пользователя, который говорит Вам, какой пользователь добавил каждый символ.
операции от сравнения один из два:
, Как результат сравнения используется, то, что Вы берете старое содержание (первое сообщение) и применяете операции к нему, и Вы тогда производите следующий пересмотр. Это - в основном различное
, Когда я применяю операции к своему списку идентификатора пользователя, когда я копирую, я просто копирую, когда я вставляю, я всегда вставляю много идентификаторов, равных длине, сохраненной в операции.
Позволяют мне дать пример:
Исходное сообщение:
This is the first post
Следующее сообщение:
This is the next post, it is based on the first post.
список операций таким образом был бы:
, Если бы я вместо этого работаю с идентификатором пользователя, у меня был бы сначала этот массив:
0000000000000000000000
This is the first post
Теперь я применяю операции, и для каждой вставки, я вставляю 1 вместо этого:
00000000000011110000011111111111111111000000000000001
This is the next post, it is based on the first post.
Теперь я просто рассчитываю, сколько 0 и 1's я имею:
Пользователь 0 владеет 31 / (31+22) из сообщения, и пользователь 1 владеет 22 / (31+22) из сообщения.
Переведенный в проценты: пользователь 0 владеет 58%, пользователь 1 владеет 42%.
Теперь, проблемой с этим алгоритмом является проблема откатов, и добавляющий назад терял/удалял содержание.
, Например, если у Вас есть пользователи A, B и C и пользователь сообщения что-то, что действительно убирает галочку в пользователе B, пользователь B входит и удаляет все и добавляет просто, "ЭТО - ДЕРЬМО". Когда пользователь C видит это, он редактирует сообщение и добавляет назад все что отправленный, возможно с мерами. Пользователь C теперь владеет 100% сообщения.
я не знаю, как решить вышеупомянутую проблему все же.
я отправлю код, который делает это позже сегодня вечером, если это интересно.
<час>Относившийся 'быстрая коричневая лиса' пример, перенумеровывая пользователей к 1-3, я получаю это:
User 3 owns 75% (45 / 60) of the final post
User 1 owns 25% (15 / 60) of the final post
Примечание, что пользователь 2, который только добавлял 'иногда' часть, которая была впоследствии удалена, удален из списка.
идентификатор для сообщений как таковы:
The quick brown fox jumps over the lazy dog.
11111111111111111111111111111111111111111111 (44 = 100%)
The quick brown fox jumps, sometimes.
1111111111111111111111111222222222222 (25 / 12 ~ 68% / 32%)
I always see the speedy brown fox jumping over the lazy dog.
333333333333333333333331111111111111113333333333333333333333 (45 / 15 = 75% / 25%)
<час> Вещи алгоритм справится:
, Если я копирую что-то при создании моего нового сообщения, алгоритм правильно припишет скопированные элементы, даже если я теперь скопирую части, из которых я также добавил. Пример:
This is the first post, which is cool
1111111111111111111111111111111111111
This is the second post, which is the second post.
11111111111122222211111111111111112222222222111111
^-- copied ------^
единственная проблема с этим algorith и этим сообщением в целом состоит в том, что я не совсем уверен, что это производит то, что я назвал бы интуитивно справедливым результатом. Это могло быть, я просто взломал вместе программу, но намного больше тестирования с партиями и большим количеством пограничных случаев, вероятно, будет в порядке, чтобы определить, производит ли это на самом деле что-то, что люди приняли бы.
кроме того, если я просто перемещаю материал от первого сообщения, только незначительные биты, как несколько процентов, будут моими. Так как алгоритм является различным алгоритмом в глубине души, иногда стоимость вывода операции копии всего для 1 или несколько байтов перевешивает стоимость просто вставки его сырые данные, так же иногда он будет рассматривать короткую последовательность байтов, как вставлено, хотя они, возможно, были скопированы с исходного сообщения.