离线用户召回定时更新系列二

news2024/11/28 7:44:24

3.6.3 特征处理原则

  • 离散数据
    • one-hot编码
  • 连续数据
    • 归一化
  • 图片/文本
    • 文章标签/关键词提取
    • embedding

 

 

3.6.4 优化训练方式

  • 使用Batch SGD优化
    • 加入正则化防止过拟合

3.6.5 spark LR 进行预估

  • 目的:通过LR模型进行CTR预估
  • 步骤:
    • 1、需要通过spark读取HIVE外部表,需要新的sparksession配置
      • 增加HBASE配置
    • 2、读取用户点击行为表,与用户画像和文章画像,构造训练样本
    • 3、LR模型进行训练
    • 4、LR模型预测、结果评估

创建环境

import os
import sys
# 如果当前代码文件运行测试需要加入修改路径,避免出现后导包问题
BASE_DIR = os.path.dirname(os.path.dirname(os.getcwd()))
sys.path.insert(0, os.path.join(BASE_DIR))

PYSPARK_PYTHON = "/miniconda2/envs/reco_sys/bin/python"
# 当存在多个版本时,不指定很可能会导致出错
os.environ["PYSPARK_PYTHON"] = PYSPARK_PYTHON
os.environ["PYSPARK_DRIVER_PYTHON"] = PYSPARK_PYTHON

from pyspark.ml.feature import OneHotEncoder
from pyspark.ml.feature import StringIndexer
from pyspark.ml import Pipeline
from pyspark.sql.types import *
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.classification import LogisticRegressionModel
from offline import SparkSessionBase

class CtrLogisticRegression(SparkSessionBase):

    SPARK_APP_NAME = "ctrLogisticRegression"
    ENABLE_HIVE_SUPPORT = True

    def __init__(self):

        self.spark = self._create_spark_hbase()

ctr = CtrLogisticRegression()
  • 1、这里注意的是_create_spark_hbase,我们后面需要通过spark读取HIVE外部表,需要新的配置
    def _create_spark_hbase(self):

        conf = SparkConf()  # 创建spark config对象
        config = (
            ("spark.app.name", self.SPARK_APP_NAME),  # 设置启动的spark的app名称,没有提供,将随机产生一个名称
            ("spark.executor.memory", self.SPARK_EXECUTOR_MEMORY),  # 设置该app启动时占用的内存用量,默认2g
            ("spark.master", self.SPARK_URL),  # spark master的地址
            ("spark.executor.cores", self.SPARK_EXECUTOR_CORES),  # 设置spark executor使用的CPU核心数,默认是1核心
            ("spark.executor.instances", self.SPARK_EXECUTOR_INSTANCES),
            ("hbase.zookeeper.quorum", "192.168.19.137"),
            ("hbase.zookeeper.property.clientPort", "22181")
        )

        conf.setAll(config)

        # 利用config对象,创建spark session
        if self.ENABLE_HIVE_SUPPORT:
            return SparkSession.builder.config(conf=conf).enableHiveSupport().getOrCreate()
        else:
            return SparkSession.builder.config(conf=conf).getOrCreate()
  • 2、读取用户点击行为表,与用户画像和文章画像,构造训练样本
    • 目标值:clicked
    • 特征值:
      • 用户画像关键词权重:权重值排序TOPK,这里取10个
      • 文章频道号:channel_id, ID类型通常要做one_hot编码,变成25维度(25个频道)
        • 这里由于我们的历史点击日志测试时候是只有18号频道,所以不进行转换
      • 文章向量:articlevector
      • 总共:10 + 1+ 100 = 110

 

进行行为日志数据读取

ctr.spark.sql("use profile")
# +-------------------+----------+----------+-------+
# |            user_id|article_id|channel_id|clicked|
# +-------------------+----------+----------+-------+
# |1105045287866466304|     14225|         0|  false|
user_article_basic = ctr.spark.sql("select * from user_article_basic").select(
    ['user_id', 'article_id', 'channel_id', 'clicked'])

用户画像读取处理与日志数据合并

user_profile_hbase = ctr.spark.sql(
    "select user_id, information.birthday, information.gender, article_partial, env from user_profile_hbase")
