Как мне написать функцию для сравнения и ранжирования множества наборов логических (true / false) ответов? - PullRequest
3 голосов
/ 23 июля 2010

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

I 'Я гуглил далеко и широко, но все еще не придумал много, поэтому я надеялся, что кто-нибудь сможет указать мне правильное направление.Я хотел бы знать:

Какова лучшая структура данных и метод для хранения данных такого типа? Я изначально предполагал, что мог бы создать две таблицы "вопросы" и "ответы""в базе данных SQL.Однако мне не интересно, будет ли проще сравнивать два набора ответов, если они оба указаны в виде числовой строки.Т.е. 0 = не ответил, 1 = верно, 2 = ложно.При сравнении весов строк можно было бы добавить «не отвечено» = 0, «тот же ответ» = 1, «противоположный ответ» = -1, что дает оценку сходства.

Как бы я сравнилдва набора ответов? Чтобы понять «сходство» между этими наборами ответов, мне нужно написать функцию сравнения.Кто-нибудь знает, какое сравнение лучше всего подойдет для этой проблемы?Я рассмотрел выравнивание последовательности , и я думаю, что это может быть правильным путем, но я не уверен, так как это требует, чтобы данные были в длинной последовательности, плюс вопросы не связаны, так чтоне является ли это последовательностью.

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

I 'Буду очень признателен за любые полезные советы.Спасибо!

Ответы [ 4 ]

1 голос
/ 23 июля 2010

Вместо того, чтобы кластеризовать пользователей, вы также можете рассмотреть вопрос о кластеризации вопросов (например, OkCupid ). Затем вместо сравнения пользователей по всем ответам вы сравниваете их по категориям.

1 голос
/ 23 июля 2010

Хранение данных: Я бы сказал, что база данных - хорошая идея (звучит как потенциал для довольно большого набора данных). Я не знаю, сколько вопросов вы планируете иметь, но чтобы немного упростить анализ (включая ваши запросы SQL), вы можете сгруппировать ответы на подобные вопросы в отдельных таблицах. И я согласен, что использование числового значения (байт 0-2) будет хорошим способом выбора вместо логического или чего-то еще. Вы вычисляете показатель сходства, поэтому можете начать с цифр.

Сравнение: Что касается самого сравнения, я бы предложил создать класс SimilarQuestionAnswers, который содержит список байтов, и класс UserAnswers, который содержит список этих SimilarQuestionAnswers. Он настраивает ваши кластеры на метод кластерного анализа, который вы упомянули. Таким образом, вы можете добавить вес к определенным кластерам. (кластер a является важным кластером, поэтому его оценка умножается на 20, тогда как кластер b не так важен, поэтому его оценка умножается только на 10). Это также позволяет применять различные сравнения для каждого кластера, если это необходимо.

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

Сравнение применено: Здесь вам пригодится база данных. Используйте запросы SQL, чтобы минимизировать набор данных, с которым вы имеете дело. Если вы сравниваете одного человека со всеми остальными, вы можете использовать метод суммы SQL в их ответах, чтобы получить быстрое и грязное сравнение в каждом кластере и получить только тех, кто находится в пределах определенного порога. Это может привести к некоторому дублированию, но это можно легко устранить.

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

В любом случае, в конце концов, вам все равно потребуется выполнить сравнение с каждым из пользователей, которых вы получите по этому запросу. Таким образом, чем быстрее вы сможете сделать это сравнение, тем лучше. Попробуйте придерживаться формулы, которая включает только +, -, *, / большинство методов Math. Какие бы () ни добавляли много времени при большом количестве вызовов.

Извините, что это было так долго, большинство вопросов было довольно открытым, и мне пришлось принять некоторые детали. Надеюсь, это поможет.

1 голос
/ 23 июля 2010

Я думаю, вам может понадобиться вес за вопрос, основанный на ответах всех пользователей.В крайнем случае, если 1000 человек ответили на вопросы A и B, а результаты были A (2Y, 998N) и B (500Y, 500N), два Y для A значат намного больше, чем любая пара Y из B.И любая подобная пара из B несколько более похожа, чем любая пара N из A.

Проверьте Байесовская вероятность

1 голос
/ 23 июля 2010

Если бы вы установили его в SQL с таблицами для пользователей, вопросов и ответов, то я считаю, что следующий SQL-запрос можно использовать для получения других пользователей с аналогичными ответами.Просто добавьте предложение TOP, чтобы получить желаемое число.

Я не знаю, как будет производительность, но это будет во многом зависеть от размера ваших данных.

SELECT
    U2.userid,
    SUM(CASE
            WHEN A1.answer = A2.answer THEN 1
            WHEN A1.answer <> A2.answer THEN -1
            WHEN A1.answer IS NULL OR A2.answer IS NULL THEN 0  -- A bit redundant, but I like to make it clear
            ELSE 0
        END) AS similarity_score
FROM
    Questions Q
LEFT OUTER JOIN Answers A1 ON
    A1.question_id = Q.question_id AND
    A1.userid = @userid
LEFT OUTER JOIN Answers A2 ON
    A2.question_id = A1.question_id AND
    A2.userid <> A1.userid
LEFT OUTER JOIN Users U2 ON
    U2.userid = A2.userid
GROUP BY
    U2.userid
ORDER BY
    similarity_score DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...