2.5 离线增量文章画像计算
学习目标
目标
了解增量更新代码过程
应用
无
2.5.1 离线文章画像更新需求
文章画像,就是给每篇文章定义一些词。
关键词:TEXTRANK + IDF共同的词
主题词:TEXTRANK + ITFDF共同的词
更新文章时间:
1、toutiao 数据库中,news_article_content 与news_article_basic—>更新到article数据库中article_data表,方便操作
第一次:所有更新,后面增量每天的数据更新26日:1:00~2:00,2:00~3:00,左闭右开,一个小时更新一次
2、刚才新更新的文章,通过已有的idf计算出tfidf值以及hive 的textrank_keywords_values
3、更新hive的article_profile
2.5.2 定时更新文章设置
目的:通过Supervisor管理Apscheduler定时运行更新程序
步骤:
1、更新程序代码整理,并测试运行
2、Apscheduler设置定时运行时间,并启动日志添加
3、Supervisor进程管理
2.5.2.1 更新程序代码整理,并测试运行
注意在Pycharm中运行要设置环境:
PYTHONUNBUFFERED=1
JAVA_HOME=/root/bigdata/jdk
SPARK_HOME=/root/bigdata/spark
HADOOP_HOME=/root/bigdata/hadoop
PYSPARK_PYTHON=/root/anaconda3/envs/reco_sys/bin/python
PYSPARK_DRIVER_PYTHON=/root/anaconda3/envs/reco_sys/bin/python
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR))
from offline import SparkSessionBase
from datetime import datetime
from datetime import timedelta
import pyspark.sql.functions as F
import pyspark
import gc
class UpdateArticle(SparkSessionBase):
"""
更新文章画像
"""
SPARK_APP_NAME = "updateArticle"
ENABLE_HIVE_SUPPORT = True
SPARK_EXECUTOR_MEMORY = "7g"
def __init__(self):
self.spark = self._create_spark_session()
self.cv_path = "hdfs://hadoop-master:9000/headlines/models/countVectorizerOfArticleWords.model"
self.idf_path = "hdfs://hadoop-master:9000/headlines/models/IDFOfArticleWords.model"
def get_cv_model(self):
# 词语与词频统计
from pyspark.ml.feature import CountVectorizerModel
cv_model = CountVectorizerModel.load(self.cv_path)
return cv_model
def get_idf_model(self):
from pyspark.ml.feature import IDFModel
idf_model = IDFModel.load(self.idf_path)
return idf_model
@staticmethod
def compute_keywords_tfidf_topk(words_df, cv_model, idf_model):
"""保存tfidf值高的20个关键词
:param spark:
:param words_df:
:return:
"""
cv_result = cv_model.transform(words_df)
tfidf_result = idf_model.transform(cv_result)
# print("transform compelete")
# 取TOP-N的TFIDF值高的结果
def func(partition):
TOPK = 20
for row in partition:
_ = list(zip(row.idfFeatures.indices, row.idfFeatures.values))
_ = sorted(_, key=lambda x: x[1], reverse=True)
result = _[:TOPK]
# words_index = [int(i[0]) for i in result]
# yield row.article_id, row.channel_id, words_index
for word_index, tfidf in result:
yield row.article_id, row.channel_id, int(word_index), round(float(tfidf), 4)
_keywordsByTFIDF = tfidf_result.rdd.mapPartitions(func).toDF(["article_id", "channel_id", "index", "tfidf"])
return _keywordsByTFIDF
d