前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大数据挖掘算法——时间衰变算法

大数据挖掘算法——时间衰变算法

作者头像
博文视点Broadview
发布2020-06-11 16:12:17
1K0
发布2020-06-11 16:12:17
举报
文章被收录于专栏:博文视点Broadview

小编说:时间衰变算法在很多行业都会被应用,就像电商行业,在给用户推荐商品时,会分析用户对于平台商品的兴趣偏好度,同时这个兴趣偏好度也会随着时间的流逝而发生变化。 本文选自《轻松学大数据挖掘:算法、场景与数据产品》

  • 1 何为时间衰变

大家或许都听过一个故事——“遗忘曲线”。

遗忘曲线是由德国心理学家艾宾浩斯(Hermann Ebbinghaus )研究发现的,其描述了人类大脑对新事物遗忘的规律,人们可以从遗忘曲线中掌握遗忘规律并加以利用,从而提升自我记忆的能力。

人的记忆衰变过程,如图1所示。

图1 人的记忆衰变过程(来自百度百科)

这条曲线告诉人们在学习中的遗忘是有规律的,遗忘的进程很快,并且先快后慢。在分析用户对电商平台琳琅满目的商品的兴趣偏好的变化时,也可以借鉴遗忘曲线。

  • 2 如何理解兴趣和偏好

对于兴趣和偏好这两个概念,从不同的角度分析会有不同的定义,这里从时间的角度分析。

兴趣:对事物喜好或关切的情绪,它是参与实践的基础,可以看作是一个短期行为。随着时间的推移,这种喜好也随之变化。

偏好:具有浓厚的积极情绪,伴随着成长过程中的主观倾向,可以看作是一个长期行为,它是基本稳定的。

对于电商平台来说,通过营销活动达到的目的是关心用户的“短期兴趣”。看看用户短期内会更倾向于购买哪些宝贝,从而更好地去做精准营销,如短信、站内广告等。

  • 3 时间衰变算法的抽象

最简单的场景,如果用户在半年前购买过某件商品,但从此以后没有再次对其产生过任何行为(浏览、收藏、加入购物车和购买),那么用户对于该商品的兴趣衰变曲线如图2所示。

图2 单次行为的衰变曲线

重复行为是指用户在半年内针对同一商品多次浏览、收藏、购买该商品。

令t1、t2、t3表示3次相邻重复行为的时刻,用户兴趣度的衰变曲线如图3所示。

图3 用户兴趣度的衰变曲线

  • 4 采用Spark实现模型

在分析用户的商品推荐时,我们会选择动手实践其中的熵权重算法和时间衰变算法,最终结合业务的实际场景重新组合一个综合模型。

1.数据源的获取

这里会考虑从HBase中读取数据源,具体数据特征会涉及用户ID、商品类目、宝贝、行为类型、次数和操作时间。Apache HBase经过长达8年的发展,在2017年1月中旬又发布了新版本(Hbase 1.3.0),多个方面的性能也得到了提升。

为了能够成功调用HBase的API,我们优先在Maven工程的pom.xml中添加如下代码。

代码语言:javascript
复制
<dependency>        
   <groupId>org.apache.hbase</groupId>        
   <artifactId>hbase-client</artifactId>        
   <version>1.2.4</version></dependency>

注:这里使用的是Hbase 1.2.4版本,可以在中央仓库mvnrepository中搜索hbase-client来进行选择。

接下来给出一个连接HBase的测试版本,检测是否能够成功获取HBase中的表数据,代码如下。

代码语言:javascript
复制
/**
 * 扫描rowkey返回行数
 *
 * @param prefixRowKey rowkey前缀
 * @return 行数
 */
def getRowPrefixNum(table: Table,prefixRowKey: String): Option[Int] = {
  var num = 1
  try {
      val scan: Scan = new Scan()
      scan.setStartRow(Bytes.toBytes(prefixRowKey))
      scan.setStopRow(Bytes.toBytes(prefixRowKey + "|"))
      val resultScanner: ResultScanner = table.getScanner(scan)
      val it = resultScanner.iterator()
       while (it.hasNext) {
        it.next()
        num += 1
      }
 resultScanner.close()
 table.close()
 Some(num)
 } catch {
       case e: Exception => logger.error("统计行数出错,{}",e.getMessage)
      table.close()
      Some(1)
  }
}

main运行的代码模块,可以检测数据获取流程是否正常,代码如下。

代码语言:javascript
复制
def main(args: Array[String]): Unit = {
      val conf = HBaseConfiguration.create()
       conf.set(HConstants.ZOOKEEPER_CLIENT_PORT, "端口号")
       conf.set(HConstants.ZOOKEEPER_QUORUM, "data1,data2,data3")
      val connection= ConnectionFactory.createConnection(conf)
      val table=connection.getTable(TableName.valueOf("t_user"))
      val s=getRowPrefixNum(table,"rowkey")
      println(s.getOrElse("0"))
}

