用户购物性别模型标签(USG)之决策树模型

一、USG模型引入:

首先了解一下,如何通过大数据来确定用户的真实性别,
经常谈论的用户精细化运营,到底是什么?
简单来讲,就是将网站的每个用户标签化,制作一个属于用户自己的网络身份证。然后,运营人员
通过身份证来确定活动的投放人群,圈定人群范围,更为精准的用户培养和管理。
当然,身份证最基本的信息就是姓名,年龄和性别,与现实不同的是,网络上用户填写的资料不一
定完全准确,还需要进行进一步的确认和评估。
确定性别这件事很重要,简单举个栗子,比如店铺想推荐新品的Bra,如果粗糙的
全部投放人群或者投放到不准确性别的人群,那后果可想而知了。

虽然能够通过用户的行为、购买和兴趣数据,了解用户的基本信息,但是仍然不清楚如何建
模?用什么语言建模?
购物性别的区分使用的是机器学习分类算法模型,但是算法也有很多分类,包含逻辑
回归
线性支持向量机朴素贝叶斯模型决策树,又该如何选择呢?
使用大数据 Spark MLlib 机器学习库, JavaScalaPython 三种语言都支持。
其中,决策树的优点较多,主要是其变量处理灵活,不要求相互独立。可处理大维度的数
据,不用预先对模型的特征有所了解。对于表达复杂的非线性模式和特征的相互关系,模型相
对容易理解和解释,所以决定用决策树进行尝试。

核心难点:如何构建树,有三种方式

  • "ID3 算法:信息增益Info_Gain

  • C4.5 算法:信息增量率(比):lnfo Gain Rate

  • CART 算法:Classification And Regression Tree,基尼指数(Gini_Index)

建立在决策树算法之上: 集成融合学习算法 ,效果非常非常好的

  • GBT:梯度提升树算法,构建1棵树,迭代构建的树

  • RF:随机森林,构建N棵树,每个棵树不同,使用所有树预测,综合获取结果

USG:用户购物性别:

1.定义:通过用户购买的产品,确定用户的性别

2.思路:依据商品的名称、商品的颜色和商品的类别等,判断购买者的性别

如何确定USG?

基于用户购买商品确定性别的

用户在购物时,每个商品都有自己的属性,比如名称、颜色、类别等等,往往属于某个性别的用户

a.商品名称

剃须刀 male

口红 female

家用电器 male、female


b.商品颜色                                                                   

衣服红色/亮色衣服 female

格子衫(黑灰色、杂色) male

中性颜色 male、female

c.商品类别

电子数码产品 male

美容保养 female


U_1001 product_01 male

U_1001 product_02 female

U_1001 product_03 male

U_1001 product_4 male

U_1001 product_05 female

U_1001 product_06 male


基于上面用户购买的物品,打上商品购买的性别,进行计算,最终确定用户购物性别

统计购物商品的个数

total =6

统计购物中男性商品个数

maletotal = 4

占比: maleRate = 4 /6 ≈ 0.666666666

统计购物中女性商品个数

femaletotal = 2

占比: femaleRate = 2/ 6 ≈ 0.333333333333

判断男性商品占比和女商品占比 if(maleRate >=0.6)时,USG = male if(femaleRate >=0.6)时,USG = female

else:USG = 末知

=========上述计算出用户购物性别USG,为什么还需要算法构建模型预测呢?=============

依据上述计算数据,构建分类算法模型以后,直接使用算法模型对用户进行预测即可,不需要在按照规则(经验) 进行分类操作。

业务目标: 精准投放,针对已有产品,寻找某性别偏好的精准人群进行广告投放。
技术目标:对用户购物性别识别:男性,女性,中性。
解决思路:选择一种分类算法,建立Spark模型,对模型进行应用。
线上投放:对得到的数据进行小范围内的测试投放,初期不宜过大扩大投放范围。
效果分析:对投放的用户进行数据分析,评估数据的准确性。若不够完美,则需要
重新建模和测试。

二、标签模型开发:

用户购物性别标签模型类: UsgModel ,继承基类 AbstractModel ,实现标签计算方法doTag 。

订单表:

需要将 订单商品表 中订单号 cordersn 关联到 订单表 中订单号 ordersn ,获取到对应的会员ID: memberid

颜色维度表:

商品类别维度表:

