Spark 3.0 - 10.Ml 常用 Sample 采样方法

news2024/10/5 13:49:11

目录

一.引言

二.数据准备

三.随机采样 Sample

四.按权重拆分 randomSplit

五.分层采样 sampleByKey

六.总结


一.引言

使用 Spark 进行机器学习、数据分析等项目时,常常需要对数据进行采样,下面介绍三种最常用的采样方法:

A.随机采样: 适合从原始数据随机筛选一部分数据

B.按比例划分采样:适合拆分训练、测试样本

C.分层采样:适合根据不同需求对不同类型样本加权

二.数据准备

- 数据样式

采样前,首先模拟一批正负比 1:4 的正负样本,其中除了 label 外,还有 group 特征区分样本所属分组,共分为 A、B、C 三个组,比例控制在 1:1:1,累计 10000 条样本。

    val spark = SparkSession
      .builder      //创建spark会话
      .master("local")  //设置本地模式
      .appName("SampleUtil")  //设置名称
      .getOrCreate()   //创建会话变量

    spark.sparkContext.setLogLevel("error")

    val random = new scala.util.Random()
    random.setSeed(999)

    val allGroup = Array("A", "B", "C")

    import spark.implicits._

    // 模拟数据,随机分三个组,正负样本 1:4
    val testData = (0 to 10000).map(num => {
      val group = allGroup(random.nextInt(3))
      val label = if (random.nextDouble() > 0.2) {
        0
      } else {
        1
      }
      val features = Seq(random.nextInt(10), random.nextInt(10), random.nextInt(10))
      (label, group, features)
    }).toDF("label", "uGroup", "features")

    testData.printSchema()

- 数据统计

上面生成了原始数据的 DataFrame,下面使用 SparkSql 统计下 Label 与 Group 的分布信息。

    val testTable = "TestTable"
    testData.createOrReplaceTempView(testTable)
    showMetrics(testTable, spark)

其中 showMetrics 为两条 sql 语句:

  def showMetrics(tableName: String, sparkSession: SparkSession): Unit = {
    // 正负样本统计
    sparkSession.sql(s"select label,count(*) as cnt from $tableName group by label").show()
    // 组统计
    sparkSession.sql(s"select uGroup,count(*) as cnt from $tableName group by uGroup order by uGroup").show()
  }

三.随机采样 Sample

    // 1.随机采样
    val randomSampleData = testData.sample(withReplacement=false, fraction = 0.5, seed = 999)
    val randomTable = "RandomSampleTable"
    randomSampleData.createOrReplaceTempView(randomTable)
    showMetrics(randomTable, spark)

随机采样主要有三个参数:

withReplacement - 是否放回,True 有放回情况下一条样本可能会多次抽中

fraction - 采样比例

seed - 随机种子,不同 seed 采样结果不同

fraction = 0.5,所以会保留 50% 的数据,可以看到采样后数据量减半,但是整体比例不会受影响。

四.按权重拆分 randomSplit

    // 2.正负样本划分 randomSplit
    val fraction = Array(0.8, 0.1, 0.1)
    val dataSpilt = testData.randomSplit(fraction)
    val (train, test, valid) = (dataSpilt(0), dataSpilt(1), dataSpilt(2))
    println(s"Train: ${train.count()} Test: ${test.count()} Valid: ${valid.count()}")

randomSplit 方法根据传入的 Array[Ratio*] 分组比例数组对原始样本进行拆分,上述代码按照 8:1:1 拆分训练集、测试集、验证集。

Train: 7949 Test: 1025 Valid: 1027


五.分层采样 sampleByKey

分层采样需要使用 keyBy 生成 pairRDD,通过指定 key 的采样率实现分层采样,这里采样比例 Map 为 <T, Double> 的形式,其中 T 为对应 pairRDD 中 key 的形式,下述代码实现了保留全部正样本,并随机挑选一半负样本。

    // 3.分层采样
    val keyByData = testData.rdd.keyBy(_.getInt(0))
    val sampleRatio = Map(0 -> 0.5, 1 -> 1.0)
    val addWeight = keyByData.sampleByKey(withReplacement = false, fractions = sampleRatio).map(_._2)