user_profile_hbase = user_profile_hbase.drop('env')

# +--------------------+--------+------+--------------------+
# |             user_id|birthday|gender|     article_partial|
# +--------------------+--------+------+--------------------+
# |              user:1|     0.0|  null|Map(18:Animal -> ...|

_schema = StructType([
    StructField("user_id", LongType()),
    StructField("birthday", DoubleType()),
    StructField("gender", BooleanType()),
    StructField("weights", MapType(StringType(), DoubleType()))
])

def get_user_id(row):
    return int(row.user_id.split(":")[1]), row.birthday, row.gender, row.article_partial

读取用户画像HIVE的外部表,构造样本

user_profile_hbase_temp = user_profile_hbase.rdd.map(get_user_id)
user_profile_hbase_schema = ctr.spark.createDataFrame(user_profile_hbase_temp, schema=_schema)

train = user_article_basic.join(user_profile_hbase_schema, on=['user_id'], how='left').drop('channel_id')

文章频道与向量读取合并,删除无用的特征

  • 由于黑马用户信息中,大多数没有相关特征,直接删除
# +-------------------+----------+-------+--------+------+--------------------+
# |            user_id|article_id|clicked|birthday|gender|             weights|
# +-------------------+----------+-------+--------+------+--------------------+
# |1106473203766657024|     13778|  false|     0.0|  null|Map(18:text -> 0....|
ctr.spark.sql("use article")
article_vector = ctr.spark.sql("select * from article_vector")
train = train.join(article_vector, on=['article_id'], how='left').drop('birthday').drop('gender')

# +-------------------+-------------------+-------+--------------------+----------+--------------------+
# |         article_id|            user_id|clicked|             weights|channel_id|       articlevector|
# +-------------------+-------------------+-------+--------------------+----------+--------------------+
# |              13401|                 10|  false|Map(18:tp2 -> 0.2...|        18|[0.06157120217893...|

 

 

合并文章画像的权重特征

ctr.spark.sql("use article")
article_profile = ctr.spark.sql("select * from article_profile")

def article_profile_to_feature(row):

    try:
        weights = sorted(row.keywords.values())[:10]
    except Exception as e:
        weights = [0.0] * 10
    return row.article_id, weights
article_profile = article_profile.rdd.map(article_profile_to_feature).toDF(['article_id', 'article_weights'])

article_profile.show()

train = train.join(article_profile, on=['article_id'], how='left')

 

 

进行用户的权重特征筛选处理,类型处理

  • 用户权重排序筛选,缺失值
    • 获取用户对应文章频道号的关键词权重
    • 若无:生成默认值
train = train.dropna()

columns = ['article_id', 'user_id', 'channel_id', 'articlevector', 'weights', 'clicked']

def feature_preprocess(row):

    from pyspark.ml.linalg import Vectors
    try:
        weights = sorted([row.weights[key] for key in row.weights.keys() if key[:2] == str(row.channel_id)])[
                  :10]
    except Exception:
        weights = [0.0] * 10

    return row.article_id, row.user_id, row.channel_id, Vectors.dense(row.articlevector), Vectors.dense(
        weights), int(row.clicked)

train = train.rdd.map(feature_preprocess).toDF(columns)

结果:

 

 

输入模型的特征格式指定,通过VectorAssembler()收集

cols = ['article_id', 'user_id', 'channel_id', 'articlevector', 'weights', 'article_weights', 'clicked']

train_version_two = VectorAssembler().setInputCols(cols[2:6]).setOutputCol("features").transform(train)

合并特征向量(channel_id1个+用户特征权重10个+文章向量100个+文章关键词权重) = 121个特征

 

 

lr = LogisticRegression()
model = lr.setLabelCol("clicked").setFeaturesCol("features").fit(train_version_two)
model.save("hdfs://hadoop-master:9000/headlines/models/lr.obj")

3.6.5 点击率预测结果

使用model模型加载预估

online_model = LogisticRegressionModel.load("hdfs://hadoop-master:9000/headlines/models/CtrLogistic.obj")

