如何实现推荐系统?

8 投票
3 回答
24385 浏览
提问于 2025-04-16 19:18

我有一本《集体智慧》的书,但我不太确定它怎么能在实际中应用。

假设我有一个用PHP做的网站,里面有一个mySQL数据库。用户可以在数据库中插入带有标题和内容的文章。为了简单起见,我们只比较标题。

  • 如何制作咖啡
  • 关于咖啡的15件事。
  • 大问题。
  • 如何削铅笔?
  • 一个人被打到蛋蛋了

我们打开“如何制作咖啡?”这篇文章,因为它的标题和第二个和第四个标题有相似的词,所以它们会在相关文章的部分显示出来。

我该如何用PHP和mySQL来实现这个功能?如果需要用Python也可以。提前谢谢你。

3 个回答

0

这可以通过在SQL查询中使用通配符来简单实现。如果你有较长的文本,而通配符似乎无法捕捉到文本中间的部分,那么可以检查一下一个子字符串是否和另一个匹配。希望这对你有帮助。顺便提一下,你的问题标题是关于实现推荐系统的,而问题描述只是询问如何在数据库记录中匹配一个字段。推荐系统是一个很广泛的话题,涉及很多有趣的算法(比如协同过滤、基于内容的方法、矩阵分解、神经网络等等)。如果你的项目规模足够大,欢迎你去探索这些高级主题。

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.
12

给每个产品存储一组关键词,这些关键词基本上就是标题中的所有内容,除了那些被称为停用词的词。展示标题时,你需要找出其他产品中与之共享的关键词(如果有一个或多个关键词相同的产品,优先显示这些)。

你还可以进一步改进这个方法,通过给每个关键词分配一个分数,分数的高低取决于这个词的稀缺性(稀缺的词分数更高,比如说,匹配到“PHP”的相关性会比“编程”更高),或者通过记录用户在一组产品之间手动浏览的次数。

不管怎样,最好是先从简单的开始,然后随着时间的推移再逐步改进。根据你的数据库大小,使用更高级的技术可能效果并不明显。

撰写回答