根据特定数据计算用户的相关性

Ben*_*rey 11 php mysql algorithm math laravel

我目前正在尝试形成一种算法,该算法将根据某些数据位计算relevancea user到另一个算法user.

不幸的是,自从大约十年前离开学校以来,我的数学技能已经恶化,因此,我非常挣扎于此.我发现了一种在线算法,可以将"热门"帖子推到新闻源的顶部,并认为这是一个很好的起点.这是我在网上找到的算法/计算(在MySQL中):

LOG10(ABS(activity) + 1) * SIGN(activity) + (UNIX_TIMESTAMP(created_at) / 300000)
Run Code Online (Sandbox Code Playgroud)

我希望做的是调整上述概念来处理我自己的应用程序中的数据和模型.考虑这个用户对象(修剪):

{
    "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",
}
Run Code Online (Sandbox Code Playgroud)

上面有三位相关信息需要在算法中考虑:

  • 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;
Run Code Online (Sandbox Code Playgroud)

为了清楚起见,我不打算从数学天才中实施某种政府层面的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());
Run Code Online (Sandbox Code Playgroud)

打印出:

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
        )

)
Run Code Online (Sandbox Code Playgroud)

jot*_*nas 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
Run Code Online (Sandbox Code Playgroud)

1) 对于每个用户

1.1) 计算并缓存每个用户“last_seen”的年龄,以天为单位,整数向下舍入(下限)。

1.2) 存储 max(age(last_seen)) -我们称之为 max-。这是一个值,而不是每个用户一个值。但只有在之前计算出每个用户的年龄后才能计算它

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:相互连接AB
  • MO:共同对象AB
  • OA:平均共同对象年龄AB
  • BA:B的年龄

现在你必须为每一个分配权重才能找到最佳解决方案。指定总和为 100 的百分比,让您的生活更轻松:

相关性 = 40 * MC + 30 * MO + 10 * OA + 20 * BA

在这种情况下,由于 OA 与 MO 非常相关,因此您可以将它们混合使用:

相关性 = 40 * MC + 20 * MO + 20 * MO * OA + 20 * BA

我建议每天晚上运行这个。有很多方法可以改进和优化流程......玩得开心!