Maison  >  Article  >  base de données  >  Méthode pour implémenter la recommandation de contenu basée sur des balises (code)

Méthode pour implémenter la recommandation de contenu basée sur des balises (code)

不言
不言original
2018-09-14 14:11:422416parcourir

Ce que cet article vous apporte concerne la méthode (code) de mise en œuvre de la recommandation de contenu basée sur les balises. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Il s'avère que par souci de simplicité et de commodité, les recommandations de contenu pertinentes pour les pages d'articles de mon petit site Web consistent à extraire aléatoirement des données de la base de données pour remplir une liste, il n'y a donc aucune corrélation. , et il n'existe aucun moyen de guider les utilisateurs pour accéder au contenu des recommandations.

Sélection d'algorithmes

Comment pouvons-nous recommander un contenu similaire ? Puisque le petit site Web fonctionne toujours sur un hôte virtuel (oui, il n'a même pas de serveur entièrement contrôlable), il y a donc il n'y a pas beaucoup de façons d'y penser, et les conditions sont limitées à l'utilisation de PHP+MySql. J'ai donc pensé à utiliser des balises pour faire correspondre des articles similaires à des fins de recommandation. Si les TAGS de deux articles sont similaires

Par exemple : le TAGS de l'article A est : [A,B,C,D,E]
Le TAGS de l'article B est : [A,D,E,F ,G]
Les TAGS de l'article C sont : [C,H,I,J,K]

A travers nos yeux nous pouvons facilement constater que l'article B et l'article A sont plus similaires car ils ont trois mêmes mots-clés : : [A, D, E], comment utiliser un ordinateur pour déterminer leur similarité ? Ici nous utilisons l'application la plus basique de similitude Jaccard pour calculer leur similarité

similitude Jaccard

Étant donné deux ensembles A et B, le coefficient de Jaccard est défini comme le rapport de la taille de l'intersection de A et B à la taille de l'union de A et B, défini comme suit :

Méthode pour implémenter la recommandation de contenu basée sur des balises (code)

L'intersection de l'article A et de l'article B est [A,D,E], la taille est 3 et l'union est [A,B ,C,D, E, F, G], la taille est 7, 3/7=0,4285...
L'intersection de l'article A et de l'article C est [C], la taille est 1 et l'union est [A, B, C, D, E, H, I, J, K], la taille est 9, 1/9=0,11111...

De cette façon, on peut conclure que les articles A et B sont plus similaires que les articles A et C. Grâce à ces algorithmes, les ordinateurs peuvent déterminer la similitude de deux articles.

Idées de recommandations spécifiques

Étant donné un article, obtenez le mot-clé TAGS de l'article, puis utilisez l'algorithme ci-dessus pour comparer la similarité de tous les articles de la base de données afin d'obtenir les N articles les plus similaires Les articles sont recommandés.

Processus de mise en œuvre

Obtention des premiers TAGS

Les TAGS de l'article consistent à extraire les mots à haute fréquence dans l'article via l'algorithme TF-IDF, et à sélectionner N comme TAGS. Les articles chinois impliquent également un problème de segmentation des mots chinois. Parce qu'il s'agit d'un hôte virtuel, j'ai utilisé Python (pourquoi utiliser Python, la segmentation des mots jieba, si délicieuse) pour écrire un programme localement pour compléter la segmentation des mots de tous les articles. statistiques de fréquence des mots, générer des TAGS et réécrire dans la base de données du serveur. Étant donné que cet article concerne l'écriture d'algorithmes recommandés, les parties de la segmentation des mots et de l'établissement des TAGS ne seront pas abordées en détail, et différents systèmes ont différentes méthodes pour établir les TAGS.

Stockage des deuxièmes TAGS

Créer deux tables pour stocker les TAGS
tags, utilisées pour stocker les noms de toutes les balises

+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| tag   | text       | YES  |     | NULL    |       |
| count | bigint(20) | YES  |     | NULL    |       |
| tagid | int(11)    | NO   | PRI | 0       |       |
+-------+------------+------+-----+---------+-------+

tag_map pour créer une relation de balises avec l'article.

+-----------+------------+------+-----+---------+-------+
| Field     | Type       | Null | Key | Default | Extra |
+-----------+------------+------+-----+---------+-------+
| id        | bigint(20) | NO   | PRI | 0       |       |
| articleid | bigint(20) | YES  |     | NULL    |       |
| tagid     | int(11)    | YES  |     | NULL    |       |
+-----------+------------+------+-----+---------+-------+

Les données stockées dans tag_map sont similaires aux suivantes :

+----+-----------+-------+
| id | articleid | tagid |
+----+-----------+-------+
|  1 |       776 |   589 |
|  2 |       776 |   471 |
|  3 |       776 |  1455 |
|  4 |       776 |  1287 |
|  5 |       776 |    52 |
|  6 |       777 |  1386 |
|  7 |       777 |   588 |
|  8 |       777 |   109 |
|  9 |       777 |   603 |
| 10 |       777 |  1299 |
+----+-----------+-------+

En fait, lorsque vous faites des recommandations similaires, il vous suffit d'utiliser la table tag_map, car tagid et tag les noms correspondent un par un.

Codage spécifique

1. Obtenez le TAGID correspondant à tous les articles

mysql> select articleid, GROUP_CONCAT(tagid) as tags from tag_map GROUP BY articleid;
+-----------+--------------------------+
| articleid | tags                     |
+-----------+--------------------------+
|        12 | 1178,1067,49,693,1227    |
|        13 | 196,2004,2071,927,131    |
|        14 | 1945,713,1711,2024,49    |
|        15 | 35,119,9,1,1180          |
|        16 | 1182,1924,2200,181,1938  |
|        17 | 46,492,414,424,620       |
|        18 | 415,499,153,567,674      |
|        19 | 1602,805,691,1613,194    |
|        20 | 2070,1994,886,575,1149   |
|        21 | 1953,1961,1534,2038,1393 |
+-----------+--------------------------+

Grâce au SQL ci-dessus, vous pouvez interroger tous les articles à la fois et toutes les balises correspondantes
En PHP, on peut transformer les balises en tableaux.

public function getAllGroupByArticleId(){
        //缓存查询数据,因为这个是全表数据,而且不更新文章不会变化,便是每次推荐都要从数据库里获取一次数据,对性能肯定会有影响,所以做个缓存。
        if($cache = CacheHelper::getCache()){
            return $cache;
        }
        $query_result = $this->query('select articleid, GROUP_CONCAT(tagid) as tags from tag_map GROUP BY articleid');

        $result = [];
        foreach($query_result as $key => $value){
            //用articleid 做key ,值是该id下的所有tagID数组。
            $result[$value['articleid']] = explode(",",$value['tags']);
        }

        CacheHelper::setCache($result, 86400);

        return $result;

    }

Avec ce résultat de retour, c'est plus facile à gérer. L'étape suivante consiste à appliquer l'algorithme de similarité Jaccard. Regardons le code pour plus de détails.

/**
     * [更据指定文章返回相似的文章推荐]
     * @param  $articleid 指定的文章ID
     * @param  $top       要返回的推荐条数
     * @return Array      推荐条目数组
     */
function getArticleRecommend($articleid, $top = 5){
        if($cache = CacheHelper::getCache()){
            return $cache;
        }
        try{
            $articleid = intval($articleid);
            $m = new TagMapModel();
            $all_tags = $m->getAllGroupByArticleId();//调用上面的函数返回所有文章的tags
            $finded = $all_tags[$articleid];//因为上面是包含所有文章了,所以肯定包含了当前文章。

            unset($all_tags[$articleid]);//把当前文章从数组中删除,不然自己和自己肯定是相似度最高了。

            $jaccard_arr = []; //用于存相似度
            foreach ($all_tags as $key => $value) {
                $intersect =array_intersect($finded, $value); //计算交集
                $union = array_unique(array_merge($finded, $value)); //计算并集

                $jaccard_arr[$key] = (float)(count($intersect) / count($union));
            }

            arsort($jaccard_arr); //按相似度排序,最相似的排最前面

            $jaccard_keys = array_keys($jaccard_arr);//由于数组的key就是文章id,所以这里把key取出来就可以了
            array_splice($jaccard_keys, $top);//获取前N条推荐

            //到这里我们就已经得到了,最相似N篇文章的ID了,接下去的工作就是通过这几个ID,从数据库里把相关信息,查询出来就可以了
    
            $articleModels = new \Api\Model\ArticleModel();
            $recommendArticles = $articleModels->getRecommendByTag($jaccard_keys);
            CacheHelper::setCache($recommendArticles, 604800); //缓存7天
            return $recommendArticles;
        } catch (\Exception $e) {
            throw new \Exception("获取推荐文章错误");
        }
    }

Recommandations associées :

Comment implémenter simplement la fonction "Recommandation d'articles associés" en PHP

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn