用户购物性别模型标签(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.sparkSession
		import 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 = null
			colorsDF
				.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 = null
			productsDF
				.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, // 颜色ColorColumn
				    productColumn, // 产品类别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和tagName
		val 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.toDouble
				val femaleRate: Double = femaleTotal / total.toDouble
				if(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(机器学习流水线)为使用决策树算法构建和评估模型提供了一个系统化的流程,确保了整个模型开发过程的一致性和可重复性。交叉验证通过将数据集划分为不同的子集,并轮流使用这些子集进行训练和测试,为模型提供了更为准确和可靠的性能评估。这有助于我们发现并避免过拟合,调整模型参数以达到最佳性能,以及在不同算法和特征集合中选择最佳模型。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【算法】贪心算法简介

贪心算法概述 目录 1.贪心算法概念2.贪心算法特点3.贪心算法学习 1.贪心算法概念 贪心算法是一种 “思想” ,即解决问题时从 “局部最优” 从而达到 “全局最优” 的效果。 ①把解决问题的过程分为若干步②解决每一步时候,都选择当前最优解(不关注全局…

基于SSM前后端分离版本的论坛系统-自动化测试

目录 前言 一、测试环境 二、环境部署 三、测试用例 四、执行测试 4.1、公共类设计 创建浏览器驱动对象 测试套件 释放驱动类 4.2、功能测试 注册页面 登录页面 版块 帖子 用户个人中心页 站内信 4.3、界面测试 注册页面 登录页面 版块 帖子 用户个人中心页…

数据整理操作及众所周知【数据分析】

各位大佬好 ,这里是阿川的博客,祝您变得更强 个人主页:在线OJ的阿川 大佬的支持和鼓励,将是我成长路上最大的动力 阿川水平有限,如有错误,欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

进程与线程(二)

进程与线程(二) exec函数族守护进程守护进程的概念Linux守护进程的编写步骤创建子进程,父进程退出在子进程中创建新会话改变当前目录为根目录重设文件权限掩码关闭文件描述符守护进程案例编写 线程线程的概念Linux下进程和线程的区别 Linux下…

C++基础编程100题-002 OpenJudge-1.1-04 输出保留3位小数的浮点数

更多资源请关注纽扣编程微信公众号 002 OpenJudge-1.1-04 输出保留3位小数的浮点数 http://noi.openjudge.cn/ch0101/04/ 描述 读入一个单精度浮点数,保留3位小数输出这个浮点数。 输入 只有一行,一个单精度浮点数。 输出 也只有一行,…

java —— 集合

一、集合的概念 集合可以看做是一个存储对象的容器,与数组不同的是集合可以存储不同类型的对象,但开发中一般不这样做。集合不能存储基本类型的对象,如果存储则需要将其转化为对应的包装类。 二、集合的分类 集合分为 Collection 和 Map 两…

2024抖音流量认知课:掌握流量底层逻辑,明白应该选择什么赛道 (43节课)

课程下载:https://download.csdn.net/download/m0_66047725/89360865 更多资源下载:关注我。 课程目录 01序言:拍前请看.mp4 02抖音建模逻辑1.mp4 03抖音标签逻辑2.mp4 04抖音推流逻辑3.mp4 05抖音起号逻辑4.mp4 06养号的意义.mp4 0…

算法解析——单身狗问题

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

iperf3带宽压测工具使用

iperf3带宽压测工具使用 安装下载地址:[下载入口](https://iperf.fr/iperf-download.php)测试结果:时长测试(压测使用):并行测试反向测试UDP 带宽测试 iPerf3 是用于主动测试 IP 网络上最大可用带宽的工具 安装 下载地址&#x…

SAP 生产订单批量报工(代码分享)

最近公司一直在对成本这块的业务进行梳理,影响比较大的就是生产这块的报工,经常会要求要批量的冲销报工,然后在继续报工,来调整生产订单的实际工时,前面的博客中已经给大家分享了批量冲销生产订单的代码, 下面给大家分享一下生产订单批量报工的代码 首先流程制造和离散制…

如何解决研发数据传输层面安全可控、可追溯的共性需求?

研发数据在企业内部跨网文件交换,是相对较为普遍而频繁的文件流转需求,基于国家法律法规要求及自身安全管理需要,许多企业进行内部网络隔离。不同企业隔离方案各不相同,比如银行内部将网络隔离为生产网、办公网、DMZ区&#xff0c…

如何用ChatGPT上热门:完整使用教程与写作技巧

1. ChatGPT概述修订 ChatGPT是一款基于深度神经网络的语言生成技术,能够协助用户创造出各类高品质的文字材料,适宜广泛的应用场景,如编撰文章、文学创作及社交媒体内容生成。 2. 利用ChatGPT生成热门内容的基本步骤 为了有效利用ChatGPT创作…

代码随想录算法训练营第三十五 | ● 860.柠檬水找零 ● 406.根据身高重建队列 ● 452. 用最少数量的箭引爆气球

860.柠檬水找零 讲解链接:https://programmercarl.com/0860.%E6%9F%A0%E6%AA%AC%E6%B0%B4%E6%89%BE%E9%9B%B6.html 本题只有5元10元20元,只需要考虑收到5、10、20这三种情况; 收到5元,五块的个数; 收到10,找…

Appium安装及配置(Windows环境)

在做app相关自动化测试,需要使用appium来做中转操作,下面来介绍一下appium的环境安装配置 appium官方文档:欢迎 - Appium Documentation 一、下载appium 下载地址:https://github.com/appium/appium-desktop/releases?page3 通…

Java多线程--volatile关键字

并发编程的三大特性 可见性有序性原子性 可见性 为什么会有可见性问题? 多核CPU 为了提升CPU效率,设计了L1,L2,L3三级缓存,如图。 如果俩个核几乎同时操作同一块内存,cpu1修改完,当下是对c…

TDR原理的介绍

目录 简介 简单定义 TDR测试原理 简介 时域和频域就像孪生兄弟一样,经常在测试测量领域同时出现,可谓是工程师们分析问题和解决问题的两大法宝。所以,在某些测试场景中,如果有时域信息的护法,咱们就能从时频域两个维…

嵌入式Linux shell编程实例

1. 输入两个数,实现两个数的相加 (1)具体实现代码如下 1 #!/bin/bash2 read a3 read b4 sum$(($a$b))5 echo "$sum"(2)编辑完内容后按Esc键再输入:wq保存,回车退出,执行结果如下图&a…

uniapp创建支付密码实现(初始密码,第二次密码)

示例: 插件地址:自定义数字/身份证/密码输入框,键盘密码框可分离使 - DCloud 插件市场 1.下载插件并导入HBuilderX,找到文件夹,copy number-keyboard.vue一份为number-keyboard2.vue(number-keyboard.vue是…

[数据集][目标检测]脑溢血检测数据集VOC+YOLO格式767张2类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):767 标注数量(xml文件个数):767 标注数量(txt文件个数):767 标注类别…

java 远程调试

1.远程启动时 jdk1.8-32\jre\bin\java.exe -Dfile.encodingUTF-8 -Djava.library.pathlib -agentlib:jdwptransportdt_socket,servery,suspendn,address5005 -jar local-com.yuetai.service-0.0.1-SNAPSHOT.jar --spring.config.locationapplication.yml 2.本地调试项目连接远…