当前位置: 首页 > news >正文

【解决(几乎)任何机器学习问题】:特征选择

当你创建了成千上万个特征后,就该从中挑选出⼏个了。但是,我们绝不应该创建成百上千个⽆⽤的特征。特征过多会带来⼀个众所周知的问题,即 "维度诅咒"。如果你有很多特征,你也必须有很多训练样本来捕捉所有特征。什么是 "⼤量 "并没有正确的定义,这需要您通过正确验证您的模型和检查训练模型所需的时间来确定。
选择特征的最简单⽅法是 删除⽅差⾮常⼩的特征 。如果特征的⽅差⾮常⼩(即⾮常接近于 0),它们就接近于常量,因此根本不会给任何模型增加任何价值。最好的办法就是去掉它们,从⽽降低复杂度。请注意,⽅差也取决于数据的缩放。 Scikit-learn 的 VarianceThreshold 实现了这⼀点。
from sklearn.feature_selection import VarianceThreshold
data = .
var_thresh = VarianceThreshold(threshold=0.1)
transformed_data = var_thresh.fit_transform(data)
我们还可以删除相关性较⾼的特征。要计算不同数字特征之间的相关性,可以使⽤⽪尔逊相关性。
import pandas as pd
from sklearn.datasets import fetch_california_housing
data = fetch_california_housing()
X = data["data"]
col_names = data["feature_names"]
y = data["target"]
df = pd.DataFrame(X, columns=col_names)
df.loc[:, "MedInc_Sqrt"] = df.MedInc.apply(np.sqrt)
df.corr()

得出相关矩阵,如图 1 所⽰。 

我们看到,MedInc_Sqrt 与 MedInc 的相关性⾮常⾼。因此,我们可以删除其中⼀个特征。
现在我们可以转向⼀些 单变量特征选择⽅法 。单变量特征选择只不过是针对给定⽬标对每个特征进⾏评分。 互信息 ⽅差分析 F 检验和 chi2 是⼀些最常⽤的单变量特征选择⽅法。在 scikit-learn 中,有两种⽅法可以使⽤这些⽅法。
SelectKBest:保留得分最⾼的 k 个特征
SelectPercentile:保留⽤⼾指定百分⽐内的顶级特征。
必须注意的是,只有⾮负数据才能使⽤ chi2。在⾃然语⾔处理中,当我们有⼀些单词或基于 tf-idf 的特征时,这是⼀种特别有⽤的特征选择技术。最好为单变量特征选择创建⼀个包装器,⼏乎可以⽤于任何新问题。

from sklearn.feature_selection import chi2
from sklearn.feature_selection import f_classif
from sklearn.feature_selection import f_regression
from sklearn.feature_selection import mutual_info_classif
from sklearn.feature_selection import mutual_info_regression
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import SelectPercentileclass UnivariateFeatureSelction:def __init__(self, n_features, problem_type, scoring):if problem_type == "classification":valid_scoring = {"f_classif": f_classif,"chi2": chi2,"mutual_info_classif": mutual_info_classif}else:valid_scoring = {"f_regression": f_regression,"mutual_info_regression": mutual_info_regression}if scoring not in valid_scoring:raise Exception("Invalid scoring function")if isinstance(n_features, int):self.selection = SelectKBest(valid_scoring[scoring],k=n_features)elif isinstance(n_features, float):self.selection = SelectPercentile(valid_scoring[scoring],percentile=int(n_features * 100))else:raise Exception("Invalid type of feature")def fit(self, X, y):return self.selection.fit(X, y)def transform(self, X):return self.selection.transform(X)def fit_transform(self, X, y):return self.selection.fit_transform(X, y)

使⽤该类⾮常简单。

# Example usage:
ufs = UnivariateFeatureSelction(n_features=0.1,problem_type="regression",scoring="f_regression"
)
ufs.fit(X, y)
X_transformed = ufs.transform(X)
这样就能满⾜⼤部分单变量特征选择的需求。请注意,创建较少⽽重要的特征通常⽐创建数以百计的特征要好。单变量特征选择不⼀定总是表现良好。⼤多数情况下,⼈们更喜欢使⽤机器学习模型进⾏特征选择。让我们来看看如何做到这⼀点。
使⽤模型进⾏特征选择的最简单形式被称为贪婪特征选择。在贪婪特征选择中,第⼀步是选择⼀个模型。第⼆步是选择损失/评分函数。第三步也是最后⼀步是反复评估每个特征,如果能提⾼损失/评分,就将其添加到 "好 "特征列表中。没有⽐这更简单的了。但你必须记住,这被称为贪婪特征选择是有原因的。这种特征选择过程在每次评估特征时都会适合给定的模型。这种⽅法的计算成本⾮常⾼。完成这种特征选择也需要⼤量时间。如果不正确使⽤这种特征选择,甚⾄会导致模型过度拟合。让我们来看看它是如何实现的。

