【SparkML实践5】特征转换FeatureTransformers实战scala版

本节介绍了用于处理特征的算法,大致可以分为以下几组:

  • 提取(Extraction):从“原始”数据中提取特征。
  • 转换(Transformation):缩放、转换或修改特征。
  • 选择(Selection):从更大的特征集中选择一个子集。
  • 局部敏感哈希(Locality Sensitive Hashing, LSH):这类算法结合了特征转换的方面与其他算法。

本章节主要讲转换1

Feature Transformers

Tokenizer(分词)

分词是将文本(如一个句子)拆分成单独词汇(通常是单词)的过程。一个简单的Tokenizer类提供了这项功能。下面的例子展示了如何将句子分割成单词序列。

RegexTokenizer允许基于正则表达式(regex)匹配进行更高级的分词。默认情况下,参数“pattern”(正则表达式,默认值:“\s+”)被用作分隔符来分割输入文本。或者,用户可以将参数“gaps”设置为false,表示正则表达式“pattern”指的是“tokens”,而不是分割间隙,并找到所有匹配的情况作为分词结果。


import org.apache.spark.ml.feature.{RegexTokenizer, Tokenizer}
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._object TokenizerExample {def main(args: Array[String]): Unit = {val spark = SparkSession.builder.master("local[*]").appName("TokenizerExample").getOrCreate()// 数据样本val sentenceDataFrame = spark.createDataFrame(Seq((0, "Hi I heard about Spark"),(1, "I wish Java could use case classes"),(2, "Logistic,regression,models,are,neat"))).toDF("id", "sentence")val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")val regexTokenizer = new RegexTokenizer().setInputCol("sentence").setOutputCol("words").setPattern("\\W") // 或者 .setPattern("\\w+").setGaps(false)val countTokens = udf { (words: Seq[String]) => words.length }val tokenized = tokenizer.transform(sentenceDataFrame)tokenized.select("sentence", "words").withColumn("tokens", countTokens(col("words"))).show(false)val regexTokenized = regexTokenizer.transform(sentenceDataFrame)regexTokenized.select("sentence", "words").withColumn("tokens", countTokens(col("words"))).show(false)spark.stop()}
}
StopWordsRemover(停用词)

停用词是那些应该从输入中排除的词,通常是因为这些词出现频率高而且不携带太多意义。

StopWordsRemover接受一个字符串序列作为输入(例如Tokenizer的输出),并丢弃输入序列中的所有停用词。停用词的列表由stopWords参数指定。可以通过调用StopWordsRemover.loadDefaultStopWords(language)获取一些语言的默认停用词列表,可选的语言有“danish”(丹麦语)、“dutch”(荷兰语)、“english”(英语)、“finnish”(芬兰语)、“french”(法语)、“german”(德语)、“hungarian”(匈牙利语)、“italian”(意大利语)、“norwegian”(挪威语)、“portuguese”(葡萄牙语)、“russian”(俄语)、“spanish”(西班牙语)、“swedish”(瑞典语)和“turkish”(土耳其语)。一个布尔参数caseSensitive指示匹配是否应该区分大小写(默认为false)。

示例

假设我们有以下DataFrame,包含列id和raw:

idraw
0[I, saw, the, red, balloon]
1[Mary, had, a, little, lamb]

应用StopWordsRemover,以raw作为输入列,以filtered作为输出列,我们应该得到以下结果:

idrawfiltered
0[I, saw, the, red, balloon][saw, red, balloon]
1[Mary, had, a, little, lamb][Mary, little, lamb]

在filtered中,停用词“I”、“the”、“had”和“a”已经被过滤掉了。

import org.apache.spark.ml.feature.StopWordsRemover
// $example off$
import org.apache.spark.sql.SparkSessionobject StopWordsRemoverExample {def main(args: Array[String]): Unit = {val spark = SparkSession.builder.master("local[*]").appName("StopWordsRemoverExample").getOrCreate()//创建停用词移除器val remover = new StopWordsRemover().setInputCol("raw").setOutputCol("filtered")val dataSet = spark.createDataFrame(Seq((0, Seq("I", "saw", "the", "red", "balloon")),(1, Seq("Mary", "had", "a", "little", "lamb")))).toDF("id", "raw")remover.transform(dataSet).show(false)spark.stop()}
}
n-gram

n-gram是n个连续词条(通常是单词)的序列,其中n是某个整数。NGram类可以用来将输入特征转换成n-grams。

NGram接受一系列字符串作为输入(例如,Tokenizer的输出)。参数n用于确定每个n-gram中的词条数。输出将包括一系列n-grams,其中每个n-gram由n个连续单词组成的以空格分隔的字符串表示。如果输入序列包含的字符串少于n个,则不会产生输出。


import org.apache.spark.ml.feature.NGram
// $example off$
import org.apache.spark.sql.SparkSessionobject NGramExample {def main(args: Array[String]): Unit = {val spark = SparkSession.builder.master("local").appName("NGramExample").getOrCreate()val wordDataFrame = spark.createDataFrame(Seq((0, Array("Hi", "I", "heard", "about", "Spark")),(1, Array("I", "wish", "Java", "could", "use", "case", "classes")),(2, Array("Logistic", "regression", "models", "are", "neat")))).toDF("id", "words")//NGram 的输出是一个数组,每个元素都是一个 n-gram。//如果输入数组的长度小于 n,则不会生成 n-grams。//NGram 主要用于文本数据,但理论上它可以用于任何序列化的特征。val ngram = new NGram().setN(2).setInputCol("words").setOutputCol("ngrams")val ngramDataFrame = ngram.transform(wordDataFrame)ngramDataFrame.select("ngrams").show(false)spark.stop()}
}
Binarizer

二值化是将数值特征阈值化为二进制(0/1)特征的过程。

二值化器(Binarizer)接受常见的参数inputCol和outputCol,以及用于二值化的阈值。特征值大于阈值的将被二值化为1.0;等于或小于阈值的值将被二值化为0.0。对于inputCol,既支持Vector类型也支持Double类型。


import org.apache.spark.ml.feature.Binarizer
// $example off$
import org.apache.spark.sql.SparkSessionobject BinarizerExample {def main(args: Array[String]): Unit = {val spark = SparkSession.builder.master("local").appName("BinarizerExample").getOrCreate()val data = Array((0, 0.1), (1, 0.8), (2, 0.2))val dataFrame = spark.createDataFrame(data).toDF("id", "feature")val binarizer: Binarizer = new Binarizer().setInputCol("feature").setOutputCol("binarized_feature").setThreshold(0.5)val binarizedDataFrame = binarizer.transform(dataFrame)println(s"Binarizer output with Threshold = ${binarizer.getThreshold}")binarizedDataFrame.show()spark.stop()}
}
PCA

PCA(主成分分析)是一种统计程序,它使用正交变换将一组可能相关的变量的观测值转换为一组线性无关的变量值,这些变量值称为主成分。PCA类训练一个模型,使用PCA将向量投影到低维空间中。下面的例子展示了如何将5维特征向量投影到3维主成分中。

import org.apache.spark.ml.feature.PCA
import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.sql.SparkSessionobject PCAExample {def main(args: Array[String]): Unit = {val spark = SparkSession.builder.master("local").appName("PCAExample").getOrCreate()val data = Array(Vectors.sparse(5, Seq((1, 1.0), (3, 7.0))),Vectors.dense(2.0, 0.0, 3.0, 4.0, 5.0),Vectors.dense(4.0, 0.0, 0.0, 6.0, 7.0))val df = spark.createDataFrame(data.map(Tuple1.apply)).toDF("features")// 初始化PCA,设置降维到3维val pca = new PCA().setInputCol("features").setOutputCol("pcaFeatures").setK(3).fit(df)val result = pca.transform(df).select("pcaFeatures")result.show(false)spark.stop()}
}
PolynomialExpansion

多项式展开是将特征扩展到多项式空间的过程,这个空间是由原始维度的n次组合构成的。PolynomialExpansion类提供了这个功能。下面的例子展示了如何将特征扩展到3次多项式空间。

import org.apache.spark.ml.feature.PolynomialExpansion
import org.apache.spark.ml.linalg.Vectorsimport org.apache.spark.sql.SparkSessionobject PolynomialExpansionExample {def main(args: Array[String]): Unit = {val spark = SparkSession.builder.appName("PolynomialExpansionExample").getOrCreate()val data = Array(Vectors.dense(2.0, 1.0),Vectors.dense(0.0, 0.0),Vectors.dense(3.0, -1.0))val df = spark.createDataFrame(data.map(Tuple1.apply)).toDF("features")val polyExpansion = new PolynomialExpansion().setInputCol("features").setOutputCol("polyFeatures").setDegree(3)val polyDF = polyExpansion.transform(df)polyDF.show(false)spark.stop()}
}
Discrete Cosine Transform (DCT)

离散余弦变换(Discrete Cosine Transform,简称DCT)将时域中长度为N的实数序列转换为频域中另一长度为N的实数序列。一个DCT类提供了这个功能,实现了DCT-II,并通过1/2的平方根来缩放结果。转换后的序列不会应用位移(例如,变换序列的第0个元素是第0个DCT系数,而不是第N/2个)。


import org.apache.spark.ml.feature.DCT
import org.apache.spark.ml.linalg.Vectors
// $example off$
import org.apache.spark.sql.SparkSessionobject DCTExample {/*** 离散余弦变换(Discrete Cosine Transform,简称DCT)是一种用于信号和图像处理的变换,它类似于离散傅立叶变换(Discrete Fourier Transform,简称DFT),但只使用实数。DCT在多个领域非常有用,尤其是在压缩技术中,比如JPEG图像压缩就广泛使用了DCT。*/def main(args: Array[String]): Unit = {val spark = SparkSession.builder.appName("DCTExample").getOrCreate()val data = Seq(Vectors.dense(0.0, 1.0, -2.0, 3.0),Vectors.dense(-1.0, 2.0, 4.0, -7.0),Vectors.dense(14.0, -2.0, -5.0, 1.0))val df = spark.createDataFrame(data.map(Tuple1.apply)).toDF("features")val dct = new DCT().setInputCol("features").setOutputCol("featuresDCT").setInverse(false)val dctDf = dct.transform(df)dctDf.select("featuresDCT").show(false)spark.stop()}
}
StringIndexer

StringIndexer 将包含标签的字符串列编码为标签索引列。StringIndexer 可以编码多个列。索引位于 [0, numLabels) 范围内,并支持四种排序选项:“frequencyDesc”(按标签频率降序,频率最高的标签分配索引0)、“frequencyAsc”(按标签频率升序,频率最低的标签分配索引0)、“alphabetDesc”(按字母表降序)和“alphabetAsc”(按字母表升序,默认为“frequencyDesc”)。注意,在“frequencyDesc”/“frequencyAsc”下,如果频率相同,字符串会进一步按字母表排序。

如果用户选择保留未见过的标签,这些标签将被放置在索引 numLabels 处。如果输入列是数值型,我们会将其转换为字符串并对这些字符串值进行索引。当下游的管道组件如 Estimator 或 Transformer 使用这个字符串索引的标签时,你必须将该组件的输入列设置为这个字符串索引的列名。在许多情况下,你可以使用 setInputCol 来设置输入列。

示例

假设我们有以下包含 id 和 category 列的 DataFrame:

idcategory
0a
1b
2c
3a
4a
5c

category 是一个字符串列,包含三个标签:“a”、“b”和“c”。应用 StringIndexer,并将 category 设置为输入列,categoryIndex 设置为输出列,我们应该得到以下结果:

idcategorycategoryIndex
0a0.0
1b2.0
2c1.0
3a0.0
4a0.0
5c1.0

“a” 获得索引0,因为它是最频繁的,其次是“c”获得索引1,“b”获得索引2。

此外,关于当你在一个数据集上训练了 StringIndexer,然后用它来转换另一个数据集时,StringIndexer 将如何处理未见过的标签,有三种策略:

  • 抛出一个异常(这是默认行为)
  • 完全跳过包含未见标签的行
  • 将未见标签放在一个特殊的额外桶中,索引为 numLabels

让我们回到我们之前的例子,但这次在以下数据集上重用我们之前定义的 StringIndexer:

idcategory
0a
1b
2c
3d
4e

如果你没有设置 StringIndexer 如何处理未见过的标签,或者将其设置为“error”,那么将会抛出一个异常。然而,如果你之前调用了 setHandleInvalid(“skip”),那么将会生成以下数据集:

idcategorycategoryIndex
0a0.0
1b2.0
2c1.0

请注意,包含“d”或“e”的行不会出现。

如果你调用 setHandleInvalid(“keep”),那么将会生成以下数据集:

idcategorycategoryIndex
0a0.0
1b2.0
2c1.0
3d3.0
4e3.0

请注意,包含“d”或“e”的行被映射到索引“3.0”。

import org.apache.spark.ml.feature.StringIndexer
import org.apache.spark.sql.SparkSessionobject StringIndexerExample {def main(args: Array[String]): Unit = {val spark = SparkSession.builder.master("local").appName("StringIndexerExample").getOrCreate()val df = spark.createDataFrame(Seq((0, "a"), (1, "b"), (2, "c"), (3, "a"), (4, "a"), (5, "c"))).toDF("id", "category")val indexer = new StringIndexer().setInputCol("category").setOutputCol("categoryIndex").setHandleInvalid("skip") //#  "error" 或 "keep"val indexed = indexer.fit(df).transform(df)indexed.show()spark.stop()}
}

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

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

相关文章

分组密码工作模式

在密码学中,分组密码工作模式可以提供诸如机密性或真实性的信息服务。 基于分组的对称加密算法(DES 、AES等)只是描述如何根据加密密钥对一段固 定长度(块)的数据进行加密,对于比较长的数据,分组…

Spring AOP的基本使用

Spring AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架的一个重要组成部分,它允许开发者在不修改原有代码的基础上,通过动态代理的方式,在程序的执行过程中插入额外的逻辑。这种编程方式可以有…

C++ 预处理器

预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。 所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C 语句,所以它们不会以分号(;&#xff09…

【Spring Boot 源码学习】BootstrapRegistry 详解

《Spring Boot 源码学习系列》 BootstrapRegistry 详解 一、引言二、往期内容三、主要内容3.1 源码初识3.2 register 方法3.3 registerIfAbsent 方法3.4 isRegistered 方法3.5 getRegisteredInstanceSupplier 方法3.6 addCloseListener 方法3.7 InstanceSupplier 内部接口类3.7…

使用Go的并发模型

Golang提供了强大的并发支持,可以轻松编写高效的并发程序。以下是一些使用Go并发模型的技巧: Goroutine:通过使用goroutine,您可以并发地执行函数或方法,从而充分利用多核处理器的能力。Channel:使用chann…

故障诊断 | 一文解决,GRU门控循环单元故障诊断(Matlab)

文章目录 效果一览文章概述专栏介绍模型描述源码设计参考资料效果一览 文章概述 故障诊断 | 一文解决,GRU门控循环单元故障诊断(Matlab) 专栏介绍 订阅【故障诊断】专栏,不定期更新机器学习和深度学习在故障诊断中的应用;订阅

基于spring boot实现邮箱发送和邮箱验证

目录 一、邮箱发送实现1. 开通邮箱服务2. 添加邮箱依赖3.添加配置4.添加邮箱通用类5. 测试类 二、邮箱验证实现1.添加依赖2. 添加配置3.添加controller4. 测试 项目地址: https://gitee.com/nssnail/springboot-email 一、邮箱发送实现 1. 开通邮箱服务 使用qq邮箱、163邮箱都…

1月无代码资讯 | 两项低代码无代码行业报告相继重磅发布;GitHub Copilot Chat全面开放使用

栏目导读:无代码资讯栏目从全球视角出发,带您了解无代码相关最新资讯。 TOP3 大事件 1、ResearchAndMarkets.com "低代码无代码开发平台市场—— 2018-2028 年全球行业规模、份额、趋势、机遇及预测"报告发布 据雅虎财经近日资讯显示&#xf…

网络层 IP协议(1)

前置知识 主机:配有IP地址,但是不进行路由控制的设备 路由器:既配置了IP地址,又能进行路由控制的设备 节点:主机和路由器的总称 IP协议主要完成的任务就是 地址管理和路由选择 地址管理:使用一套地址体系,将网络设备的地址描述出来 路由选择:一个数据报如何从源地址到目的地址 …

【LVGL源码移植】

LVGL源码移植 ■ LVGL源码移植一:下载LVGL源码二:修改LVGL文件夹1: 将这5个文件,复制到一个新的文件夹2: 简化文件,减少内存消耗(去除不必要的文件)3: 为了规范化,我们将下列文件进行重命名 三&…

git使用方法(简易版)

一、git使用过程 1.注册git账号,并新建一个仓库; http://t.csdnimg.cn/ePcsx可以参考链接 2.在电脑文件夹中,右键选择 Git Bash Here,输入git init(初始化仓库); git init - 初始化仓库。 Git 使用 git …

【Java万花筒】驶入未来:利用Java库构建智能自动驾驶与车联网系统

加速汽车智能化:解析自动驾驶与车联网的Java库应用技巧 前言 随着自动驾驶和车联网技术的发展,开发人员需要强大的工具和资源来构建智能交通系统。本文将介绍几个重要的Java库,包括Autoware、Apollo、OpenXC、CarSync和V2XLib,它…

webassembly003 MINISIT mnist/convert-h5-to-ggml.py

数据结构 # Convert MNIS h5 transformer model to ggml format # # Load the (state_dict) saved model using PyTorch # Iterate over all variables and write them to a binary file. # # For each variable, write the following: # - Number of dimensions (int) # …

张维迎《博弈与社会》多重均衡与制度和文化(1)多重均衡问题

什么是多重均衡 我曾经在课堂上做过这样一个实验:随机选择男女两位同学参加一个选数字的游戏。游戏的基本规则为:每一个同学随机地从1到10十个数字中任意选择5个。如果两人选择的数字没有任何重复的话,则每人可以得到50元;如果两人…

npm install 安装依赖,为什么有时候会修改项目 package-lock.json,怎么解决?

前端开发时经常会接手一个别人创建的项目已经上线了,后期让我来修复缺陷,或者子新增功能。 上来就使用npm install 安装项目依赖,一看package-lock.json文件被自动修改了,可是我也没有修改package.json文件内容啊,不管…

深入了解协议栈内核源码

三次握手内核源码 深入理解 Linux 的 TCP 三次握手_tcp_v4_conn_request-CSDN博客 socket.c 内核态函数入口 三次状态变化 创建socket入口 ping Breakpoint 7, SyS_socket (family2, type3, protocol1) at net/socket.c:1325 1325 SYSCALL_DEFINE3(socket, int, famil…

Google Gemini Pro 国内版

Google Gemini Pro 国内版:【直达链接】 Google Gemini Pro 国内版 能力分类基准测试描述更高分数更好Gemini UltraGPT-4通用MMLU57个主题(包括STEM、人文等)的问题表示是90.0%86.4%(5-shot, 报告)推理Big-Bench Hard…

微信小程序(二十九)交互提示-界面加载框和提示框

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.showLoading加载框示范 2.showToast提示框示范 源码&#xff1a; index.wxml <!-- 列表渲染基础写法&#xff0c;不明白的看上一篇 --> <view class"students"><view class"it…

音视频数字化(音乐CD)

上篇文章【音视频数字化(音频数字化)】我们聊了音频数字化原理,其中谈到了音乐CD,结尾也提到了一个小问题:“CD音质是最高吗?为什么?”不知道大家是怎么理解的。 其实CD质量只是“无损”存储,但是数字化标准只是“44.1kHz,16bit”,因此相对于现在,音质不能说最高。 …

故障诊断 | 一文解决,BP神经网络的故障诊断(Matlab)

文章目录 效果一览文章概述专栏介绍模型描述源码设计参考资料效果一览 文章概述 故障诊断 | 一文解决,BP神经网络的故障诊断(Matlab) 专栏介绍 订阅【故障诊断】专栏,不定期更新机器学习和深度学习在故障诊断中的应用;订阅