特征工程
特征工程是机器学习中至关重要的一步,它涉及从原始数据中提取、转换和选择特征,以便更好地训练模型。特征工程的质量直接影响模型的性能,因此掌握这一技能对于任何机器学习从业者来说都是必不可少的。
什么是特征工程?
特征工程是指将原始数据转换为更适合机器学习模型的特征的过程。这些特征可以是数值、类别、文本或其他形式的数据。特征工程的目标是提高模型的预测能力,减少过拟合,并加快训练速度。
特征工程的主要步骤
- 特征提取:从原始数据中提取有用的信息。
- 特征转换:将提取的特征转换为适合模型的格式。
- 特征选择:选择对模型最有用的特征,减少冗余和噪声。
特征提取
特征提取是从原始数据中提取有用信息的过程。例如,从文本数据中提取词频,或从图像数据中提取边缘特征。
示例:文本特征提取
假设我们有一段文本数据,我们可以使用 Spark MLlib 的 Tokenizer
和 CountVectorizer
来提取词频特征。
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
来实现。
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
来选择与目标变量最相关的特征。
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] |
+---+------------------+-----+----------------+
实际案例
假设我们有一个电商数据集,包含用户的年龄、性别、购买金额等信息。我们的目标是预测用户是否会再次购买。我们可以通过特征工程来提取和转换这些特征,以提高模型的预测能力。
- 特征提取:从用户行为日志中提取购买频率、平均购买金额等特征。
- 特征转换:将性别转换为独热编码,将年龄进行分桶处理。
- 特征选择:使用卡方检验选择与目标变量最相关的特征。
总结
特征工程是机器学习中不可或缺的一步,它直接影响模型的性能。通过特征提取、转换和选择,我们可以从原始数据中提取出对模型最有用的信息。Spark MLlib 提供了丰富的工具来帮助我们完成这些任务。
附加资源
- Spark MLlib 官方文档
- 《机器学习实战》—— Peter Harrington
- 《特征工程入门与实践》—— Alice Zheng
练习
- 使用 Spark MLlib 对一个文本数据集进行特征提取和转换。
- 尝试对一个数值数据集进行标准化和特征选择。
- 思考在实际项目中,如何结合业务知识进行特征工程。
特征工程是一个需要不断实践和优化的过程。多尝试不同的方法,结合业务知识,才能找到最适合的特征工程方案。