职业院校大数据技术——数据挖掘1

c

)

/

d

]

[x, y] 转换为 [(x - a) / b, (y - c) / d]

[x,y]转换为[(x−a)/b,(y−c)/d]。

基础知识

余弦相似度

  • A,B为向量,向量长度必须一致,这表示维度一致。
  • 公式如下:
    余弦相似度计算公式
  • 代码如下:

import org.apache.spark.ml.linalg.{Vector, Vectors}
import org.apache.spark.sql.functions.udf

// 定义一个UDF,用于计算两个向量的余弦相似度
val cosineSimilarity = udf((v1: Vector, v2: Vector) => {
  val dotProduct = v1.dot(v2)
  val norms = Vectors.norm(v1, 2) \* Vectors.norm(v2, 2)
  dotProduct / norms
}:Double)



上面的v1,v2可以看作向量A、B。

这段代码是用来计算两个向量的余弦相似度。余弦相似度是一种常用的相似度度量方法,它可以衡量两个向量之间的夹角的余弦值。如果两个向量的方向完全相同,那么它们的余弦相似度就是1;如果两个向量的方向完全相反,那么它们的余弦相似度就是-1;如果两个向量是正交的,那么它们的余弦相似度就是0。

这段代码中的每一行都有特定的作用:

  1. val dotProduct = Vectors.dot(v1, v2):这行代码计算了向量v1和v2的点积。点积是将两个向量的对应元素相乘,然后将结果相加得到的一个标量。公式中对应分子的计算
  2. val norms = Vectors.norm(v1, 2) * Vectors.norm(v2, 2):这行代码计算了向量v1和v2的范数(也就是长度),然后将结果相乘。范数是将向量的每个元素的平方相加,然后取平方根得到的一个标量。公式中对应分母的计算。
  3. dotProduct / norms:这行代码计算了点积除以范数的结果。这就是余弦相似度。

23年国赛题代码

每个feature函数和它调用的子函数表示每个特征工程的任务代码。

为什么要这么写呢?
因为不可能一步到位,所以分步完成每一个任务。

注意:代码中数据获取皆从mysql中获取,任务书可能要求是hive、hudi。

package Bds

import Bds.DataFrameUtils._  // 这是封装的一个获取各种数据仓库配置项的模块
import org.apache.spark.ml.feature._
import org.apache.spark.ml.linalg._
import org.apache.spark.ml.functions.vector\_to\_array
import org.apache.spark.sql.DataFrame
import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions._

object dataMining {
  val spark = getSparkSession("dataM")
  spark.sparkContext.setLogLevel("OFF")
  // 获取mysql配置项
  val mySQLConfig = getMySQLCf("shtd\_store","sku\_info","bigdata1")

  def order_detail(): DataFrame ={
    mySQLConfig("dbtable") = "order\_info"
    val order = spark.read.format("jdbc").options(mySQLConfig).load()
    mySQLConfig("dbtable") = "order\_detail"
    val detail = spark.read.format("jdbc").options(mySQLConfig).load()
    mySQLConfig("dbtable") = "sku\_info"
    val sku_info = spark.read.format("jdbc").options(mySQLConfig).load()

    // 连接三个表即可剔除不存在现有维表的数据
    order.join(detail,order("id")===detail("order\_id"))
      .select(order("user\_id"),detail("sku\_id"))
      .join(sku_info,col("sku\_id")===col("id"))
      // 不确定种类是指sku\_id还是category3\_id,这里用的是category,如果使用sku\_id注释掉下面这一行即可
      .select(col("user\_id"),col("category3\_id").as("sku\_id"))
      .dropDuplicates("user\_id","sku\_id")
  }

  def feature1(targetUser:Int=6708): Unit ={
    val userBuySku = order_detail()

    val resultDf = userBuySku.filter(col("user\_id")=!=targetUser).join(
      userBuySku.filter(col("user\_id")===targetUser),
      Seq("sku\_id"),"semi"
    ).groupBy("user\_id").count()
    val result = resultDf.orderBy(desc("count")).limit(10)
      .collect().map(_.getLong(0)).mkString(",")
    println("-------------------相同种类前10的id结果展示为:--------------------")
    println(result)

  }