import pandas as pd
from sklearn import linear_model
from sklearn import metrics
from sklearn.datasets import make_classificationclass GreedyFeatureSelection:def evaluate_score(self, X, y):model = linear_model.LogisticRegression()model.fit(X, y)predictions = model.predict_proba(X)[:, 1]auc = metrics.roc_auc_score(y, predictions)return aucdef _feature_selection(self, X, y):good_features = []best_scores = []num_features = X.shape[1]while True:this_feature = Nonebest_score = 0for feature in range(num_features):if feature in good_features:continueselected_features = good_features + [feature]xtrain = X[:, selected_features]score = self.evaluate_score(xtrain, y)if score > best_score:this_feature = featurebest_score = scoreif this_feature is None:breakgood_features.append(this_feature)best_scores.append(best_score)if len(best_scores) > 1:if best_scores[-1] < best_scores[-2]:breakreturn best_scores[:-1], good_features[:-1]def __call__(self, X, y):scores, features = self._feature_selection(X, y)return X[:, features], scoresif __name__ == "__main__":X, y = make_classification(n_samples=1000, n_features=100)X_transformed, scores = GreedyFeatureSelection()(X, y)
这种贪婪特征选择⽅法会返回分数和特征索引列表。图 2 显⽰了在每次迭代中增加⼀个新特征后,分数是如何提⾼的。我们可以看到,在某⼀点之后,我们就⽆法提⾼分数了,这就是我们停⽌的地⽅。
另⼀种贪婪的⽅法被称为递归特征消除法(RFE)。在前⼀种⽅法中,我们从⼀个特征开始,然后不断添加新的特征,但在 RFE 中,我们从所有特征开始,在每次迭代中不断去除⼀个对给定模型提供最⼩值的特征。但我们如何知道哪个特征的价值最⼩呢?如果我们使⽤线性⽀持(SVM)或逻辑回归等模型,我们会为每个特征得到⼀个系数,该系数决定了特征的重要性。⽽对于任何基于树的模型,我们得到的是特征重要性,⽽不是系数。在每次迭代中,我们都可以剔除最不重要的特征,直到达到所需的特征数量为⽌。因此,我们可以决定要保留多少特征。

当我们进⾏递归特征剔除时,在每次迭代中,我们都会剔除特征重要性较⾼的特征或系数接近 0 的特征。请记住,当你使⽤逻辑回归这样的模型进⾏⼆元分类时,如果特征对正分类很重要,其系数就会更正,⽽如果特征对负分类很重要,其系数就会更负。修改我们的贪婪特征选择类,创建⼀个新的递归特征消除类⾮常容易,但 scikit-learn 也提供了 RFE。下⾯的⽰例展⽰了⼀个简单的法。

import pandas as pd
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housingdata = fetch_california_housing()
X = data["data"]
col_names = data["feature_names"]
y = data["target"]model = LinearRegression()
rfe = RFE(estimator=model,n_features_to_select=3
)
rfe.fit(X, y)
X_transformed = rfe.transform(X)
我们看到了从模型中选择特征的两种不同的贪婪⽅法。但也可以根据数据拟合模型,然后通过特征系数或特征的重要性从模型中选择特征。如果使⽤系数,则可以选择⼀个阈值,如果系数⾼于该阈值,则可以保留该特征,否则将其剔除。
让我们看看如何从随机森林这样的模型中获取特征重要性。

import pandas as pd
from sklearn.datasets import load_diabetes
from sklearn.ensemble import RandomForestRegressor
data = load_diabetes()
X = data["data"]
col_names = data["feature_names"]
y = data["target"]
model = RandomForestRegressor()
model.fit(X, y)

随机森林(或任何模型)的特征重要性可按如下⽅式绘制。

importances = model.feature_importances_
idxs = np.argsort(importances)
plt.title('Feature Importances')
plt.barh(range(len(idxs)), importances[idxs], align='center')
plt.yticks(range(len(idxs)), [col_names[i] for i in idxs])
plt.xlabel('Random Forest Feature Importance')
plt.show()

 结果如图 3 所⽰。

