SparkML机器学习之特征工程(一)特征提取(TF-IDF、Word2Vec、CountVectorizer)

简介:

特征工程

我们都知道特征工程在机器学习中是很重要的,然而特征工程到底是什么?怎么样通俗的理解它呢?打个比方,即使你有再好的渔具,如果给你一片没有鱼的池塘,那也是白费力气的。而特征工程就是找有鱼的那片水域。所以我们可以这么理解,特征是数据中抽取出来的对结果预测有用的信息(水域),而特征工程就是使用专业知识来处理数据,筛选出具有价值的特征(从100个水域中挑选出鱼最多最好的水域)。所以有句话是这么说的:算法再牛逼,其上限也是由特征工程决定的,就像你渔具再好,捕鱼多少也是由水域这个特征决定的。
在SparkML中、对于特征工程的操作主要分为特征提取,特征转化、特征选择

特征提取

从原始数据中提取特征

TF-IDF (Term frequency-inverse document frequency)

TF-IDF称为词频-逆文件频率,先搞清楚它有什么作用吧!很经典的一个问题,如何得到一篇文章的关键词??大家都能想到,看看这篇文章什么词出现最多!思路是没问题,但是,一篇文章,出现最多的,应该都是诸如“的”之类的停用词吧?这就没意义了啊!那就把这些停用词过滤掉呗,这样还是会出问题。比如一篇文章,叫做中国功夫,中国和功夫出现了同样多次数,可是显而易见,该文重点应该是功夫。而出现问题的原因,是因为中国是个热门词。这让我想到我曾写过的基于物品的协同过滤算法,也是要将热门物品做一个惩罚,否则会导致推荐不精确。
image.png
TF-IDF完美的解决了这个问题,TF-IDF作用就是体现一个文档中词语重要程度。TF是某个词或短语在一篇文章中出现的频率。而IDF,就是一种对热门词语的惩罚,对于较热门词语比如"中国"会给予较小的权重,较少见的词“功夫”给予较大的权重。至于如何判断它是否为热门词,则通过该词在整个语料库的出现次数决定。比如中国这个词,语料库一共1000篇文章他就出现了100次,自然为热门词,而功夫,1000篇文章只有1篇出现了,那就为冷门词了。
image.png
image.png

package ml.test
import org.apache.spark.ml.feature.{HashingTF, IDF, Tokenizer}
import org.apache.spark.sql.SparkSession
/**
  * Created by LYL on 2018/4/4.
  */
object TFDemo {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("TF-IDF Demo").master("local").getOrCreate()
    val sentenceData = spark.createDataFrame(Seq(
      (0.0, "china kungfu kungfu is good"),
      (1.0, "I lova china"),
      (2.0, "I love china shenzhen")
    )).toDF("label", "sentence")
    //Tokenizer分词器 将句子分成单词
    val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")
    val wordsData = tokenizer.transform(sentenceData)
    //将每个词转换成Int型,并计算其在文档中的词频(TF)
    //setNumFeatures(200)表示将Hash分桶的数量设置为200个,可以根据你的词语数量来调整,一般来说,这个值越大不同的词被计算为一个Hash值的概率就越小,数据也更准确,但需要消耗更大的内存
    val hashingTF = new HashingTF().setInputCol("words").setOutputCol("TF Features").setNumFeatures(200)
    val featurizedData = hashingTF.transform(wordsData)
    //计算IDF
    val idf = new IDF().setInputCol("TF Features").setOutputCol("TF-IDF features")
    val idfModel = idf.fit(featurizedData)
    val rescaledData = idfModel.transform(featurizedData)
    rescaledData.select("words","TF Features","TF-IDF features")show(false)
  }
}

输出结果为:
由于china在三个文档中都出现了,所以TF-IDF=0.0,而kungfu只在第一个文档出现(说明是冷门词),却是第一个文档中出现次数最多的,因此计算出来的TF-IDF=1.3862943611198906也是最高的

+---------------------------------+----------------------------------------+---------------------------------------------------------------------------------------+
|words                            |TF Features                             |TF-IDF features                                                                        |
+---------------------------------+----------------------------------------+---------------------------------------------------------------------------------------+
|[china, kungfu, kungfu, is, good]|(200,[81,168,169,198],[1.0,1.0,1.0,2.0])|(200,[81,168,169,198],[0.6931471805599453,0.28768207245178085,0.0,1.3862943611198906]) |
|[i, lova, china]                 |(200,[91,129,169],[1.0,1.0,1.0])        |(200,[91,129,169],[0.6931471805599453,0.28768207245178085,0.0])                        |
|[i, love, china, shenzhen]       |(200,[40,129,168,169],[1.0,1.0,1.0,1.0])|(200,[40,129,168,169],[0.6931471805599453,0.28768207245178085,0.28768207245178085,0.0])|
+---------------------------------+----------------------------------------+---------------------------------------------------------------------------------------+