  def skuFeature(): DataFrame ={
    // 读取商品数据
    val sku = spark.read.format("jdbc").options(mySQLConfig).load()

    // 对price、weight进行规范化(StandardScaler)
    val vectorCol = Array("price","weight")
    val assembler = new VectorAssembler().setInputCols(vectorCol).setOutputCol("feature")
    val assembled= assembler.transform(sku)
    val Scaler = new StandardScaler().setInputCol("feature").setOutputCol("selectFeature")
      .setWithMean(true)
      .setWithStd(true)
    var scaled = Scaler.fit(assembled).transform(assembled)
      .withColumn("selectFeature", vector_to_array(col("selectFeature")))
      .withColumn("price",col("selectFeature").getItem(0))
      .withColumn("weight",col("selectFeature").getItem(1))


    // scaled.show()
    val categoryColNames:Array[String] = Array("spu\_id","tm\_id","category3\_id")
    // 如果类别字段是从1开始的,就使用下面的代码
    scaled = categoryColNames.foldLeft(scaled){
      (tmpDf,colName)=>{
        tmpDf.withColumn(colName,col(colName)-1)
      }
    }
	// 对类别字段做OneHot处理
    val encoder = new OneHotEncoder()
      .setInputCols(categoryColNames)
      .setOutputCols(Array("spu\_idOH","tm\_idOH","category3\_idOH"))
      .setDropLast(false)
    val encoded = encoder.fit(scaled).transform(scaled)
    val result = encoded.drop(categoryColNames: _\*)
      .select(
        col("id").cast("double"),
        col("price"),
        col("weight"),
        col("spu\_idOH"),
        col("tm\_idOH"),
        col("category3\_idOH")
      )

    // 这里id还是整型,国赛要求是double
    result.orderBy("id")
  }

  def feature2(): Unit ={
    // 只要第一行,节省计算量
    val output = skuFeature().limit(1)
    
    val assembler = new VectorAssembler().setInputCols(Array("id","price","weight","spu\_idOH","tm\_idOH","category3\_idOH"))
      .setOutputCol("V")
    val assembled = assembler.transform(output)
    println("--------------------第一条数据前10列结果展示为:---------------------")
    val V: SparseVector = assembled.first().getAs[SparseVector]("V")
    // 注意每个类型字段都被额外加了一个元素在下标为0的位置
    val result = (0 to 9).map(V(_)).mkString(",")
    println(result)
  }

  /\*\*
 \*
 \* @param targetUser 目标用户
 \* @param top10UserId 通过feature1获得
 \*/
  def recmd_sys(top10UserId:Array[Int],targetUser:Int=6708): Unit ={  
    // 筛除需要使用的数据
    val UserBuySku = order_detail().filter(col("user\_id").isin(top10UserId) || col("user\_id")===targetUser).cache()
    // 剔除目标用户购买过的商品
    val userT = UserBuySku.filter(col("user\_id")===targetUser)  // user id == targetUser 的数据
    val top10UserBuySku= UserBuySku.join(userT,Seq("sku\_id"),"left\_anti")  // 返回不存在6708用户买过的商品数据
      .dropDuplicates("sku\_id")  // 去重商品,避免留下多个用户买过的同一商品

    val sku_feature = skuFeature()

    // sku\_feature所有字段做为向量
    val assembler = new VectorAssembler().setInputCols(sku_feature.columns).setOutputCol("V")
    val assembled = assembler.transform(sku_feature)
      .select(
        col("id").cast("Long"),
        col("V")
      )

    // 跟上各自商品的特征
    val joinOn = col("sku\_id")===col("id")
    val userTWithV = userT.join(assembled,joinOn)
    val top10UserBuySkuWithV = top10UserBuySku.join(assembled,joinOn)

    val result = userTWithV.alias("u").crossJoin(top10UserBuySkuWithV.alias("t"))
      .withColumn("cosineSimilarity",cosineSimilarity(col("u.V"),col("t.V")))
      .groupBy("sku\_id").agg(mean("cosineSimilarity").alias("cosineSimilarity"))

    println("------------------------推荐Top5结果如下------------------------")
    result.orderBy(col("cosineSimilarity").desc).limit(10)
      .collect().map(x=>(x.getLong(0),x.getDouble(1)))
      .zipWithIndex
      .foreach(x=>{
        println(s"相似度top${x.\_2}(商品id:${x.\_1.\_1},平均相似度:${x.\_1.\_2})")
      })
  }