从模型中选择最佳特征并不是什么新鲜事。您可以从⼀个模型中选择特征,然后使⽤另⼀个模型进⾏训练。例如,你可以使⽤逻辑回归系数来选择特征,然后使⽤随机森林(Random Forest)对所选特征进⾏模型训练。Scikit-learn 还提供了 SelectFromModel 类,可以帮助你直接从给定的模型中选择特征。您还可以根据需要指定系数或特征重要性的阈值,以及要选择的特征的最⼤数量。
请看下⾯的代码段,我们使⽤ SelectFromModel 中的默认参数来选择特征。
import pandas as pd
from sklearn.datasets import load_diabetes
from sklearn.ensemble import RandomForestRegressor
from sklearn.feature_selection import SelectFromModel
data = load_diabetes()
X = data["data"]
col_names = data["feature_names"]
y = data["target"]
model = RandomForestRegressor()
sfm = SelectFromModel(estimator=model)
X_transformed = sfm.fit_transform(X, y)
support = sfm.get_support()
print([x for x, y in zip(col_names, support) if y = True ])
上⾯程序打印结果: ['bmi','s5']。我们再看图 3,就会发现这是最重要的两个特征。因此,我们也可以直接从随机森林提供的特征重要性中进⾏选择。我们还缺少⼀件事,那就是使⽤ L1 Lasso )惩罚模型 进⾏特征选择。当我们使⽤ L1 惩罚进⾏正则化时,⼤部分系数都将为 0(或接近 0),因此我们要选择系数不为 0 的特征。只需将模型选择⽚段中的随机森林替换为⽀持 L1 惩罚的模型(如 lasso 回归)即可。所有基于树的模型都提供特征重要性,因此本章中展⽰的所有基于模型的⽚段都可⽤于 XGBoost、LightGBM 或 CatBoost。特征重要性函数的名称可能不同,产⽣结果的格式也可能不同,但⽤法是⼀样的。最后,在进⾏特征选择时必须⼩⼼谨慎。在训练数据上选择特征,并在验证数据上验证模型,以便在不过度拟合模型的情况下正确选择特征。

相关文章:

【解决(几乎)任何机器学习问题】:特征选择

当你创建了成千上万个特征后&#xff0c;就该从中挑选出⼏个了。但是&#xff0c;我们绝不应该创建成百上千个⽆⽤的特征。特征过多会带来⼀个众所周知的问题&#xff0c;即 "维度诅咒"。如果你有很多特征&#xff0c;你也必须有很多训练样本来捕捉所有特征。什么是 …...

24 双非计算机秋招总结

引言 我整理了一份 10w 字数的前端技术文档&#xff08;飞书&#xff09;&#xff0c;地址&#xff1a;https://qx8wba2yxsl.feishu.cn/docx/Vb5Zdq7CGoPAsZxMLztc53E1n0k?fromfrom_copylink&#xff0c;欢迎对前端感兴趣的同学查看、共建、分享。 PS&#xff1a;我是一名大四…...

用友NC65与用友NCC对接集成NC65-凭证列表查询打通凭证新增

用友NC65与用友NCC对接集成NC65-凭证列表查询打通凭证新增 数据源平台:用友NC65 用友NC是为集团与行业企业提供的全线管理软件产品&#xff0c;由亚太本土最大的企业管理软件提供商用友公司研发提供&#xff0c;用友NC率先采用J2EE架构和先进开放的集团级开发平台UAP&#xff0…...

【初中生讲机器学习】12. 似然函数和极大似然估计:原理、应用与代码实现

创建时间&#xff1a;2024-02-23 最后编辑时间&#xff1a;2024-02-24 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名初三学生&#xff0c;热爱计算机和数学&#xff0c;我们一起加…...

【达梦数据库】查看pesg回滚段信息的视图和SQL

一些达梦回滚段是使用情况的查询SQL&#xff0c;供排查“回滚记录版本太旧&#xff0c;无法获取用户记录” 等类似问题时使用 视图名说明主库备库v$pseg_items显示回滚系统中当前回滚项信息&#xff08;回滚线程的工作信息&#xff09;总行数WORKER_THREADS1查询 no rowsv$pseg…...

UML---活动图

活动图概述 活动图&#xff08;Activity Diagram&#xff09;是UML&#xff08;Unified Modeling Language&#xff0c;统一建模语言&#xff09;中的一种行为建模工具&#xff0c;主要用于描述系统或业务流程中的一系列活动或操作。活动图通常用于描述用例中的行为&#xff0c…...

编程笔记 Golang基础 018 常量与变量

编程笔记 Golang基础 018 常量与变量 一、常量常量的定义iota特性 二、变量变量定义变量作用域零值与初始化类型转换注意事项 三、重要性 常量&#xff0c;就是在程序编译阶段就确定下来的值&#xff0c;而程序在运行时则无法改变该值。变量是程序的基本组成单位&#xff0c;用…...

如何使用Douglas-042为威胁搜索和事件应急响应提速

关于Douglas-042 Douglas-042是一款功能强大的PowerShell脚本&#xff0c;该脚本可以提升数据分类的速度&#xff0c;并辅助广大研究人员迅速从取证数据中筛选和提取出关键数据。 该工具能够搜索和识别Windows生态系统中潜在的安全漏洞&#xff0c;Douglas-042会将注意力放在…...

华为配置WLAN AC和AP之间VPN穿越示例