由于 sampleByKey 后获取的是 RDD<T, Row> 的形式,为了进行 spark sql 统计需要将 RDD 转换为 DataFrame:

    val schema =
    StructType(
      StructField("label", IntegerType, false) ::
        StructField("uGroup", StringType, false) ::
        StructField("features", ArrayType(IntegerType), false) :: Nil
    )
    println(schema)

    val name = "addWeightTable"
    addWeightTable.createOrReplaceTempView(name)
    showMetrics(name, spark)

Tips:

这里 RDD 转 DF 可以不使用 schema,此时字段变为 _1、_2 ... 为了继续使用 showMetrics 方法,所以指定 schema,除了上面手动指定外,也可以使用 case class 进行推理:

  case class User(label: Int, uGroup: String, features: Array[Int])

    import org.apache.spark.sql.catalyst.ScalaReflection
    val scalaSchema = ScalaReflection.schemaFor[User].dataType.asInstanceOf[StructType]
    val encoderSchema = Encoders.product[User].schema
    println(encoderSchema)

上面为手动定义的 schema,下面为推理得到的 schema,主要差别在 nullable 参数。

六.总结

randomSplit 按权重拆分训练集、测试集以及 randomByKey 对样本进行分层采样,例如上采样可以使用上述方法多次采样保留更多正样本,也可以指定不同 seed 实现 Bagging 采样。

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

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

相关文章

Vue3 学习笔记 —— 自动导入 Vue3 APIs、v-model

目录 1. 自动导入 Vue3 APIs —— unplugin-auto-import/vite 2. v-model 2.1 相较于 Vue2&#xff0c;Vue3 做出了哪些变化&#xff1f; 2.2 绑定一个 v-model 2.2.1 父组件 2.2.2 子组件 2.3 绑定多个 v-model 2.3.1 父组件 2.3.2 子组件 2.4 v-model 中的自定义修…

Android Material Design之ShapeableImageView(十三)

效果图 资源引入 implementation com.google.android.material:material:1.4.0属性 属性描述android:id控件idandroid:layout_width控件长度android:layout_height控件高度app:shapeAppearance控件外观样式app:strokeWidth画笔粗度app:strokeColor画笔颜色android:src图像资源…

MySQL逻辑架构

逻辑架构剖析 服务器处理客户端请求 数据库查询请求流程&#xff1a; 连接层 系统&#xff08;客户端&#xff09;访问 MySQL 服务器前&#xff0c;做的第一件事就是建立 TCP 连接。 经过三次握手建立连接成功后&#xff0c; MySQL 服务器对 TCP 传输过来的账号密码做身份认…

了解Wi-fi频段概念

前言 信道带宽&#xff0c;应该了解wi-fi频段&#xff0c;这样才能分析有多少信道带宽可用&#xff0c;以及如何在没有任何干扰&#xff08;失真&#xff09;的情况下有效地使用它。 2.4GHz和5GHz频段可用于wi-fi。 2.4 GHz Wi-Fi频段&#xff1a;在2.4 GHz频段&#xff0c;…

通过Shell脚本自动安装HiveJDBC测试提供CDH5网盘地址

〇、参考地址 1、Linux下编写脚本自动安装hive https://blog.csdn.net/weixin_44911081/article/details/121227024?ops_request_misc%257B%2522request%255Fid%2522%253A%2522163695916016780269859534%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%252…

Linux——网络配置(重点)

目录 一、查看网络IP和网关 1.1 那怎么看连接成功呢&#xff1f; 1.1.1 虚拟机接受主机 1.1.2 主机可以接收到虚拟机 1.2 怎么查看电脑的IP地址 方法一&#xff1a; 方法二&#xff1a; 1.3 怎么查看虚拟机的IP地址 二、网络连接模式 2.1 基本了解 2.2 VMware三种网络…

夯实算法-每日温度

题目&#xff1a;LeetCode 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。…

【关系抽取】基于Bert的信息抽取模型CasRel

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

冒名顶替综合症:悄悄地杀死你的梦想

如今&#xff0c;越来越多的开发人员自学成才&#xff0c;很容易消极地与那些拥有计算机科学学士学位或硕士学位的同事进行比较&#xff0c;但请不要这样做。 你们中的很多都很出色&#xff0c;只是你们不清楚这一点。看到那些认为自己不够优秀&#xff0c;但实际上很了不起的人…