  def main(args: Array[String]): Unit = {
    // feature1() // 参数填入任务书指定的用户id
    // feature2() // 特征2的结果
    // recmd\_sys() // 推荐系统的结果,参数有注释
    spark.stop()
  }
}



![img](https://img-blog.csdnimg.cn/img_convert/ccde460603514b729f5f1f07e6f785c4.png)
![img](https://img-blog.csdnimg.cn/img_convert/b0674097342521ce72ad9d9d0000669b.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

093303)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
数据挖掘分析面试题 数据挖掘分析面试题全文共16页,当前为第1页。数据挖掘分析面试题全文共16页,当前为第1页。2011Alibaba数据分析师(实习)试题解析 数据挖掘分析面试题全文共16页,当前为第1页。 数据挖掘分析面试题全文共16页,当前为第1页。 一、异常值是指什么?请列举1种识别连续型变量异常值的方法? 异常值(Outlier) 是指样本中的个别值,其数值明显偏离所属样本的其余观测值。在数理统计里一般是指一组观测值中与平均值的偏差超过两倍标准差的测定值。 Grubbs' test(是以Frank E.Grubbs命名的),又叫maximumnormed residual test,是一种用于单变量数据集异常值识别的统计检测,它假定数据集来自正态分布的总体。 未知总体标准差σ,在五种检验法中,优劣次序为:t检验法、格拉布斯检验法、峰度检验法、狄克逊检验法、偏度检验法。 二、什么是聚类分析?聚类算法有哪几种?请选择一种详细描述其计算原理和步骤。 聚类分析(clusteranalysis)是一组将研究对象分为相对同质的群组(clusters)的统计分析技术。聚类分析也叫分类分析(classification analysis)或数值分类(numerical taxonomy)。聚类与分类的不同在于,聚类所要求划分的类是未知的。 聚类分析计算方法主要有: 层次的方法(hierarchical method)、划分方法(partitioning method)、基于密度的方法(density-based method)、基于网格的方法(grid-based method)、基于模型的方法(model-based method)等。其中,前两种算法是利用统计学定义的距离进行度量。 k-means 算法的工作过程说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数. k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。 其流程如下: (1)从 n个数据对象任意选择 k 个对象作为初始聚类中心;      (2)根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;   (3)重新计算每个(有变化)聚类的均值(中心对象); (4)循环(2)、(3)直到每个聚类不再发生变化为止(标准测量函数收敛)。 优 点:本算法确定的K 个划分到达平方误差最小。当聚类是密集的,且类与类之间区别明显时,效果较好。对于处理大数据集,这个算法是相对可伸缩和高效的,计算的复杂度为 O(NKt),其中N是数据对象的数目,t是迭代的次数。一般来说,K<<N,t<<N 。 缺点:1. K 是事先给定的,但非常难以选定;2. 初始聚类中心的选择对聚类结果有较大的影响。 三、根据要求写出SQL 表A结构如下: Member_ID (用户的ID,字符型) Log_time (用户访问页面时间,日期型(只有一天的数据)) URL (访问的页面地址,字符型) 要求:提取出每个用户访问的第一个URL(按时间最早),形成一个新表(新表名为B,表结构和表A一致) create table B as select Member_ID,min(Log_time), URL from A group by Member_ID ; 四、销售数据分析 以下是一家B2C电子商务网站的一周销售数据,该网站主要用户群是办公室女性,销售额主数据挖掘分析面试题全文共16页,当前为第2页。数据挖掘分析面试题全文共16页,当前为第2页。要集中在5种产品上,如果你是这家公司的分析师, a) 从数据中,你看到了什么问题?你觉得背后的原因是什么? b) 如果你的老板要求你提出一个运营改进计划,你会怎么做? 表如下:一组每天某网站的销售数据 数据挖掘分析面试题全文共16页,当前为第2页。 数据挖掘分析面试题全文共16页,当前为第2页。 a) 从这一周的数据可以看出,周末的销售额明显偏低。这其中的原因,可以从两个角度来看:站在消费者的角度,周末可能不用上班,因而也没有购买该产品的欲望;站在产品的角度来看,该产品不能在周末的时候引起消费者足够的注意力。 b) 针对该问题背后的两方面原因,我的运营改进计划也分两方面:一是,针对消费者周末没有购买欲望的心理,进行引导提醒消费者周末就应该准备好该产品;二是,通过该产品的一些类似于打折促销等活动来提升该产品在周末的人气和购买力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值