读取订单表数据

	val session: SparkSession = businessDF.sparkSessionimport session.implicits._val ordersDF: DataFrame = spark.read.format("hbase").option("zkHosts", "bigdata-cdh01.itcast.cn").option("zkPort", "2181").option("hbaseTable", "tbl_tag_orders").option("family", "detail").option("selectFields", "memberid,ordersn").load()

加载颜色维度数据并与ID进行相应的映射:

	val colorsDF: DataFrame = {spark.read.format("jdbc").option("driver", "com.mysql.jdbc.Driver").option("url","jdbc:mysql://bigdata-cdh01.itcast.cn:3306/?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC").option("dbtable", "profile_tags.tbl_dim_colors").option("user", "root").option("password", "123456").load()}val colorColumn: Column = {// 声明变量var colorCol: Column = nullcolorsDF.as[(Int, String)].rdd.collectAsMap().foreach{case (colorId, colorName) =>if(null == colorCol){colorCol = when($"ogcolor".equalTo(colorName), colorId)}else{colorCol = colorCol.when($"ogcolor".equalTo(colorName), colorId)}}colorCol = colorCol.otherwise(0).as("color")//  返回colorCol}

加载商品维度表数据并将其与对应ID进行映射:

val productsDF: DataFrame = {spark.read.format("jdbc").option("driver", "com.mysql.jdbc.Driver").option("url","jdbc:mysql://bigdata-cdh01.itcast.cn:3306/?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC").option("dbtable", "profile_tags.tbl_dim_products").option("user", "root").option("password", "123456").load()}var productColumn: Column = {// 声明变量var productCol: Column = nullproductsDF.as[(Int, String)].rdd.collectAsMap().foreach{case (productId, productName) =>if(null == productCol){productCol = when($"producttype".equalTo(productName), productId)}else{productCol = productCol.when($"producttype".equalTo(productName), productId)}}productCol = productCol.otherwise(0).as("product")// 返回productCol}

根据运营规则标注的部分数据并关联订单数据,颜色维度和商品类别维度数据: 

		val labelColumn: Column = {when($"ogcolor".equalTo("樱花粉").or($"ogcolor".equalTo("白色")).or($"ogcolor".equalTo("香槟色")).or($"ogcolor".equalTo("香槟金")).or($"productType".equalTo("料理机")).or($"productType".equalTo("挂烫机")).or($"productType".equalTo("吸尘器/除螨仪")), 1) //女.otherwise(0)//男.alias("label")//决策树预测label}val goodsDF: DataFrame = businessDF// 关联订单数据:.join(ordersDF, businessDF("cordersn") === ordersDF("ordersn"))// 选择所需字段,使用when判断函数.select($"memberid".as("userId"), //colorColumn, // 颜色ColorColumnproductColumn, // 产品类别ProductColumn// 依据规则标注商品性别labelColumn)

打标签,统计每个用户男女性商品个数占比:

	// TODO: 直接使用标注数据,给用户打标签val predictionDF: DataFrame = goodsDF.select($"userId", $"label".as("prediction"))// 4. 按照用户ID分组,统计每个用户购物男性或女性商品个数及占比val genderDF: DataFrame = predictionDF.groupBy($"userId").agg(count($"userId").as("total"), // 某个用户购物商品总数// 判断label为0时,表示为男性商品,设置为1,使用sum函数累加sum(when($"prediction".equalTo(0), 1).otherwise(0)).as("maleTotal"),// 判断label为1时,表示为女性商品,设置为1,使用sum函数累加sum(when($"prediction".equalTo(1), 1).otherwise(0)).as("femaleTotal"))

计算标签、计算占比、获取画像标签数据:

		// 5.1 获取属性标签:tagRule和tagNameval rulesMap: Map[String, String] = TagTools.convertMap(tagDF)val rulesMapBroadcast: Broadcast[Map[String, String]] = session.sparkContext.broadcast(rulesMap)// 对每个用户,分别计算男性商品和女性商品占比,当占比大于等于0.6时,确定购物性别val gender_tag_udf: UserDefinedFunction = udf((total: Long, maleTotal: Long, femaleTotal: Long) => {// 计算占比val maleRate: Double = maleTotal / total.toDoubleval femaleRate: Double = femaleTotal / total.toDoubleif(maleRate >= 0.6){ // usg = 男性rulesMapBroadcast.value("0")}else if(femaleRate >= 0.6){ // usg =女性rulesMapBroadcast.value("1")}else{ // usg = 中性rulesMapBroadcast.value("-1")}})//  获取画像标签数据val modelDF: DataFrame = genderDF.select($"userId", //gender_tag_udf($"total", $"maleTotal", $"femaleTotal").as("usg"))

三、ML Pipeline

在机器学习中,特别是在使用Apache Spark MLlib或Spark ML(Spark的机器学习库)时,ML Pipeline(机器学习流水线)是一个非常重要的概念。ML Pipeline提供了一种将多个机器学习步骤(如特征提取、转换、选择、模型训练和评估等)组合在一起的方式,使得数据处理和模型训练过程更加清晰、模块化和可重用。

DataFrame:数据框,一种数据结构,来源于SparkSQL中,DataFrame=Dataset[Row],存储要训练的和测试的数据集;

Transformer:转换器,一种算法Algorithm,必须实现transform方法。比如:模型 Model就是一个转换器,将输入的数据集DataFrame,转换为预测结果的数据集 DataFrame;

Estimator :估计器或者模型学习器,将数据集DataFrame转换为一个Transformer, 实现 fit() 方法,输入一个 DataFrame并产生一个 Model,即一个Transformer(转换 器);

Pipeline :管道,管道由一系列阶段组成,每个阶段都是 估计器或转换器;

Parameter :参数,无论是转换器Transformer还是模型学习器Estimator都是一个 算法,使用算法的时候必然有参数。

将USG中 构建决策树算法模型 代码修改为 训练Pipeline模型 ,整个管道Pipeline流程示意图如下: 

完整代码封装函数 trainPipelineModel如下:

	def trainPipelineModel(dataframe: DataFrame): PipelineModel = {// 数据划分为训练数据集和测试数据集val Array(trainingDF, testingDF) = dataframe.randomSplit(Array(0.8, 0.2), seed = 123)// a. 特征向量化val assembler: VectorAssembler = new VectorAssembler().setInputCols(Array("color", "product")).setOutputCol("raw_features")// b. 类别特征进行索引val vectorIndexer: VectorIndexer = new VectorIndexer().setInputCol("raw_features").setOutputCol("features").setMaxCategories(30)// c. 构建决策树分类器val dtc: DecisionTreeClassifier = new DecisionTreeClassifier().setFeaturesCol("features").setLabelCol("label").setPredictionCol("prediction").setImpurity("gini") // 基尼系数.setMaxDepth(5) // 树的深度.setMaxBins(32) // 树的叶子数目// TODO: 构建Pipeline管道对象,组合模型学习器(算法)和转换器(模型)val pipeline: Pipeline = new Pipeline().setStages(Array(assembler, vectorIndexer, dtc))// 训练模型,使用训练数据集val pipelineModel: PipelineModel = pipeline.fit(trainingDF)// f. 模型评估val predictionDF: DataFrame = pipelineModel.transform(testingDF)predictionDF.show(100, truncate = false)println(s"accuracy = ${modelEvaluate(predictionDF, "accuracy")}")// 返回模型pipelineModel}

ML Pipeline优缺点分析:

优点:

降低耦合度:将不同的处理逻辑封装成独立的阶段,每个阶段只关注自己的输入和输出,不需要知道其他阶段的细节。这使得添加、删除或修改阶段变得更加容易,且不影响整个流程的运行。
增加灵活性:通过配置化可以实现不同的业务走不同的流程,而不需要修改代码。这能够根据需求变化快速调整流程,提高开发效率和可维护性。
提高性能:可以利用多线程或异步机制来并行执行不同的阶段,从而提高整个流程的吞吐量和响应时间。
提高可读性:通过将复杂的机器学习模型分解为多个阶段,每个阶段负责特定的任务,使得整个模型的结构更加清晰,易于理解和维护。
可测试性强:由于不同的步骤之间相对独立,耦合较低,可以更方便地对每个步骤编写单元测试,从而提高代码质量。

缺点:

调试困难:当流水线中的某个阶段出现问题时,可能需要逐个检查每个阶段以确定问题的根源,这可能会增加调试的复杂性和时间成本。
资源消耗:并行执行多个阶段可能会消耗更多的计算资源,包括CPU、内存和存储空间等。
配置和部署:配置和部署一个复杂的ML Pipeline可能需要一定的技术知识和经验,以确保所有组件能够正确协同工作。

注意
对管道调用 fit 方法的效果跟依次对每个评估器调用 fit 方法一样, 都是transform 输入并传递给下个步骤。 管道中最后一个评估器的所有方法,管道都有。例如,如果最后的评估器是一个分类器, Pipeline 可以当做分类器来用。如果最后一个评估器是转换器,管道也一样可以。 

四、模型调优 

交叉验证(Cross-Validation):

交叉验证(Cross-Validation) 是一种评估机器学习模型性能的方法,特别是当可用的训练数据较少时。这种方法通过重复使用数据来模拟训练集和测试集,从而得到模型性能的一个更可靠估计。以下是交叉验证的基本概念和一些常见的交叉验证策略:

K折交叉验证(K-Fold Cross-Validation)

  • 将数据集分为K个大小相等的子集(或尽可能相等)。
  • 对于每个子集,都将其视为测试集,而其余K-1个子集则作为训练集。
  • 重复此过程K次,每次都使用不同的子集作为测试集。
  • 最终,计算K次评估的平均值作为模型性能的估计。

 

五、总结: 

在USG模型中,ML Pipeline(机器学习流水线)为使用决策树算法构建和评估模型提供了一个系统化的流程,确保了整个模型开发过程的一致性和可重复性。交叉验证通过将数据集划分为不同的子集,并轮流使用这些子集进行训练和测试,为模型提供了更为准确和可靠的性能评估。这有助于我们发现并避免过拟合,调整模型参数以达到最佳性能,以及在不同算法和特征集合中选择最佳模型。

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

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

相关文章

D3D 顶点格式学习

之前D3D画三角形的代码中有这一句, device.VertexFormat CustomVertex.TransformedColored.Format; 这是设置顶点格式; 画出的三角形如下, 顶点格式是描述一个三维模型的顶点信息的格式;可以包含以下内容, 位置…

Xcode设置cocoapods库的最低兼容版本

目录 前言 1.使用cocoapods遇到的问题 2.解决办法 1.用法解释 1. config.build_settings: 2.IPHONEOS_DEPLOYMENT_TARGET 2.使用实例 3.注意事项 1.一致性 2.pod版本 前言 这篇文章主要是介绍如何设置cocoapods三方库如何设置最低兼容的版本。 1.使用cocoapods遇到的…

qt学习笔记

qt的对象树 在 Qt中创建对象的时候会提供一个 Parent 对象指针,Q0bject是以对象树的形式组织起来的。 当你创建一个 Q0biect 对象时,会看到 Q0biect 的构造函数接收一个Q0b.ject指针作为参数,这个参数就是 parent,也就是父对象指…

三次样条插值的实现(Matlab)

一、问题描述 三次样条插值的实现。 二、实验目的 掌握三次样条插值方法的原理,能够编写代码获得自然、抛物线端点以及非纽结三次样条。 三、实验内容及要求 找出并画出三次样条S,满足S(0) 1, S(1) 3, S(2) 3, S(3) 4, S(4) 2,其中…

Spring Boot 开发 -- 过滤器与拦截器详解

引言 在Web开发中,经常需要对请求进行预处理或在响应后进行后处理,Spring Boot提供了过滤器和拦截器两种机制来实现这一需求。虽然它们都可以用来处理HTTP请求和响应,但在使用场景、执行顺序和配置方式上存在明显的差异。本文将详细讲解Spri…

LeetCode 2928.给小朋友们分糖果 I:Java提交的运行时间超过了61%的用户

【LetMeFly】2928.给小朋友们分糖果 I:Java提交的运行时间超过了61%的用户 力扣题目链接:https://leetcode.cn/problems/distribute-candies-among-children-i/ 给你两个正整数 n 和 limit 。 请你将 n 颗糖果分给 3 位小朋友,确保没有任何…

易语言贪吃蛇游戏(附带源码)

易语言贪吃蛇游戏 效果图源码说明源码领取下期更新预报 效果图 源码说明 本源码用易语言来编写,供大家研究,保留版权,谢谢! 源码领取 易语言贪吃蛇游戏源码领取地址:https://www.123pan.com/s/ji8kjv-TKPU3.html提取…

Oracle中rman的增量备份使用分享

继上次使用RMAN的全量备份和异机还原以后,开始研究一下增量备份和还原的方法。相比于全量RMAN的备份还原,增量的备份还原就相对简单。本实践教程直接上操作,还是回归到一个问题,就是关于两个数据库创建时候,必须保持or…

泄漏libc基地址

拿libc基地址 方法一:格式化字符串 格式化字符串,首先确定输入的 AAAA 在栈上的位置(x)。使用 elf.got[fun] 获得got地址。利用格式化字符串,构造payload泄漏got地址处的值,recv接受到的字符串中&#xf…

linux部署运维1——centos7.9离线安装部署web或java项目所需的依赖环境,包括mysql8.0,nginx1.20,redis5.0等工具

在实际项目部署运维过程中,如果是云服务器,基本安装项目所需的依赖环境都是通过yum联网拉取网络资源实现自动化安装的;但是对于一些特殊场合,在没有外部网络的情况下,就无法使用yum命令联网操作,只能通过编…

网络报文协议头学习

vxlan:就是通过Vxlan_header头在原始报文前面套了一层UDPIP(4/6)Eth_hdr 需求背景:VXLAN:简述VXLAN的概念,网络模型及报文格式_vxlan报文格式-CSDN博客 如果服务器作为VTEP,那从服务器发送到接…

jmeter之MD5加密请求秒杀接口教程

前言: 有时候在项目中,需要使用MD5加密的方法才可以登录,或者在某一个接口中遇到 登录获取token后才可以进行关联,下面介绍下遇到的常见使用 一、第一种方法:使用jmeter自带的函数助手digest 选择工具,选…

并查集拓展(扩展域并查集)

事实证明,扩展域并查集应该在带权并查集前面讲的,因为比较好理解,而且回过头看带权并查集可能也会更轻松一些。 https://www.luogu.com.cn/problem/P1892https://www.luogu.com.cn/problem/P1892 题目描述 现在有 𝑛 个人&…

算法解析——单身狗问题

欢迎来到博主的专栏:算法解析 博主ID代码小豪 文章目录 什么是单身狗问题leetcode_136——只出现一次的数字I使用位运算解决单身狗问题。 leetcode_137——只出现一次的数字II统计二进制数解决单身狗问题leetcode_260 只出现一次数字III分区域按位异或解决问题。 总…

C语言:如何写文档注释、内嵌注释、行块注释?

技术答疑流程 扫描二维码,添加个人微信;支付一半费用,获取答案;如果满意,则支付另一半费用; 知识点费用:10元 项目费用:如果有项目任务外包需求,可以微信私聊

【scikit-learn009】异常检测系列:单类支持向量机(OC-SVM)实战总结(看这篇就够了,已更新)

1.一直以来想写下机器学习训练AI算法的系列文章,作为较火的机器学习框架,也是日常项目开发中常用的一款工具,最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下scikit-learn框架OCSVM模型相关知识体系。 3.欢迎批评指正,欢迎互三,跪谢一键三连! 4.欢迎…

Vue3实战笔记(57)—一键换肤:在Vuetify中打造个性化主题切换体验

文章目录 前言一键换肤总结 前言 在当今追求极致用户体验的时代,为应用程序提供个性化的主题切换功能已经成为提升用户满意度和留存率的关键因素之一。Vuetify,作为基于Vue.js的流行前端框架,以其丰富的组件库和高度可定制性,为开…

day05-多任务-正则-装饰器

一、多任务 1-进程和线程 进程是操作系统分配资源的最小单元 线程执行程序的的最小单元 线程依赖进程,可以获取进程的资源 一个程序执行 先要创建进程分配资源,然后使用线程执行任务 默认情况下一个进程中有一个线程 2-多任务介绍 运行多个进程或线程执…

民国漫画杂志《时代漫画》第38期.PDF

时代漫画38.PDF: https://url03.ctfile.com/f/1779803-1248636380-dd7daa?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了,截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

CATIA进阶操作——创成式曲面设计入门(1)线架设计,三维点、直线、平面、曲线

目录 引出三维空间点生成三维直线三维平面三维曲线总结异形弹簧新建几何体草图编辑,画一条样条线进行扫掠,圆心和半径画出曲面上的螺旋线再次选择扫掠,圆心和半径 其他自定义信号和槽1.自定义信号2.自定义槽3.建立连接4.进行触发 自定义信号重…