Word2Vec

word2vec是用一个向量去表示一个对象(因为计算机是无法识别对象实体的),对象可以是单词,句子,文章,用户等等。然后基于向量相似度去计算对象的相似度,找到相关的对象,发现相关关系,可以用来做分类、聚类、也可以做词的相似度计算。应用非常广泛,比如:相关词(搜索乔布斯会出来苹果),补全句子中缺失的单词,推荐系统,分析用户关系等等。

object Word2VecDemo {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().master("local[2]").appName("Word2VecDemo").getOrCreate()
    val documentDF = spark.createDataFrame(Seq(
      "Hi I love Spark".split(" "),
      "Hi I love java".split(" "),
      "Logistic regression models are neat".split(" ")
    ).map(Tuple1.apply)).toDF("text")
    // setVectorSize 目标数值向量的维度大小 setMinCount 只有当某个词出现的次数大于或者等于 minCount 时,才会被包含到词汇表里,否则会被忽略掉
    val word2Vec = new Word2Vec()
      .setInputCol("text")
      .setOutputCol("result")
      .setVectorSize(3)
      .setMinCount(0)
    val model = word2Vec.fit(documentDF)
    //​利用Word2VecModel把文档转变成特征向量。
    val result = model.transform(documentDF)
    result.show(false)
  }
}

输出结果为:

+-----------------------------------------+-------------------------------------------------------------------+
|text                                     |result                                                             |
+-----------------------------------------+-------------------------------------------------------------------+
|[Hi, I, love, Spark]                     |[-0.03605498746037483,-0.02823249064385891,0.06127407215535641]    |
|[Hi, I, love, java]                      |[-0.046827200800180435,-0.052235052920877934,0.0025074686855077744]|
|[Logistic, regression, models, are, neat]|[0.04324783757328987,0.030185341089963916,-5.047338083386422E-4]   |
+-----------------------------------------+-------------------------------------------------------------------+

CountVectorizer

由于计算机是不能识别单词的,所以我们要把它转为向量。Countvectorizer和Countvectorizermodel旨在通过计数来将一个文档转换为向量。

object CountVectorizerDemo {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().master("local[2]").getOrCreate()
    val dataFrame = spark.createDataFrame(Seq(
      (0, Array("a", "b","b","c","d","d")),
      (1, Array("a","c","b" ))
    )).toDF("id", "words")

    //setVocabSize设定词汇表的最大容量为3,setMinDF设定词汇表中的词至少要在2个文档中出现过。
    //如果setMinDF=2 那么就不会出现d(只在一个文档存在)了。
    val cv = new CountVectorizer().setVocabSize(3).setMinDF(2).setInputCol("words").setOutputCol("features")
    //如果setVocabSize=2 那么就不会出现a,c(次数少)了。
    val cv1 = new CountVectorizer().setVocabSize(2).setInputCol("words").setOutputCol("features")

    val cvModel = cv.fit(dataFrame)
    val cvModel1 = cv1.fit(dataFrame)

    cvModel.transform(dataFrame).show(truncate = false)
    cvModel1.transform(dataFrame).show(truncate = false)

  }
}

输出结果为:

//3代表词汇表的容量,[0,1,2]分别对应b,a,c,[2.0,1.0,1.0]代表出现次数
+---+------------------+-------------------------+
|id |words             |features                 |
+---+------------------+-------------------------+
|0  |[a, b, b, c, d, d]|(3,[0,1,2],[2.0,1.0,1.0])|
|1  |[a, c, b]         |(3,[0,1,2],[1.0,1.0,1.0])|
+---+------------------+-------------------------+