最后补充整个工程相关的依赖包,代码如下。

代码语言:javascript
复制
import org.slf4j.{Logger, LoggerFactory}
import org.apache.hadoop.hbase.{HBaseConfiguration, HConstants, TableName}
import org.apache.hadoop.hbase.client._
import org.apache.hadoop.hbase.util.Bytes

2.用户行为权重的调整

这里的数据输入来源于从HBase获取到的用户数据。优先选择用户行为的数据计算出5种行为(浏览、点击、收藏、加入购物车和购买)的权重值。

(1)确定算法过程中的统计指标,代码如下。

代码语言:javascript
复制
val standDatas = rdd.map(_.split(SEPARATOR0)).map(record =>
 {
   var str = ""
   for(i <- 1 until record.length) {
    //其中round为方法调用,保留4位有效数字
     val standValue = round((record(i).toDouble+1)/
      (indexMap.get(i).get._1+indexMap.get(i).get._2),4)
      str = str.concat((standValue*math.log(standValue)).toString). concat(SEPARATOR0)
    }
     str.trim()
 }
).map(record =>
     {
      val arraySet = ArrayBuffer[Double]()
       for(i <- 0 until record.length) {
          arraySet+=record(i).toDouble
      }
      arraySet
      }
)

其中涉及的统计指标都会在后期的计算中用到,需要缓存在RDD中。

(2)确定指标的熵值,代码如下。

代码语言:javascript
复制
val resultSet = ArrayBuffer[Double]()
for(i <- 1 to featureNum) {
    val sumAndCount = standDatas.map(_.apply(i-1)).stats()
   val value=div(sumAndCount.sum,-math.log(sumAndCount.count),4)
   resultSet += value
}

这步主要是计算每个特征向量的熵值大小,也是为计算最后的权重大小做准备的。

(3)确定特征向量的权重值,代码如下。

代码语言:javascript
复制
//确定每个特征向量的权重值
val weightSet = ArrayBuffer[Double]()
for(i <- 0 until featureNum){
    weightSet+=div(resultSet.apply(i),resultSet.sum,4)
}
weightSet.toArray

最终将计算出的用户行为权重单独保存在缓存Cache中,为了后期做兴趣衰变分析计算时可以再使用。

3.用户兴趣衰变的量化

结合上述的Hbase数据源和行为权重值,计算每个用户的兴趣衰变值,主要有以下两个步骤。

(1)计算用户兴趣衰变值,代码如下。

代码语言:javascript
复制
/*
* @describe: 对兴趣衰变的计算
* @param: behav为行为集,factor为衰变因子,weightSet为权重集
*/
 def decayAlgorithm(behav:String,factor:Double,weightSet:Map [String,Double]):Double={
   val behavSet = behav.split("_")
   val behavCategory = behavSet.apply(0)
   val behavDiff = behavSet.apply(1).toDouble
   val behavNum = behavSet.apply(2).toDouble   val interestValue = math.exp(-factor * behavDiff)*behavNum
   behavCategory match {
      case "browse" => weightSet.get("browse").get*interestValue
      case "click" => weightSet.get("click").get*interestValue
      case "collect" => weightSet.get("collect").get*interestValue
      case "addCar" => weightSet.get("addCar").get*interestValue
      case "buy" => weightSet.get("buy").get*interestValue
   }
 }

在RDD中调用上述函数进行处理,计算用户兴趣随着时间的衰变。

(2)采用Sigmoid进行归一化处理,代码如下。

代码语言:javascript
复制
/*
* @describe: 对兴趣衰变进行归一化处理
* @param: decayValue为衰变的兴趣度,factorsigmoid为归一化参数
*/
 def decayRate(decayValue:Double,factorsigmoid:Double):Double = {
   round(1.0/(1+math.exp(3.0-factorsigmoid*decayValue)),4)
 }

上述是对用户最终的兴趣值进行归一化的过程,得到用户对宝贝列表的兴趣排名,从而进行有针对性的推荐。和大家以往熟知的协同过滤推荐有所差异,基于用户兴趣偏好的衰变分析也可以做一定业务场景下的用户推荐。

数据化运营中的精准推荐涉及的业务场景很多,更多时候会从多面分析用户,甚至包括用户画像体系和商品画像体系。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博文视点Broadview 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
TDSQL MySQL 版
TDSQL MySQL 版(TDSQL for MySQL)是腾讯打造的一款分布式数据库产品,具备强一致高可用、全球部署架构、分布式水平扩展、高性能、企业级安全等特性,同时提供智能 DBA、自动化运营、监控告警等配套设施,为客户提供完整的分布式数据库解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档