配置WLAN AC和AP之间VPN穿越示例 组网图形 图1 配置WLAN AC和AP之间VPN穿越示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 企业用户接入WLAN网络&#xff0c;以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时&#xff0c;不影响…...

跨语言的序列化与反序列化

在Java中实现跨语言的序列化与反序列化通常可以采用以下几种方式 使用标准的跨语言序列化格式 可以选择使用一些标准的跨语言序列化格式,例如JSON、XML、Protocol Buffers(ProtoBuf)等。这些格式都是跨语言的,可以方便地在不同的编程语言之间进行数据交换。在Java中,可以…...

软考-中级-系统集成2023年综合知识(三)

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 软考中级专栏回顾 专栏…...

五、使用脚手架

五、使用脚手架 5.1 简单的实现 创建一个 School 组件 <template> <div><h2>学校名称&#xff1a;{{name}}</h2><h2>学校地址&#xff1a;{{address}}</h2> </div> </template><script> export default {name: "S…...

抛弃chatgpt,使用微软的Cursor提升coding效率

Whats Cursor? Cursor编辑器是一个基于GPT-4的代码编辑器&#xff0c;它可以根据用户的自然语言指令或者正在编辑的代码上下文为用户提供代码建议&#xff0c;支持多种编程语言&#xff0c;如Python、Java、C/C#、go等。Cursor编辑器还可以帮助用户重构、理解和优化代码&…...

uniapp插件uViewplus的使用(涉及TS下的问题)

在技术选型后最后定了使用有团队维护的uview-plus3.0,官方文档 配置参考&#xff1a;https://juejin.cn/post/7169875753100640270 ts配置参考&#xff1a;https://blog.csdn.net/m0_70027114/article/details/132957426 引入 在项目文件的pages.json中的"easycom"…...

google浏览器chrome无法访问localhost等本地虚拟域名的解决方法

场景一&#xff1a; 谷歌浏览器访问出现&#xff1a;forbbiden 403 问题&#xff0c;或者直接跳转到正式域名(非本地虚拟域名) 访问本地的虚拟域名http://www.hd.com/phpinfo.php?p1发生了302 条状 火狐浏览器正常访问; 解决方法&#xff1a; 方法1&#xff1a;在谷歌浏览器…...

(2.2w字)前端单元测试之Jest详解篇

Jest Jest 概述 Jest是一个领先的JavaScript测试框架&#xff0c;特别适用于React和Node.js环境。由Facebook开发&#xff0c;它以简单的配置、高效的性能和易用性而闻名。Jest支持多种类型的测试&#xff0c;包括单元测试、集成测试和快照测试&#xff0c;后者用于捕获组件或…...

【C++私房菜】面向对象中的多态

文章目录 一、多态二、对象的静态类型和动态类型三、虚函数和纯虚函数1、虚函数2、虚析构函数3、抽象基类和纯虚函数4、多态的原理 四、重载、覆盖(重写)、隐藏(重定义)的对比 一、多态 OOP的核心思想是多态性(polymorphism)。多态性这个词源自希腊语&#xff0c;其含义是“多…...

(done) 什么是特征值和特征向量?如何求特征值的特征向量 ?如何判断一个矩阵能否相似对角化?

什么是齐次方程&#xff1f; https://blog.csdn.net/shimly123456/article/details/136198159 行列式和是否有解的关系&#xff1f; https://blog.csdn.net/shimly123456/article/details/136198215 特征值和特征向量 参考视频&#xff1a;https://www.bilibili.com/video/BV…...

[rust] 11 所有权

文章目录 一 背景二 Stack 和 Heap2.1 Stack2.2 Heap2.3 性能区别2.4 所有权和堆栈 三 所有权原则3.1 变量作用域3.2 String 类型示例 四 变量绑定背后的数据交互4.1 所有权转移4.1.1 基本类型: 拷贝, 不转移所有权4.1.2 分配在 Heap 的类型: 转移所有权 4.2 Clone(深拷贝)4.3 …...

MySQL安装

文章目录 MYSQL安装一、下载二、解压三、配置1. 添加环境变量2. 初始化MySQL3. 注册MySQL服务4. 启动MySQL服务5. 修改默认账户密码 四、登录MySQL五、卸载MySQL MYSQL安装 一、下载 点开下面的链接&#xff1a;https://dev.mysql.com/downloads/mysql/ 点击Download 就可以下…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

ZYNQ学习记录FPGA(一)ZYNQ简介

一、知识准备 1.一些术语,缩写和概念&#xff1a; 1&#xff09;ZYNQ全称&#xff1a;ZYNQ7000 All Pgrammable SoC 2&#xff09;SoC:system on chips(片上系统)&#xff0c;对比集成电路的SoB&#xff08;system on board&#xff09; 3&#xff09;ARM&#xff1a;处理器…...