如何实现一个推荐系统?

8
我有一本《集体智慧》的书,但我不确定如何将其应用于实践中。
假设我有一个PHP网站和一个mySQL数据库。用户可以在数据库中插入带有标题和内容的文章。为了简单起见,我们只比较标题。
  • 如何制作咖啡
  • 关于咖啡的15件事。
  • 重要问题。
  • 如何削铅笔?
  • 男人被击中要害部位。
我们打开“如何制作咖啡?”的文章,因为第二个和第四个标题中的单词相似,所以它们将显示在相关文章部分中。
我该如何使用PHP和mySQL实现这一点?如果必须使用Python也可以。谢谢。
3个回答

12

存储每个产品的关键词集合,这些关键词基本上是标题中除了一组停用词之外的所有内容。当显示一个标题时,您可以找到任何其他共享相同关键词的产品(具有一个或多个相同的产品具有优先权)。

您可以通过为每个关键词分配基于它的稀缺程度的分数来进一步增强此功能(更稀缺的单词会被赋予较高的分数,例如与“programming”匹配相比,“PHP”的匹配将更相关),或跟踪用户在一组产品之间手动导航的次数。

无论如何,最好从简单的开始,然后随着进展逐步改进。根据您的数据库大小,更高级的技术可能并不那么有成效。


我理解的是,每次用户插入一篇文章(可能有数千个单词),程序需要将所有单词分离并存储在一个表中(忽略停用词),然后将关键字与内容ID附加到每个单词上。同时,程序将从其他文章中查找相似的单词(这些文章可能再次包含许多单词),并找出哪篇文章具有更多相似的关键字,然后将相关文章存储在一个表中。我认为这可能会很耗费资源,或者我的想法不正确? - Azam
1
它不需要很“沉重”。最简单的方法是创建一张多对多的表格,有两个列——文章ID和关键词。用户选择具有A、B和C关键词的文章#1。你可以像这样简单地进行计数:SELECT articleID, COUNT(keyword) FROM keyword WHERE keyword IN (A, B, C) GROUP BY articleID ORDER BY COUNT(keyword) DESC——显然,这非常简单,只是给出了与最多关键字匹配的文章,而不考虑每个关键字的值,正如Justin Simon所说的那样。但这将是一个开始,而且很容易启动和运行。并且,通过良好的索引,速度也非常快! - Drew

5

最好使用一组标签,这些标签在插入标题时会被解析并存储在数据库中,然后根据这些标签进行查询。

如果必须解析标题,则基本上要执行LIKE查询:

SELECT * FROM ENTRIES WHERE TITLE LIKE '%<keyword>%';

更详细的答案如下:

// You need some test to see if the word is valid. 
// "is" should not be considered a valid match.
// This is a simple one based on length, a 
// "blacklist" would be better, but that's up to you.
function isValidEntry( $word )
{
    return strlen( $word ) >= 4;
}

//to hold all relevant search strings:
$terms = array();
$postTitleWords = explode( ' ' , strtolower( 'How to Make Coffee' ) );

for( $postTitleWords as $index => $word )
{
    if( isValidEntry( $word ) ) $terms[] = $word;
    else
    {
        $bef = @$postTitleWords[ $index - 1 ];
        if( $bef && !isValidEntry( $bef ) ) $terms[] = "$bef $word";
        $aft = @$postTitleWords[ $index + 1 ];
        if( $aft && !isValidEntry( $aft ) ) $terms[] = "$word $aft";
    }
}
$terms = array_unique( $terms );
if( !count( $terms ) ) 
{
    //This is a completely unique title!
}
$search = 'SELECT * FROM ENTRIES WHERE lower( TITLE ) LIKE \'%' . implode( '%\' OR lower( TITLE ) LIKE \'%' $terms ) . '\'%';
// either pump that through your mysql_search or PDO.

感谢您详细的回答。我将把这个答案作为参考。 - Azam

0

可以通过在SQL查询中使用通配符来简单实现。如果您有更大的文本,并且通配符似乎无法捕获文本的中间部分,则检查一个子字符串是否与另一个匹配。希望这可以帮助到您。 顺便说一下,您的问题标题询问如何实现推荐系统,而问题描述只是询问如何在数据库记录中匹配字段。推荐系统是一个广泛的主题,并且带有许多有趣的算法(例如,协同过滤,基于内容的方法,矩阵分解,神经网络等)。如果您的项目达到了那个规模,请随意探索这些高级主题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接