Я ученый-компьютерщик, работающий над проблемой, которая требует некоторых статистических измерений, хотя (не очень хорошо разбираясь в статистике) я не совсем уверен, какую статистику использовать.
Обзор:
У меня есть ряд вопросов (конечно, с сайтов StackExchange), и с помощью этих данных я изучаю алгоритмы, которые будут находить вопросы, похожие на тот, который я задаю. Да, сайты StackExchange уже выполняют эту функцию, как и многие другие сайты вопросов и ответов. Что я пытаюсь сделать, так это проанализировать методы и алгоритмы, которые люди используют для выполнения этой задачи, чтобы увидеть, какие методы работают лучше всего. Моя проблема заключается в том, чтобы найти подходящие статистические показатели для количественного определения того, «какие методы работают лучше всего».
Данные:
У меня есть набор вопросов StackExchange, каждый из которых сохраняется так: {'questionID':"...", 'questionText':"..."}
. Для каждого вопроса у меня есть набор других вопросов, связанных с ним или из него. Ответчики на вопросы на сайтах StackExchange обычно добавляют в свои ответы ссылки на другие похожие сообщения, например: «Вы читали это сообщение [вставьте ссылку на сообщение здесь] того-то и того-то? Они решают аналогичную задачу». проблема..." Я считаю, что эти связанные вопросы "похожи" друг на друга.
Более конкретно, скажем, у нас есть вопрос A
. Вопрос A
содержит набор связанных вопросов {B, C, D}
. Итак, A_linked = {B, C, D}
. Моя интуиция подсказывает мне, что свойство транзитивности здесь неприменимо. То есть только потому, что A
похож на B
, а A
похож на C
, я не могу подтвердить, что B
похож на C
. (Или можно?) Однако могу с уверенностью сказать, что если A
похоже на B
, то B
похоже на A
.
Итак, чтобы упростить эти отношения, я создам набор похожих пар: {A, B}, {A, C}, {A, D}
Эти пары будут служить своего рода базовой истиной. Мы знаем, что эти вопросы похожи друг на друга, поэтому их достоверность сходства равна 1. Итак, similarityConfidence({A,B}) = 1
Что следует отметить в этой настройке, так это то, что мы знаем только несколько похожих вопросов для каждого вопроса в нашем наборе данных. Чего мы не знаем, так это того, похож ли другой вопрос E
на A
. Может быть похоже, может не похоже, мы не знаем. Так что наша «наземная истина» на самом деле является лишь частью правды.
Алгоритм:
Упрощенная версия псевдокода алгоритма такова:
for q in questions: #remember q = {'questionID':"...", 'questionText':"..."}
similarities = {} # will hold a mapping from questionID to similarity to q
q_Vector = vectorize(q) # create a vector from question text (each word is a dimension, value is unimportant)
for o in questions: #such that q!=o
o_Vector = vectorize(o)
similarities[o['questionID']] = cosineSimilarity(q_Vector,o_Vector) # values will be in the range of 1.0=identical to 0.0=not similar at all
#now what???
Итак, теперь у меня есть полное сопоставление оценок косинусного сходства между q и всеми остальными вопросами в моем наборе данных. Моя конечная цель — запустить этот код для многих вариантов функции vectorize()
(каждый из которых будет возвращать немного отличающийся вектор) и определить, какой вариант работает лучше всего с точки зрения оценок косинуса.
Проблема:
Так вот мой вопрос. Что теперь? Как мне количественно измерить, насколько хороши эти оценки косинуса?
Вот некоторые идеи измерений, которые я придумал (хотя мне кажется, что они несовершенны, неполны):
Какая-то функция ошибки, похожая на среднеквадратичную ошибку (RMSE). Итак, для каждого документа в списке достоверных сходств суммируйте квадрат ошибки (с ошибкой, грубо определяемой как
1-similarities[questionID]
). Затем мы разделим это накопление на общее количество похожих пар*2
(поскольку мы будем рассматриватьa->b
, а такжеb->a
). Наконец, мы возьмем квадратный корень из этой ошибки.- This requires some thought, since these values may need to be normalized. Though all variations of
vectorize()
will produce cosine scores in the range of 0 to 1, the cosine scores from twovectorize()
functions may not compare to one another.vectorize_1()
might have generally high cosine scores for each question, so a score of .5 might be a very low score. Alternatively,vectorize_2()
might have generally low cosine scores for each question, so a .5 might be a very high score. I need to account for this variation somehow. - Кроме того, я предложил функцию ошибки
1-similarities[questionID]
. Я выбрал 1, потому что мы знаем, что два вопроса похожи, поэтому наша уверенность в сходстве равна 1. Однако оценка косинусного сходства, равная 1, означает, что два вопроса идентичны. Мы не утверждаем, что наши «связанные» вопросы идентичны, просто они похожи. Это проблема?
- This requires some thought, since these values may need to be normalized. Though all variations of
Мы можем найти отзыв (количество возвращенных похожих документов/количество похожих документов), если мы установим порог, для которого вопросы мы возвращаем как «похожие», а какие нет.
- Although, for the reasons mentioned above, this shouldn't be a predefined threshold like
similarity[documentID]>7
because eachvectorize()
function may return different values.
- Although, for the reasons mentioned above, this shouldn't be a predefined threshold like
Мы могли бы найти отзыв @k, где мы анализируем только самые популярные посты.
- This could be problematic though, because we don't have the full ground truth. If we set
k=5
, and only 1 document (B
) of the 3 documents we knew to be relevant ({B,C,D}
) were in the top 5, we do not know whether the other 4 top documents are actually equally or more similar toA
than the 3 we knew about, but no one linked them.
- This could be problematic though, because we don't have the full ground truth. If we set
У тебя есть другие идеи? Как я могу количественно измерить, какая функция vectorize()
работает лучше всего?