Вычисление релевантности пользователя на основе конкретных данных
В настоящее время я пытаюсь создать алгоритм, который будет вычислять relevance
a user
в другой user
на основе определенных бит данных.
К сожалению, мои навыки математики ухудшились после окончания школы почти десять лет назад, и поэтому я очень сильно борюсь с этим. Я нашел алгоритм онлайн, который подталкивает "горячие" сообщения к началу ленты новостей и рисует, что это хорошее место для начала. Это алгоритм/расчет, который я нашел онлайн (в MySQL):
LOG10(ABS(activity) + 1) * SIGN(activity) + (UNIX_TIMESTAMP(created_at) / 300000)
То, что я надеюсь сделать, - это адаптировать приведенную выше концепцию к работе с данными и моделями, которые у меня есть в моем собственном приложении. Рассмотрим этот объект пользователя (обрезанный):
{
"id": 1
"first_name": "Joe",
"last_name": "Bloggs",
"counts": {
"connections": 21,
"mutual_connections": 16
},
"mutual_objects": [
{
"created_at": "2017-03-26 13:30:47"
},
{
"created_at": "2017-03-26 14:25:32"
}
],
"last_seen": "2017-03-26 14:25:32",
}
В алгоритме необходимо учитывать три бита соответствующей информации:
-
mutual_connections
-
mutual_objects
, но принимая во внимание, что старые объекты не должны повышать значимость как более новых объектов, следовательно, поле created_at
.
-
last_seen
Может ли кто-нибудь предложить довольно простой (если это возможно) способ сделать это?
Это была моя идея, но, честно говоря, я понятия не имею, что она делает, поэтому я не могу быть уверен, что это хорошее решение, и я также пропустил last_seen
, поскольку не смог найти способ добавить это:
$mutual_date_sum = 0;
foreach ($user->mutual_objects as $mutual_object) {
$mutual_date_sum =+ strtotime($mutual_object->created_at);
}
$mutual_date_thing = $mutual_date_sum / (300000 * count($user->mutual_objects));
$relevance = log10($user->counts->mutual_connections + 1) + $mutual_date_thing;
Просто, чтобы быть ясным, я не хочу реализовывать какой-то государственный уровень AI, 50 000 строк алгоритма из математического гения. Я просто ищу относительно простое решение, которое сделает трюк на данный момент.
UPDATE
У меня была небольшая игра, и мне удалось построить следующий тест. Похоже, что mutual_objects
очень сильно переносит вес в этом конкретном алгоритме, так как я ожидаю увидеть пользователей 4 и 5 выше списка результатов, учитывая их большое количество mutual_connections
.
Я не знаю, облегчает ли это изменение/играть, но это, наверное, лучшее, что я могу сделать. Пожалуйста, помогите, если у вас есть предложения: -)
$users = [
[
'id' => 1,
'mutual_connections' => 15,
'mutual_objects' => [
[
'created_at' => '2017-03-26 14:25:32'
],
[
'created_at' => '2017-03-26 14:25:32'
],
[
'created_at' => '2017-02-26 14:25:32'
],
[
'created_at' => '2017-03-15 14:25:32'
],
[
'created_at' => '2017-01-26 14:25:32'
],
[
'created_at' => '2017-03-26 14:25:32'
],
[
'created_at' => '2016-03-26 14:25:32'
],
[
'created_at' => '2017-03-26 14:25:32'
]
],
'last_seen' => '2017-03-01 14:25:32'
],
[
'id' => 2,
'mutual_connections' => 2,
'mutual_objects' => [
[
'created_at' => '2016-03-26 14:25:32'
],
[
'created_at' => '2015-03-26 14:25:32'
],
[
'created_at' => '2017-02-26 14:25:32'
],
[
'created_at' => '2017-03-15 14:25:32'
],
[
'created_at' => '2017-01-26 14:25:32'
],
[
'created_at' => '2017-03-26 14:25:32'
],
[
'created_at' => '2016-03-26 14:25:32'
],
[
'created_at' => '2016-03-26 14:25:32'
],
[
'created_at' => '2016-03-26 14:25:32'
],
[
'created_at' => '2017-03-15 14:25:32'
],
[
'created_at' => '2017-02-26 14:25:32'
],
[
'created_at' => '2017-03-15 14:25:32'
],
[
'created_at' => '2017-01-26 14:25:32'
],
[
'created_at' => '2017-03-12 14:25:32'
],
[
'created_at' => '2016-03-13 14:25:32'
],
[
'created_at' => '2017-03-17 14:25:32'
]
],
'last_seen' => '2015-03-25 14:25:32'
],
[
'id' => 3,
'mutual_connections' => 30,
'mutual_objects' => [
[
'created_at' => '2017-02-26 14:25:32'
],
[
'created_at' => '2017-03-26 14:25:32'
]
],
'last_seen' => '2017-03-25 14:25:32'
],
[
'id' => 4,
'mutual_connections' => 107,
'mutual_objects' => [],
'last_seen' => '2017-03-26 14:25:32'
],
[
'id' => 5,
'mutual_connections' => 500,
'mutual_objects' => [],
'last_seen' => '2017-03-26 20:25:32'
],
[
'id' => 6,
'mutual_connections' => 5,
'mutual_objects' => [
[
'created_at' => '2017-03-26 20:55:32'
],
[
'created_at' => '2017-03-25 14:25:32'
]
],
'last_seen' => '2017-03-25 14:25:32'
]
];
$relevance = [];
foreach ($users as $user) {
$mutual_date_sum = 0;
foreach ($user['mutual_objects'] as $bubble) {
$mutual_date_sum =+ strtotime($bubble['created_at']);
}
$mutual_date_thing = empty($mutual_date_sum) ? 1 : $mutual_date_sum / (300000 * count($user['mutual_objects']));
$relevance[] = [
'id' => $user['id'],
'relevance' => log10($user['mutual_connections'] + 1) + $mutual_date_thing
];
}
$relevance = collect($relevance)->sortByDesc('relevance');
print_r($relevance->values()->all());
Это выдает:
Array
(
[0] => Array
(
[id] => 3
[relevance] => 2485.7219150272
)
[1] => Array
(
[id] => 6
[relevance] => 2484.8647045837
)
[2] => Array
(
[id] => 1
[relevance] => 622.26175831599
)
[3] => Array
(
[id] => 2
[relevance] => 310.84394042139
)
[4] => Array
(
[id] => 5
[relevance] => 3.6998377258672
)
[5] => Array
(
[id] => 4
[relevance] => 3.0334237554869
)
)
Ответы
Ответ 1
Эта проблема является кандидатом на машинное обучение. Ищите вводную книгу, потому что я думаю, что она не очень сложна, и вы можете это сделать. Если нет, в зависимости от дохода, который вы делаете на своем веб-сайте, вы можете подумать о найме того, кто сделает это за вас.
Если вы предпочитаете делать это "вручную"; вы создадите свою собственную модель с конкретными весами для разных факторов. Имейте в виду, что наши мозги обманывают нас очень часто, и то, что вы считаете идеальной моделью, может быть далеко не оптимальным.
Я предлагаю вам сразу же начать хранить данные, с которыми пользователи взаимодействуют друг с другом; поэтому вы можете сравнить свои результаты с реальными данными. Кроме того, в будущем у вас будет фундамент для создания надлежащей системы машинного обучения.
Сказав это, вот мое предложение:
В конце концов, вам нужен такой список (с 3 пользователями):
A->B: relevance
----------------
User1->User2: 0.59
User1->User3: 0.17
User2->User1: 0.78
User2->User3: 0.63
User3->User1: 0.76
User3->User2: 0.45
1) Для каждого пользователя
1.1) Вычислить и кешировать возраст каждого пользователя "last_seen", в днях, целое округление (пол).
1.2) Хранить максимум (возраст (last_seen)) - просто назовите его просто макс. Это одно значение, а не одно для каждого пользователя. Но вы можете вычислить его только после того, как вы предварительно вычислили возраст каждого пользователя.
1.3) Для каждого пользователя измените сохраненное возрастное значение с результатом (max-age)/max, чтобы получить значение от 0 до 1.
1.4) Вычислить и кэшировать также каждый объект "created_at", в днях.
2) Для каждого пользователя, сравнивая с каждым другим пользователем
2.1) Что касается взаимных связей, подумайте об этом: если A имеет 100 соединений, 10 из них разделены с B, а C имеет 500 соединений, 10 из которых разделены с D, вы действительно принимаете 10 в качестве значения для вычисления в обоих случаях? Я бы взял процент. Для A- > B это будет 10, а для C- > D - 2. И тогда значение /100 должно иметь значение от 0 до 1.
2.2) Выберите максимальный возраст для взаимных объектов, чтобы быть релевантным. Возьмем 365 дней.
2.3) В пользователе A удалите объекты старше 365 дней. Не удаляйте их, просто отфильтровывайте их для этих вычислений.
2.4) Из остальных объектов вычислите процент взаимных объектов с каждым из других пользователей.
2.5) Для каждого из этих других пользователей вычислите средний возраст общих объектов с предыдущего шага. Возьмите максимальный возраст (365), вычтите вычисленное среднее значение и /365, чтобы иметь значение от 0 до 1.
2.6) Получить возрастное значение другого пользователя.
Итак, для каждой комбинации A- > B у вас есть четыре значения от 0 до 1:
- MC: взаимные соединения A-B
- MO: взаимные объекты A-B
- OA: средний возраст объекта A-B
- BA: возраст B
Теперь вам нужно назначить веса каждому из них, чтобы найти оптимальное решение. Назначьте проценты, которые составляют 100, чтобы облегчить вашу жизнь:
Релевантность = 40 * MC + 30 * MO + 10 * OA + 20 * BA
В этом случае, поскольку OA так связано с MO, вы можете их смешать:
Релевантность = 40 * MC + 20 * MO + 20 * MO * OA + 20 * BA
Я предлагаю запустить эту ночь, каждый день. Существует много способов улучшить и оптимизировать процесс... получайте удовольствие!