res_transfrom = online_model.transform(train_version_two)

res_transfrom.select(["clicked", "probability", "prediction"]).show()

probability结果中有对某个文章点击(1为目标)的概率,和不点击(0为目标)的概率

def vector_to_double(row):
    return float(row.clicked), float(row.probability[1]) 

score_label = res_transfrom.select(["clicked", "probability"]).rdd.map(vector_to_double)

3.6.6 模型评估-Accuracy与AUC

画出ROC图,使用训练的时候的模型model中会有

import matplotlib.pyplot as plt
plt.figure(figsize=(5,5))
plt.plot([0, 1], [0, 1], 'r--')
plt.plot(model.summary.roc.select('FPR').collect(),
         model.summary.roc.select('TPR').collect())
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()

结果

 

 

  • from pyspark.mllib.evaluation import BinaryClassificationMetrics
from pyspark.mllib.evaluation import BinaryClassificationMetrics
metrics = BinaryClassificationMetrics(score_label)
metrics.areaUnderROC
0.7364334522585716

其它方法

from sklearn.metrics import roc_auc_score, accuracy_score
import numpy as np

arr = np.array(score_label.collect())

评估AUC与准确率

accuracy_score(arr[:, 0], arr[:, 1].round())
0.9051438053097345


roc_auc_score(arr[:, 0], arr[:, 1])
0.719274521004087

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/180299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos学习笔记【part1】安装与注册服务

一、概述与安装 Nacos 是是一个构建云原生应用的动态服务发现、配置管理和服务管理平台,用于发现、配置和管理微服务,提供了一组简单易用的特性集,快速实现动态服务发现、服务配置、服务元数据及流量管理。 Nacos 更敏捷和容易地构建…

分享136个ASP源码,总有一款适合您

ASP源码 分享136个ASP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 136个ASP源码下载链接:https://pan.baidu.com/s/11db_K2QXns5pm8vMZBVPSw?pwds0lb 提取码&#x…

js 文字转语音 api SpeechSynthesisUtterance

