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

时间:2017-03-26 15:18:27

标签: php mysql algorithm laravel math

我目前正在尝试构建一种算法,根据某些数据位计算relevance 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线算法。我只是在寻找一个相对简单的解决方案,暂时可以解决这个问题。

更新

我玩了一点,并设法建立了以下测试。似乎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 个答案:

答案 0 :(得分:1)

这个问题是机器学习的候选者。寻找一本介绍性的书,因为我觉得它不是很复杂,你可以做到。如果没有,根据您在网站上的收入,您可能会考虑雇用为您做这件事的人。

如果你喜欢这样做"手动&#34 ;;你将建立自己的模型,具有不同因素的特定权重。请注意,我们的大脑经常欺骗我们,你认为完美的模型可能远非最佳。

我建议你立即开始存储每个用户与哪些用户交互的数据;这样您就可以将结果与实际数据进行比较。此外,在未来,您将拥有构建合适的机器学习系统的基础。

话虽如此,这是我的建议:

最后,你需要一个这样的列表(有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)计算并缓存每个用户的年龄,以天为单位,整数向下舍入(下限)。

1.2)存储最大值(年龄(last_seen))-let仅将其称为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:相互联系A-B
  • MO:共同对象A-B
  • OA:avg mutual object age A-B
  • BA:B的年龄

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

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

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

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

我建议每天一夜之间运行。有很多方法可以改进和优化流程......玩得开心!