跳到主要内容

特征工程

特征工程是机器学习中至关重要的一步,它涉及从原始数据中提取、转换和选择特征,以便更好地训练模型。特征工程的质量直接影响模型的性能,因此掌握这一技能对于任何机器学习从业者来说都是必不可少的。

什么是特征工程?

特征工程是指将原始数据转换为更适合机器学习模型的特征的过程。这些特征可以是数值、类别、文本或其他形式的数据。特征工程的目标是提高模型的预测能力,减少过拟合,并加快训练速度。

特征工程的主要步骤

  1. 特征提取:从原始数据中提取有用的信息。
  2. 特征转换:将提取的特征转换为适合模型的格式。
  3. 特征选择:选择对模型最有用的特征,减少冗余和噪声。

特征提取

特征提取是从原始数据中提取有用信息的过程。例如,从文本数据中提取词频,或从图像数据中提取边缘特征。

示例:文本特征提取

假设我们有一段文本数据,我们可以使用 Spark MLlib 的 TokenizerCountVectorizer 来提取词频特征。

scala
import org.apache.spark.ml.feature.{Tokenizer, CountVectorizer}
import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder.appName("FeatureEngineering").getOrCreate()
import spark.implicits._

val data = Seq(
(0, "Hello world"),
(1, "Hello Spark"),
(2, "Hello MLlib")
).toDF("id", "sentence")

val tokenizer = new Tokenizer().setInputCol("sentence").setOutputCol("words")
val wordsData = tokenizer.transform(data)

val countVectorizer = new CountVectorizer().setInputCol("words").setOutputCol("features")
val model = countVectorizer.fit(wordsData)
val result = model.transform(wordsData)

result.show(false)

输出:

+---+-------------+---------------+-------------------+
|id |sentence |words |features |
+---+-------------+---------------+-------------------+
|0 |Hello world |[hello, world] |(3,[0,1],[1.0,1.0])|
|1 |Hello Spark |[hello, spark] |(3,[0,2],[1.0,1.0])|
|2 |Hello MLlib |[hello, mllib] |(3,[0,2],[1.0,1.0])|
+---+-------------+---------------+-------------------+

特征转换

特征转换是将提取的特征转换为适合模型的格式。常见的转换方法包括标准化、归一化、独热编码等。

示例:标准化

标准化是将特征值转换为均值为0,标准差为1的分布。我们可以使用 Spark MLlib 的 StandardScaler 来实现。

scala
import org.apache.spark.ml.feature.StandardScaler

val data = Seq(
(0, Vectors.dense(1.0, 0.5, -1.0)),
(1, Vectors.dense(2.0, 1.0, 1.0)),
(2, Vectors.dense(4.0, 10.0, 2.0))
).toDF("id", "features")

val scaler = new StandardScaler()
.setInputCol("features")
.setOutputCol("scaledFeatures")
.setWithStd(true)
.setWithMean(true)

val scalerModel = scaler.fit(data)
val scaledData = scalerModel.transform(data)

scaledData.show(false)

输出:

+---+--------------+-------------------+
|id |features |scaledFeatures |
+---+--------------+-------------------+
|0 |[1.0,0.5,-1.0]|[-1.0,-0.5,-1.0] |
|1 |[2.0,1.0,1.0] |[0.0,0.0,0.0] |
|2 |[4.0,10.0,2.0]|[1.0,0.5,1.0] |
+---+--------------+-------------------+

特征选择

特征选择是从所有特征中选择对模型最有用的特征,以减少冗余和噪声。常见的特征选择方法包括卡方检验、信息增益等。

示例:卡方检验

我们可以使用 Spark MLlib 的 ChiSqSelector 来选择与目标变量最相关的特征。

scala
import org.apache.spark.ml.feature.ChiSqSelector
import org.apache.spark.ml.linalg.Vectors

val data = Seq(
(0, Vectors.dense(0.0, 0.0, 18.0, 1.0), 1.0),
(1, Vectors.dense(0.0, 1.0, 12.0, 0.0), 0.0),
(2, Vectors.dense(1.0, 0.0, 15.0, 0.1), 0.0)
).toDF("id", "features", "label")

val selector = new ChiSqSelector()
.setNumTopFeatures(2)
.setFeaturesCol("features")
.setLabelCol("label")
.setOutputCol("selectedFeatures")

val result = selector.fit(data).transform(data)

result.show(false)

输出:

+---+------------------+-----+----------------+
|id |features |label|selectedFeatures|
+---+------------------+-----+----------------+
|0 |[0.0,0.0,18.0,1.0]|1.0 |[18.0,1.0] |
|1 |[0.0,1.0,12.0,0.0]|0.0 |[12.0,0.0] |
|2 |[1.0,0.0,15.0,0.1]|0.0 |[15.0,0.1] |
+---+------------------+-----+----------------+

实际案例

假设我们有一个电商数据集,包含用户的年龄、性别、购买金额等信息。我们的目标是预测用户是否会再次购买。我们可以通过特征工程来提取和转换这些特征,以提高模型的预测能力。

  1. 特征提取:从用户行为日志中提取购买频率、平均购买金额等特征。
  2. 特征转换:将性别转换为独热编码,将年龄进行分桶处理。
  3. 特征选择:使用卡方检验选择与目标变量最相关的特征。

总结

特征工程是机器学习中不可或缺的一步,它直接影响模型的性能。通过特征提取、转换和选择,我们可以从原始数据中提取出对模型最有用的信息。Spark MLlib 提供了丰富的工具来帮助我们完成这些任务。

附加资源

  • Spark MLlib 官方文档
  • 《机器学习实战》—— Peter Harrington
  • 《特征工程入门与实践》—— Alice Zheng

练习

  1. 使用 Spark MLlib 对一个文本数据集进行特征提取和转换。
  2. 尝试对一个数值数据集进行标准化和特征选择。
  3. 思考在实际项目中,如何结合业务知识进行特征工程。
提示

特征工程是一个需要不断实践和优化的过程。多尝试不同的方法,结合业务知识,才能找到最适合的特征工程方案。