Рубрики
Uncategorized

Реализация простой рекомендации по контенту на основе тегов

Автор оригинала: David Wong.

Первоначально для простоты и удобства на страницах статей на их небольших веб-сайтах рекомендуется использовать связанный контент для заполнения списка случайными данными, извлеченными из базы данных, поэтому корреляции вообще нет, и нет способа направить пользователей на посещение рекомендуемого контента.

Как рекомендовать аналогичный контент? Поскольку небольшие веб-сайты все еще работают на виртуальных хостах (правильно, у них даже нет собственного полностью управляемого сервера), существует не так много способов подумать об этом. Условие состоит в том, что можно использовать только PHP + MySQL. Поэтому я придумал, как сопоставлять похожие статьи с тегами для рекомендаций. Если ТЕГИ двух статей похожи

Например, ТЕГИ статьи A: [A, B, C, D, E] ТЕГИ статьи B: [A, D, E, F, G] ТЕГИ статьи C: [C, H, I, J, K]

Глазами мы можем легко обнаружить, что статья B и статья A более похожи, потому что у них одни и те же три ключевых слова: [A, D, E]. Как использовать компьютеры, чтобы судить об их сходстве? Здесь мы используем Сходство Джаккарда Самое простое приложение для расчета их сходства

Сходство Джаккарда

Учитывая два набора A, B, коэффициенты Жаккарда определяются как отношение размера пересечения A и B к размеру объединения A и B следующим образом:

Пересечение статьи A и статьи B равно [A, D, E], размер равен 3, а объединение равно [A, B, C, D, E, F, G], размер равен 7, 4285. Пересечение статьи A и статьи C равно [C], размер равен 1, а объединение равно [A, B, C, D, E, H, I, J, K], размер равен 9,.11111.

Таким образом, можно сделать вывод , что статьи A и B более похожи, чем статьи A и C. С помощью этого алгоритма компьютер может судить о сходстве двух статей.

Для данной статьи получите ТЕГИ ключевых слов статьи, а затем сравните сходство всех статей в базе данных с помощью приведенного выше алгоритма, чтобы получить наиболее похожие N статей для рекомендации.

Приобретение первых МЕТОК

ТЕГИ-это алгоритм TF-IDF для извлечения высокочастотных слов из статей. В качестве ТЕГОВ выбирается N слов. Для китайских статей это также связано с проблемой сегментации китайских слов, потому что это отношения между виртуальными хостами. На этом шаге я написал локальную программу с использованием Python (почему Python, сегментация слов Jieba, Чжэньсян). Я выполнил сегментацию слов, статистику частоты слов всех статей и сгенерировал ТЕГ. S, и запишите обратно в базу данных сервера. Поскольку эта статья представляет собой рекомендательный алгоритм, часть сегментации слов и создания ТЕГОВ специально не расширена, и в разных системах существуют разные способы создания ТЕГОВ.

Хранение вторых ТЕГОВ

Создайте две таблицы для хранения ТЕГОВ тегов, для хранения имен всех тегов

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

Tag_map устанавливает взаимосвязь сопоставления между тегом и статьей.

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

Данные, хранящиеся в tag_map, похожи на следующие:

+----+-----------+-------+
| 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 |
+----+-----------+-------+

На самом деле, делая подобную рекомендацию, вам нужно использовать только таблицу tag_map, потому что TagID и имя тега соответствуют один к одному.

1. Получите идентификатор ТЕГА, соответствующий всем статьям

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 |
+-----------+--------------------------+

С помощью приведенного выше SQL вы можете запросить все статьи и теги за один раз. В PHP мы можем превращать теги в массивы.

public function getAllGroupByArticleId(){
        // Cache query data, because this is full table data, and does not update the article will not change, that is, every recommendation to get data from the database once, will certainly have an impact on performance, so make a cache.
        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){
            // With articleid as key, the value is all tagID arrays under that ID.
            $result[$value['articleid']] = explode(",",$value['tags']);
        }

        CacheHelper::setCache($result, 86400);

        return $result;

    }

С таким обратным результатом это будет сделать проще. Следующая работа заключается в применении алгоритма подобия Jaccard, в зависимости от кода.

/**
     * [Return similar article recommendations based on specified articles]
     *@ Article ID specified by param $articleid
     *@ Number of recommended items to be returned by param $top
     *@ Return Array Recommendation Item Array
     */
function getArticleRecommend($articleid, $top = 5){
        if($cache = CacheHelper::getCache()){
            return $cache;
        }
        try{
            $articleid = intval($articleid);
            $m = new TagMapModel();
            $all_tags = $m - > getAllGroupByArticleId (); // Call the above function to return tags for all articles
            $finded = $all_tags [$articleid]; // Because it contains all the articles above, it must contain the current article.

            Unset ($all_tags [$articleid]); /// Delete the current article from the array, otherwise you and yourself will surely be the most similar.

            $jaccard_arr= []; // for storage similarity
            foreach ($all_tags as $key => $value) {
                $intersect = array_intersect ($finded, $value); // Compute intersection
                $union = array_unique (array_merge ($finded, $value);//Computational union set

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

            Arsort ($jaccard_arr); /// sorted by similarity, with the most similar row at the front

            $jaccard_keys = array_keys ($jaccard_arr); // Since the key of the array is the article id, you can just take the key out here.
            Array_splice ($jaccard_keys, $top); // Get the first N recommendations

            // Here we have got the ID of the most similar N articles. The next work is to query the relevant information from the database through these IDs.
    
            $articleModels = new \Api\Model\ArticleModel();
            $recommendArticles = $articleModels->getRecommendByTag($jaccard_keys);
            CacheHelper:: setCache ($recommend Articles, 604800); // Cache 7 days
            return $recommendArticles;
        } catch (\Exception $e) {
            Throw new Exception ("Get Recommendation Articles Error");
        }
    }

Хотя и простой, несколько фрагментов кода, но эффект все еще возможен, рекомендуемые статьи имеют определенную степень сходства, безусловно, могут улучшить пользовательский интерфейс, примеры вы можете увидеть https://www.wx2share.com/Arti…