SpeechSynthesisUtterance基本介绍 SpeechSynthesisUtterance是HTML5中新增的API,用于将指定文字合成为对应的语音.也包含一些配置项,指定如何去阅读(语言,音量,音调)等 官方文档地址(https://developer.mozilla.org/zh-CN/docs/Web/API/SpeechSynthesisUtterance…

【JavaEE初阶】第七节.多线程(基础篇)单例模式(案例一)

欢迎大家跟我一起来学习有关多线程的有关内容!!!!!!!!!! 文章目录 前言 一、单例模式的概念 二、单例模式的简单实 2.1 饿汉模式 2.2 懒汉模式 总结 前言…

搭建Linux环境

学习Linux之前,我们首先需要在电脑上搭建Linux操作系统环境。 就好比说你买了一台电脑,需要使用Windows10操作系统,那么首先应该安装Windows操作系统(刚买的电脑会引导你一步一步的安装)。 一、Linux环境搭建的三种方式…

数据结构 第三章 栈和队列(队列)

感谢:点击收听 1 基本知识点 1、允许删除的一端称为队头(front) 2、允许插入的一端称为队尾(rear) 3、当队列中没有元素时称为空队列 4、顺序队列: 1 使用顺序表来实现队列 2 两个指针分别指向队列的前端和尾端 **3 如果队列的大小为MaxSize个,那么元…

什么是倒排表(倒排索引)

这种搜索引擎的实现常常用的就是倒排的技术 文档(Document):一般搜索引擎的处理对象是互联网网页,而文档这个概念要更宽泛些,代表以文本形式存在的存储对象,相比网页来说,涵盖更多种形式,比如Word&#xff…

在Mac下如何创建文件

相比于windows中创建Mac是比较复杂的 第一步:打开启动台,依次打开「启动台-其他-自动操作」,可以按住「 Command 空格」直接搜索「自动操作」程序。 第二步:打开之后在「选取文稿类型」选项时,选择「快速操作」&#…

工地车辆未冲洗识别抓拍系统 yolov5网络

工地车辆未冲洗识别抓拍系统通过yolov5网络深度算法学习模型,自动对画面中每辆进出车辆的清洗实现自动识别判定。如果识别到车辆冲洗不合格,就会自动进行抓拍并将违规车辆信息回传。目标检测架构分为两种,一种是two-stage,一种是o…

「兔了个兔」看我如何抓取兔兔图片到本地(附源码)

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…

如何在IDEA中使用Maven构建Java项目?Maven的使用详细解读

文章目录1. 前言2. IDEA 中配置 Maven 环境3. Maven 的坐标问题4. IDEA 中创建 Maven 项目5. IDEA 中导入 Maven 项目6. 安装插件7. 依赖管理8. 依赖范围6. 总结Java编程基础教程系列1. 前言 前面在如何使用 Maven 构建 Java 项目一文中,我们一直在命令行中执行构建…

LabVIEW什么是实时操作系统(RTOS)

LabVIEW什么是实时操作系统(RTOS)一般而言,操作系统的任务是管理计算机的硬件资源和应用程序。实时操作系统会执行这些任务,但是运行时间精度和可靠度都极高。在实际应用中,有的系统失常代价高昂,甚至会引起安全事故。这时&#x…

成为提示专家,AI艺术杂志:AI Unleashed 第一期

shadow最近发现了一期AI艺术的杂志。名称叫 AI Unleashed,是一本深入探索 AI 和想象力的杂志。每期杂志都将填满精彩的 AI 艺术,激发你的好奇心, 让你更加了解最新的 AI 技术,以及它如何改变现有工作流和我们对艺术和技术的看法。…

LVS+keepalived(双主)+Nginx实现高可用负载均衡

#为什么采用双主架构: 单主架构只有一个keepalived对外提供服务,该主机长期处于繁忙状态,而另一台主机却很空闲,利用率低下 #双主架构的优点: 即将两个或以上VIP分别运行在不同的keepalived服务器,以实现…

C++11使用线程类thread的方法

C11 之前,C 语言没有对并发编程提供语言级别的支持。如果需要使用线程,windows系统需要使用CreateThread函数创建线程,而linux需要使用pthread库使用线程。C11 中增加了线程以及线程相关的类,很方便地支持了并发编程。由于可以跨平…

活动星投票十大商业品牌网络评选微信的投票方式线上免费投票

“十大商业品牌”网络评选投票_线上系统免费投票_功能齐全的视频投票_在线投票免费小程序用户在使用微信投票的时候,需要功能齐全,又快捷方便的投票小程序。而“活动星投票”这款软件使用非常的方便,用户可以随时使用手机微信小程序获得线上投…

CV学习笔记-VGG

VGG 1. 常见的卷积神经网络 VGG属于一种经典的卷积神经网络结构,其出现在AlexNet之后,由于AlexNet的突破证实了卷积神经网络的可行性,VGG的思路主要是将网络层数加深,从某种意义上说,网络层数的加深可以粗略地认为考虑…

编译原理学习笔记14——属性文法与语法制导翻译1

编译原理学习笔记14——属性文法与语法制导翻译114.1 属性文法14.2 属性计算14.1 属性文法 属性文法 综合属性 自下而上传递信息语法规则:根据右 部候选式中的符号 的属性计算左部被 定义符号的综合属性语法树:根据子结 点的属性和父结点 自身的属性…

【日常系列】LeetCode《30·动态规划总结》

动态规划总结 线性动态规划问题总结 打家劫舍总结 最大子数组和总结 dp[i] 依赖于前面一个或者两个状态 dp[i] 依赖于前面多个状态 注意:子序列可以不连续 dp[i] 带有一个或者多个维度 输入为两个数组或者两个字符串 lc 10【剑指 19】【top100】:正…

【LeetCode每日一题:2309. 兼具大小写的最好英文字母~~~模拟+Hash表+贪心】

题目描述 给你一个由英文字母组成的字符串 s ,请你找出并返回 s 中的 最好 英文字母。返回的字母必须为大写形式。如果不存在满足条件的字母,则返回一个空字符串。 最好 英文字母的大写和小写形式必须 都 在 s 中出现。 英文字母 b 比另一个英文字母 …