+---+------------------+-------------------+
|id |words             |features           |
+---+------------------+-------------------+
|0  |[a, b, b, c, d, d]|(2,[0,1],[2.0,2.0])|
|1  |[a, c, b]         |(2,[0],[1.0])      |
+---+------------------+-------------------+
相关文章
|
2月前
|
机器学习/深度学习 数据采集 数据挖掘
特征工程在营销组合建模中的应用:基于因果推断的机器学习方法优化渠道效应估计
因果推断方法为特征工程提供了一个更深层次的框架,使我们能够区分真正的因果关系和简单的统计相关性。这种方法在需要理解干预效果的领域尤为重要,如经济学、医学和市场营销。
78 1
特征工程在营销组合建模中的应用:基于因果推断的机器学习方法优化渠道效应估计
|
7月前
|
机器学习/深度学习 数据采集 算法
探索机器学习中的特征工程
【5月更文挑战第10天】 在机器学习领域,特征工程扮演着至关重要的角色。它涉及选择、修改和创造从原始数据中提取的特征,旨在提高模型的性能。本文将深入探讨特征工程的多个方面,包括数据清洗、特征选择、维度缩减以及特征编码等,同时提供实用的技巧和策略,帮助读者构建出更有效的机器学习模型。
|
5月前
|
机器学习/深度学习 人工智能
8个特征工程技巧提升机器学习预测准确性
8个特征工程技巧提升机器学习预测准确性
118 6
8个特征工程技巧提升机器学习预测准确性
|
4月前
|
机器学习/深度学习 SQL 数据采集
"解锁机器学习数据预处理新姿势!SQL,你的数据金矿挖掘神器,从清洗到转换,再到特征工程,一网打尽,让数据纯净如金,模型性能飙升!"
【8月更文挑战第31天】在机器学习项目中,数据质量至关重要,而SQL作为数据预处理的强大工具,助力数据科学家高效清洗、转换和分析数据。通过去除重复记录、处理缺失值和异常值,SQL确保数据纯净;利用数据类型转换和字符串操作,SQL重塑数据结构;通过复杂查询生成新特征,SQL提升模型性能。掌握SQL,就如同拥有了开启数据金矿的钥匙,为机器学习项目奠定坚实基础。
45 0
|
4月前
|
机器学习/深度学习 数据采集 算法
如何使用机器学习神器sklearn做特征工程?
如何使用机器学习神器sklearn做特征工程?
|
6月前
|
机器学习/深度学习 算法 Python
特征工程:机器学习成功的关键步骤
【6月更文挑战第4天】特征工程是机器学习的关键,涉及特征选择、构建和变换,旨在提升模型性能。通过处理原始数据,如顾客购买行为,选择相关特征,创建新特征并转换数据(如对数变换),可以增强模型预测能力。例如,对异常值丰富的收入数据进行对数变换,可提升模型稳定性和准确性。特征工程是耗时且需要创造力的过程,是连接数据与智能的桥梁,在机器学习中发挥着至关重要的作用。
86 2
|
6月前
|
机器学习/深度学习 分布式计算 监控
在大数据模型训练中,关键步骤包括数据收集与清洗、特征工程、数据划分;准备分布式计算资源
【6月更文挑战第28天】在大数据模型训练中,关键步骤包括数据收集与清洗、特征工程、数据划分;准备分布式计算资源,选择并配置模型如深度学习架构;通过初始化、训练、验证进行模型优化;监控性能并管理资源;最后保存模型并部署为服务。过程中要兼顾数据隐私、安全及法规遵守,利用先进技术提升效率。
116 0
|
7月前
|
机器学习/深度学习 数据采集 算法
探索机器学习中的特征工程之艺术
【5月更文挑战第25天】 在机器学习的实践中,特征工程是连接原始数据与高效模型的桥梁。不同于常规的摘要侧重于概括文章内容,本文将通过具体案例深入剖析特征工程的重要性、方法论以及实际应用中的经验教训。文章将揭示如何通过细致的特征选择、构建和转换,来提升模型性能,并讨论在此过程中遇到的挑战及应对策略。
|
7月前
|
机器学习/深度学习 数据采集 人工智能
探索机器学习中的特征工程最佳实践
【5月更文挑战第21天】 在机器学习领域,特征工程是模型性能优化的关键环节之一。本文将深入探讨特征工程的核心概念、方法及其在构建高效机器学习模型中的应用。文章不仅总结了实用的特征选择技巧和数据预处理策略,还介绍了如何通过自动化工具简化特征工程流程。通过案例分析,我们展示了在不同数据集上应用这些技术的效果,并讨论了特征工程在未来发展中的潜在趋势与挑战。
|
7月前
|
机器学习/深度学习 数据采集 算法
DataFrame 与机器学习:数据预处理与特征工程
【5月更文挑战第19天】数据预处理(如处理缺失值、标准化)和特征工程对机器学习模型的性能至关重要。使用`pandas`进行缺失值填充,`StandardScaler`实现数据标准化,通过创建新特征(如从日期提取月份、对数变换价格)和特征组合增强信息。相关性分析帮助选择重要特征,提升模型准确性和泛化能力。灵活运用这些方法能有效提升模型性能。DataFrame简化了数据操作,助力高效机器学习。
105 1