08 | 模型优化(上):怎么用特征工程提高模型效率?
![](https://static001.geekbang.org/resource/image/54/b3/542348edd9596bd5a303a2c78f8d29b3.jpg)
- 深入了解
- 翻译
- 解释
- 总结
![](https://static001.geekbang.org/resource/image/d0/e4/d0880927e2a522a038be2d04bf19dfe4.png)
特征工程在机器学习中扮演着至关重要的角色。本文详细介绍了特征工程的基本思路和实际操作方法,包括特征选择、特征变换和特征构建。通过相关性热力图确定哪些特征对标签的预测或分类起着重要作用,降低数据维度,节省模型拟合时的计算空间。文章还介绍了对数值型特征的缩放和类别型特征的变换方法,以及对数值型特征离散化的情况。特征构建是整个特征工程领域最具创造力的部分,通过实例和代码演示,使读者能够深入了解特征工程的重要性和实际操作方法。总的来说,本文为读者提供了有力的指导和帮助,使他们能够在机器学习项目中进行特征工程时更加得心应手。 在思考题部分,读者被鼓励尝试使用不同的特征缩放器和OneHotEncoder工具,以拓展对特征工程的理解。此外,读者还被邀请分享自己在工作中使用特征工程构建新特征的经验,或者对特征工程的新理解。这种互动性和实践性使得本文不仅是一篇理论性的介绍,更是一次实际操作的引导和启发。 总的来说,本文内容丰富,涵盖了特征工程的基本概念和实际操作,同时通过思考题部分增加了互动性和实践性,为读者提供了全面的学习体验。
《零基础实战机器学习》,新⼈⾸单¥59
全部留言(13)
- 最新
- 精选
- 在路上佳哥好,我的理解是,特征构建是将数据和经验相结合,提炼数据的特征,提高模型预测的准确度;特征变换是将数据变成可运算的,或者转化成关心的尺度,减少计算资源的消耗;特征选择既可以去掉重复的特征,提高模型预测的准确度,也可以去掉相关度较小的特征,减少计算资源的消耗,但代价是牺牲模型预测的准确度。 get_dummies将城市这一个维度变成了N个维度,是不是可以把N个维度合并,用位来表示不同的城市?
作者回复: 如果把N个维度合并,变成一个维度-“城市”1-北京,2-上海,3-苏州,4...,5...,6.... 我想那样是不对的,为什么呢,因为回归模型会认为苏州比上海大,上海比北京大。影响权重的分配。需要全部转换为N个 0 、 1 虚拟变量编码才是正确的做法。
2021-09-1512 - 谦‘’数据和特征决定了机器学习的上限,而模型和算法只是无限逼近这个上限而已‘’,对这句话深有体会,特征工程,特别是特征构建是核心竞争力,花时间最多的也是数据采集和特征提取。每一次训练的模型预测结果不理想,都要反过去考虑是不是数据样本太片面了,是不是还有更好的特征可以使用,还能不能构建出更好的特征?
作者回复: 是这样的,调包容易,数据的收集和预处理难。需要领域知识和经验,也就是domain knowledge.
2021-09-1525 - iron我敢说这一章关于虚拟变量和独热编码的区别,没几个“零基础”的兄弟能看懂,反正要不是再去百度研究几小时,我是肯定看不懂。
作者回复: 的确,写的不够清晰。下面再解释解释。 假设我们有一个名为 Color 的特征,其中包含三种可能的颜色值:Red、Green 和 Blue。 1. 虚拟变量 (Dummy Variables) 对于虚拟变量方法,我们会为 k-1(即 3-1=2)个类别创建新的二元特征。 可能的输出是: Color Dummy_Red Dummy_Green Red 1 0 Green 0 1 Blue 0 0 这里,我们不需要 Dummy_Blue 列,因为当 Dummy_Red 和 Dummy_Green 都为 0 时,我们可以推断颜色是 Blue。 2. 独热编码 (One-Hot Encoding) 对于独热编码,我们会为所有 k 个类别创建新的二元特征。 输出如下: Color OneHot_Red OneHot_Green OneHot_Blue Red 1 0 0 Green 0 1 0 Blue 0 0 1 每种颜色都有一个独立的列,其中 1 表示该颜色的存在,0 表示不存在。 虚拟变量 (Dummy Variables): 对于一个有 k 个类别的特征,创建 k-1 个新的二元特征。 通过省去一个虚拟变量来避免"虚拟变量陷阱"。这是因为 k-1 个虚拟变量就足以表示 k 个类别。 独热编码 (One-Hot Encoding): 对于一个有 k 个类别的特征,创建 k 个新的二元特征。 在某些机器学习算法中(例如决策树或随机森林),不需要担心"虚拟变量陷阱",因此独热编码通常是一个好选择。 总结: 虚拟变量为 k 个类别创建 k-1 个特征,而独热编码为 k 个类别创建 k 个特征。 虚拟变量方法通常用于线性回归中,以避免多重共线性,而独热编码在许多其他机器学习算法中更为常用。
2022-12-28归属地:浙江33 - Mark@ZEGO思考题2: from sklearn.preprocessing import OneHotEncoder #导入OneHotEncoder工具 encoder = OneHotEncoder(sparse=False) df_city = encoder.fit_transform(df_sales.城市.values.reshape(-1, 1)) df_city = pd.DataFrame(df_city, columns=encoder.get_feature_names()) df_sales = pd.concat([df_sales, df_city], axis=1) df_sales = df_sales.drop(['城市'], axis=1)
作者回复: OK
2022-03-102 - trust老师,之前用多项式拟合的时候,拟合效果挺好,但是用预测方面上比较差。比如用x属于1到100的数据来拟合,来预测x是120的结果,就不准了,是不是过拟合还是其他方面的问题哒~
作者回复: 拟合效果好,但是预测不准,就是存在过拟合的问题了。模型太过于依赖训练集数据了。
2021-12-281 - Vincent老师,请问一个问题。文中“。。。其实,我们从图中可以观察到,X-Y 之间的关系其实更接近多项式回归(polynomial regression)中的二项式回归,也就是说,Y 是 X 的二次函数。那么,我们就在 X 的基础上做个平方,构建出一个新特征。”,为什么要构建一个特征为 X 平方?机器学习不能从特征 X 和 y的值中找到这个平方关系?这应该是机器学习的目的吧?
作者回复: 您提出的问题非常好,在理想情况下,如果我们的机器学习模型足够强大,理论上它应该能从数据中学习出任何类型的关系,包括线性和非线性关系。然而,实际情况中,大多数机器学习模型,尤其是传统的算法,如线性回归、逻辑回归等,主要是设计用来捕捉数据中的线性关系。它们在处理非线性关系时表现不佳,除非显式地对特征进行转换。 回到您的问题,“为什么要构建一个特征为 X 的平方?”这是因为当我们观察到 X 和 Y 之间的关系更像是一个二次函数时,直接在模型中引入 X 的平方作为新特征,可以帮助模型更好地捕捉这种非线性关系。实际上,通过添加 X 的平方(或者其他形式的转换),我们是在帮助模型“看到”数据中可能存在的非线性模式。 如果使用的是像决策树或随机森林这样的非线性模型,它们可能能自然地捕捉到非线性关系,不过在许多情况下,即使是这些模型,通过显式地引入新的非线性特征也能提升性能。 这就是特征工程的一个重要方面:通过转换和构建新特征,我们不仅能提高模型的性能,还能增加模型对数据的理解,使其能够适应更复杂的数据模式。
2024-01-02归属地:上海 - SYN数字化技术plt.scatter(df.X, df.Y) #散点图 plt.plot(X_test, model.predict(X_test),linestyle='--', color = 'red') #显示拟合曲线 上面的代码是不是有问题?既然真实数据使用散点图,那么测试集也应该用散点图画图,这样才能显示出测试集的散点图能不能拟合真实数据
作者回复: 我们的目标是展示模型是如何拟合到真实数据的,咱们的代码是可以很直观地显示模型预测的曲线和真实数据之间的关系。 但如果目标是同时展示训练集的数据分布和测试集的预测结果与真实结果的差异,那么你当然可以为测试集的真实值也绘制一个散点图。这样可以看到模型在训练集上的拟合情况和在测试集上的预测准确性 例如: plt.scatter(df.X, df.Y, label="真实数据") plt.scatter(X_test, Y_test, color='green', marker='x', label="测试集真实值") plt.plot(X_test, model.predict(X_test), linestyle='--', color='red', label="预测曲线") plt.legend() plt.show() 在这里,Y_test是测试集的真实值,我们使用绿色的x标记表示。这样的图形会更加直观地显示模型在测试集上的表现。
2023-10-24归属地:山东 - Matthew# 评估模型 from sklearn.metrics import r2_score, median_absolute_error #导入Sklearn评估模块 print('验证集上的R平方分数-随机森林(无缩放): %0.4f' % r2_score(y_valid, model_rfr.predict(X_valid))) print('验证集上的R平方分数-随机森林(标准化): %0.4f' % r2_score(y_valid, model_rfr_standard.predict(X_valid_standard))) print('验证集上的R平方分数-随机森林(归一化): %0.4f' % r2_score(y_valid, model_rfr_minmax.predict(X_valid_minmax))) print('验证集上的R平方分数-随机森林(百分位数): %0.4f' % r2_score(y_valid, model_rfr_robust.predict(X_valid_robust))) print('验证集上的R平方分数-随机森林(规范化): %0.4f' % r2_score(y_valid, model_rfr_normalize.predict(X_valid_normalizer)))
作者回复: ✌️
2023-05-31归属地:江苏 - Matthew课后作业第1题: ## 四种特征缩放器比较 # 第一种缩放 标准化 from sklearn.preprocessing import StandardScaler #导入标准化缩放器 scaler = StandardScaler() #创建标准化缩放器 X_train_standard = scaler.fit_transform(X_train) #拟合并转换训练集数据 X_valid_standard = scaler.transform(X_valid) #转换验证集数据 X_test_standard = scaler.transform(X_test) #转换测试集数据 # 第二种缩放 归一化 from sklearn.preprocessing import MinMaxScaler #导入归一化缩放器 scaler = MinMaxScaler() #创建归一化缩放器 X_train_minmax = scaler.fit_transform(X_train) #拟合并转换训练集数据 X_valid_minmax = scaler.transform(X_valid) #转换验证集数据 X_test_minmax = scaler.transform(X_test) #转换测试集数据 # 第三种缩放 百分位数缩放 from sklearn.preprocessing import RobustScaler #导入归一化缩放器 scaler = RobustScaler() #创建百分位数缩放器 X_train_robust = scaler.fit_transform(X_train) #拟合并转换训练集数据 X_valid_robust = scaler.transform(X_valid) #转换验证集数据 X_test_robust = scaler.transform(X_test) #转换测试集数据 # 第四种缩放 规范化缩放 from sklearn.preprocessing import Normalizer #导入归一化缩放器 scaler = Normalizer() #创建规范化缩放器 X_train_normalizer = scaler.fit_transform(X_train) #拟合并转换训练集数据 X_valid_normalizer = scaler.transform(X_valid) #转换验证集数据 X_test_normalizer = scaler.transform(X_test) #转换测试集数据 #----------------------------------------------------------------------# ## 模型、训练、评估 # 选择算法创建模型 from sklearn.ensemble import RandomForestRegressor #导入随机森林回归模型 model_rfr = RandomForestRegressor() model_rfr_standard = RandomForestRegressor() model_rfr_minmax = RandomForestRegressor() model_rfr_robust = RandomForestRegressor() model_rfr_normalize = RandomForestRegressor() # 训练模型 model_rfr.fit(X_train, y_train) model_rfr_standard.fit(X_train_standard, y_train) model_rfr_minmax.fit(X_train_minmax, y_train) model_rfr_robust.fit(X_train_robust, y_train) model_rfr_normalize.fit(X_train_normalizer, y_train)
作者回复: ✌️
2023-05-31归属地:江苏 - Geek_e0514aStandardScaler 这种变换会不会影响数据的特征
作者回复: 通常不会改变数据的特征,因为不会改变数据分别。对数据进行线性变换,使其具有零均值和单位方差。这种变换的目的是消除数据之间的量纲差异,使得不同特征具有相似的尺度。
2023-03-21归属地:重庆