Word2Vec计算相似文章

第一步:得到用户帖子的点击日志。

from pyspark.sql.types import BooleanType,LongType
from scipy.stats import norm, t
from pyspark.sql import SparkSession, DataFrame, functions as F
from pyspark.sql.functions import udf,lit
from dateutil.parser import parse
import string
from pyspark.sql.types import IntegerType, ArrayType
import pandas as pd
import pymysql
import jieba
import re
from pyspark.sql.functions import udf
from pyspark.sql.types import ArrayType, StringType
from pyspark.sql.functions import col,udf, json_tuple, lit
from datetime import datetime
from pyspark.ml.feature import Word2Vec, Word2VecModel


dp='2020-05-07'
start_date='2020-04-20'
end_date='2020-04-20'
#1.读取最近3天用户点击日志,有条件的用户可以天级别日志+当天实时日志,效果更佳。
log_sql = """select uid, post_id, log_time, dp from %s where dp >= '%s' and dp <= '%s'""" % ('dm.post_click_daily', start_date, end_date)
df = spark.sql(log_sql)
log = df.select('uid', 'post_id', 'log_time')

得到点击日志:

第二步【选做】:按照uid、post_id去重。

log = log.groupBy('uid', 'post_id').agg(F.first('log_time').alias('log_time'))

即某个用户最近三天可能点击了某个帖子 三次。只需要随机取一次即可。

第三步:得到每个用户的点击序列。

 
# 组成post_id,date_time两列。然后按照第二列排序,把第一列存到list中,得到用户按时间排序的点击序列。
def sort2seq(arr):
    """将用户浏览的post_id按照浏览时间升序排序
    :param arr: {list}
    :return: {list} list of target_ids
    """
    # 按照浏览时间排序
    sorted_arr = sorted(arr, key=lambda x: x[1])
    return [row[0] for row in arr]
#注册UDF
sort2seq = F.udf(sort2seq, returnType=ArrayType(StringType()))

post_struct = F.struct('post_id', 'log_time')
user_seq = log.groupBy('uid') \
    .agg(F.collect_list(post_struct).alias('seq')) \
    .select('uid', sort2seq('seq').alias('post_ids'))

得到用户的点击序列:

第四步【选做】:过滤点击序列太长、太短的用户。

#选取 浏览过10~600个帖子的用户
size_limit = (10, 600)
training = user_seq.filter(F.size('post_ids').between(*size_limit))

第五步:用户点击序列训练Word2Vec

#把用户的帖子点击序列当成 文章。训练得到每个帖子的vec。
word2vec = Word2Vec(vectorSize=40, minCount=5, maxIter=5, numPartitions=40,
                    # window_size设置一个超大的数,这样就会把用户浏览过的所有物品都组合一遍
                    windowSize=50, inputCol='post_ids', outputCol="user_vec",maxSentenceLength=200)
model = word2vec.fit(training)    
#  DataFrame[word: string, c: vector]
target_df = model.getVectors().select(
    # 这里注意,把target_id转为bigint
    F.col('word').cast(LongType()).alias('post_id'),
    F.col('vector').alias('target_vec'),
)

target_df:每一个帖子都有了一个40维(vectorSize)的向量来表示。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章