MySQL语句

目录 一、常用查询 二、高级SQL语句 1、按关键字排序 单字段排序 按分数降序排列 结合条件过滤 多字段排序 查询学生信息先按兴趣id升序排列&#xff0c;相同分数的&#xff0c;id按升序排列 区间判断及查询不重复记录 嵌套/多条件 对hobbyid进行分组查询&#xff0c…

RabbitMQ学习笔记之Work Queues

工作队列(又称任务队列)的主要思想是避免立即执行资源密集型任务&#xff0c;而不得不等待它完成。 相反我们安排任务在之后执行。我们把任务封装为消息并将其发送到队列。在后台运行的工作进 程将弹出任务并最终执行作业。当有多个工作线程时&#xff0c;这些工作线程将一起…

Nacos2.0.3集群搭建

集群搭建 前置条件 JDK 1.8MySQL 5.7.29Nacos 2.0.3 搭建过程 将Nacos安装包上传至三个服务器&#xff0c;本次搭建使用三个端口来模拟三个不同的主机解压&#xff1a; tar -zvxf nacos-server-2.0.3.tar.gzNacos持久化&#xff0c;首先确保服务器已经安装MySQL(Nacos持久化要…

爆肝!阿里最新版的Spring Security源码手册,强行霸占GitHub榜首

写在前面 Spring Security 的前身是 Acegi Security&#xff0c;在被收纳为Spring 子项目后正式更名为Spring Security。在笔者成书时&#xff0c;Spring Security已经升级到5.1.3.RELEASE版本&#xff0c;加入了原生OAuth2.0框架&#xff0c;支持更加现代化的密码加密方式。 …

你入职的时候一定要问领导要的maven私服配置文件,它是什么?Nexus入门使用指南

上一篇教大家如何在Linux搭建Nexus Linux安装Nexus&#xff08;图文解说详细版&#xff09; 文章目录&#x1f64b;登录Nexus&#x1f470;在maven中配置自己的私服地址&#x1f647;在idea中使用nexus作为maven私服&#x1f491; 引用nexus里面的jar包&#x1f487;配置maven文…

【NLP】自然语言处理的语料库与词库

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

双十二有哪些实用性强的数码好物?值得入手的实用数码好物推荐

赶在年末的双十二快来了&#xff0c;大家有没有心仪的数码好物正在购物车里蠢蠢欲动呢&#xff1f;入手数码产品最重要的还是要看其实用性强不强&#xff0c;下面&#xff0c;我整理了一份值得入手的实用数码好物清单&#xff0c;希望能给大家有个参考。 一、蓝牙耳机 蓝牙耳…

10、Springboot整合Security很全

1.什么是Security SpringSecurity是基于Spring AOP和Servlet过滤器的安全框架。 它提供全面的安全性解决方案&#xff0c;同时在Web 请求级和方法调用级处理身份确认和授权。 2.Spring Security核心功能&#xff1f; &#xff08;1&#xff09;认证&#xff08;你是谁&…

Java集合容器面试题(2023最新版)

集合容器概述 什么是集合 集合框架&#xff1a;用于存储数据的容器。 集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。 任何集合框架都包含三大块内容&#xff1a;对外的接口、接口的实现和对集合运算的算法。 接口&#xff1a;表示集合的抽象数据类型。接口…

王洪伟:流体力学与微积分方法求解水池进排水问题

作者 | 王洪伟 北京航空航天大学副教授&#xff0c;仿真秀专栏作者 导 读&#xff1a;经过了几篇略显烧脑的文章后&#xff0c;来一篇轻松一点的&#xff0c;经典的小学数学应用题。 1、问题分析 题&#xff1a;一个水池有一个进水管和一个排水管。只开进水管&#xff0c;2个…

Linux常用命令总结

目录和文件命令 &#xff08;1&#xff09;用户目录&#xff1a;位于/home/user&#xff0c;称之为用户工作目录&#xff1b; &#xff08;2&#xff09;ls&#xff1a;是英文单词list的简写&#xff0c;其功能为列出目录的内容&#xff1b; ls -a 列出隐藏文件&#xff0c;文…