Pandas/Sklearn进行机器学习之特征筛选,有效提升模型性能
liuian 2024-12-20 17:19 66 浏览
作者:俊欣
来源:关于数据分析与可视化
今天小编来说说如何通过pandas以及sklearn这两个模块来对数据集进行特征筛选,毕竟有时候我们拿到手的数据集是非常庞大的,有着非常多的特征,减少这些特征的数量会带来许多的好处,例如
- 提高预测的精准度
- 降低过拟合的风险
- 加快模型的训练速度
- 增加模型的可解释性
事实上,很多时候也并非是特征数量越多训练出来的模型越好,当添加的特征多到一定程度的时候,模型的性能就会下降,从下图中我们可以看出,
因此我们需要找到哪些特征是最佳的使用特征,当然我们这里分连续型的变量以及离散型的变量来讨论,毕竟不同数据类型的变量处理的方式不同,我们先来看一下对于连续型的变量而言,特征选择到底是怎么来进行的。
计算一下各个变量之间的相关性
我们先导入所需要用到的模块以及导入数据集,并且用pandas模块来读取
from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm
%matplotlib inline
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import RFE
from sklearn.linear_model import RidgeCV, LassoCV, Ridge, Lasso
这次用到的数据集是机器学习中尤其是初学者经常碰到的,波士顿房价的数据集,其中我们要预测的这个对象是MEDV这一列
x = load_boston()
df = pd.DataFrame(x.data, columns = x.feature_names)
df["MEDV"] = x.target
X = df.drop("MEDV",1) #将模型当中要用到的特征变量保留下来
y = df["MEDV"] #最后要预测的对象
df.head()
output
CRIM ZN INDUS CHAS NOX ... TAX PTRATIO B LSTAT MEDV
0 0.00632 18.0 2.31 0.0 0.538 ... 296.0 15.3 396.90 4.98 24.0
1 0.02731 0.0 7.07 0.0 0.469 ... 242.0 17.8 396.90 9.14 21.6
2 0.02729 0.0 7.07 0.0 0.469 ... 242.0 17.8 392.83 4.03 34.7
3 0.03237 0.0 2.18 0.0 0.458 ... 222.0 18.7 394.63 2.94 33.4
4 0.06905 0.0 2.18 0.0 0.458 ... 222.0 18.7 396.90 5.33 36.2
我们可以来看一下特征变量的数据类型
df.dtypes
output
CRIM float64
ZN float64
INDUS float64
CHAS float64
NOX float64
RM float64
AGE float64
DIS float64
RAD float64
TAX float64
PTRATIO float64
B float64
LSTAT float64
MEDV float64
dtype: object
我们看到都是清一色的连续型的变量,我们来计算一下自变量和因变量之间的相关性,通过seaborn模块当中的热力图来展示,代码如下
plt.figure(figsize=(10,8))
cor = df.corr()
sns.heatmap(cor, annot=True, cmap=plt.cm.Reds)
plt.show()
相关系数的值一般是在-1到1这个区间内波动的
- 相关系数要是接近于0意味着变量之间的相关性并不强
- 接近于-1意味着变量之间呈负相关的关系
- 接近于1意味着变量之间呈正相关的关系
我们来看一下对于因变量而言,相关性比较高的自变量有哪些
# 筛选出于因变量之间的相关性
cor_target = abs(cor["MEDV"])
# 挑选于大于0.5的相关性系数
relevant_features = cor_target[cor_target>0.5]
relevant_features
output
RM 0.695360
PTRATIO 0.507787
LSTAT 0.737663
MEDV 1.000000
Name: MEDV, dtype: float64
筛选出3个相关性比较大的自变量来,然后我们来看一下自变量之间的相关性如何,要是自变量之间的相关性非常强的话,我们也只需要保留其中的一个就行,
print(df[["LSTAT","PTRATIO"]].corr())
print("=" * 50)
print(df[["RM","LSTAT"]].corr())
print("=" * 50)
print(df[["PTRATIO","RM"]].corr())
output
LSTAT PTRATIO
LSTAT 1.000000 0.374044
PTRATIO 0.374044 1.000000
==================================================
RM LSTAT
RM 1.000000 -0.613808
LSTAT -0.613808 1.000000
==================================================
PTRATIO RM
PTRATIO 1.000000 -0.355501
RM -0.355501 1.000000
从上面的结果中我们可以看到,RM变量和LSTAT这个变量是相关性是比较高的,我们只需要保留其中一个就可以了,我们选择保留LSTAT这个变量,因为它与因变量之间的相关性更加高一些
递归消除法
我们可以尝试这么一种策略,我们选择一个基准模型,起初将所有的特征变量传进去,我们再确认模型性能的同时通过对特征变量的重要性进行排序,去掉不重要的特征变量,然后不断地重复上面的过程直到达到所需数量的要选择的特征变量。
LR= LinearRegression()
# 挑选出7个相关的变量
rfe_model = RFE(model, 7)
# 交给模型去进行拟合
X_rfe = rfe_model.fit_transform(X,y)
LR.fit(X_rfe,y)
# 输出各个变量是否是相关的,并且对其进行排序
print(rfe_model.support_)
print(rfe_model.ranking_)
output
[False False False True True True False True True False True False
True]
[2 4 3 1 1 1 7 1 1 5 1 6 1]
第一行的输出包含True和False,其中True代表的是相关的变量对应下一行的输出中的1,而False包含的是不相关的变量,然后我们需要所需要多少个特征变量,才能够使得模型的性能达到最优
#将13个特征变量都依次遍历一遍
feature_num_list=np.arange(1,13)
# 定义一个准确率
high_score=0
# 最优需要多少个特征变量
num_of_features=0
score_list =[]
for n in range(len(feature_num_list)):
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size = 0.3, random_state = 0)
model = LinearRegression()
rfe_model = RFE(model,feature_num_list[n])
X_train_rfe_model = rfe_model.fit_transform(X_train,y_train)
X_test_rfe_model = rfe_model.transform(X_test)
model.fit(X_train_rfe_model,y_train)
score = model.score(X_test_rfe_model,y_test)
score_list.append(score)
if(score>high_score):
high_score = score
num_of_features = feature_num_list[n]
print("最优的变量是: %d个" %num_of_features)
print("%d个变量的准确率为: %f" % (num_of_features, high_score))
output
最优的变量是: 10个
10个变量的准确率为: 0.663581
从上面的结果可以看出10个变量对于整个模型来说是最优的,然后我们来看一下到底是哪10个特征变量
cols = list(X.columns)
model = LinearRegression()
# 初始化RFE模型,筛选出10个变量
rfe_model = RFE(model, 10)
X_rfe = rfe.fit_transform(X,y)
# 拟合训练模型
model.fit(X_rfe,y)
df = pd.Series(rfe.support_,index = cols)
selected_features = df[df==True].index
print(selected_features)
output
Index(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'DIS', 'RAD', 'PTRATIO',
'LSTAT'],
dtype='object')
正则化
例如对于Lasso的正则化而言,对于不相关的特征而言,该算法会让其相关系数变为0,因此不相关的特征变量很快就会被排除掉了,只剩下相关的特征变量
lasso = LassoCV()
lasso.fit(X, y)
coef = pd.Series(lasso.coef_, index = X.columns)
然后我们看一下哪些变量的相关系数是0
print("Lasso算法挑选了 " + str(sum(coef != 0)) + " 个变量,然后去除掉了" + str(sum(coef == 0)) + "个变量")
output
Lasso算法挑选了10个变量,然后去除掉了3个变量
我们来对计算出来的相关性系数排个序并且做一个可视化
imp_coef = coef.sort_values()
matplotlib.rcParams['figure.figsize'] = (8, 6)
imp_coef.plot(kind = "barh")
plt.title("Lasso Model Feature Importance")
output
可以看到当中有3个特征,‘NOX’、'CHAS'、'INDUS'的相关性为0
根据缺失值来进行判断
下面我们来看一下如何针对离散型的特征变量来做处理,首先我们可以根据缺失值的比重来进行判断,要是对于一个离散型的特征变量而言,绝大部分的值都是缺失的,那这个特征变量也就没有存在的必要了,我们可以针对这个思路在进行判断。
首先导入所需要用到的数据集
train = pd.read_csv("credit_example.csv")
train_labels = train['TARGET']
train = train.drop(columns = ['TARGET'])
我们可以先来计算一下数据集当中每个特征变量缺失值的比重
missing_series = train.isnull().sum() / train.shape[0]
df = pd.DataFrame(missing_series).rename(columns = {'index': '特征变量', 0: '缺失值比重'})
df.sort_values("缺失值比重", ascending = False).head()
output
缺失值比重
COMMONAREA_AVG 0.6953
COMMONAREA_MODE 0.6953
COMMONAREA_MEDI 0.6953
NONLIVINGAPARTMENTS_AVG 0.6945
NONLIVINGAPARTMENTS_MODE 0.6945
我们可以看到缺失值最高的比重将近有70%,我们也可以用可视化的根据来绘制一下缺失值比重的分布图
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.figure(figsize = (7, 5))
plt.hist(df['缺失值比重'], bins = np.linspace(0, 1, 11), edgecolor = 'k', color = 'blue', linewidth = 2)
plt.xticks(np.linspace(0, 1, 11));
plt.xlabel('缺失值的比重', size = 14);
plt.ylabel('特征变量的数量', size = 14);
plt.title("缺失值分布图", size = 14);
output
我们可以看到有一部分特征变量,它们缺失值的比重在50%以上,有一些还在60%以上,我们可以去除掉当中的部分特征变量
计算特征的重要性
在基于树的众多模型当中,会去计算每个特征变量的重要性,也就是feature_importances_属性,得出各个特征变量的重要性程度之后再进行特征的筛选
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier()
# 模型拟合数据
clf.fit(X,Y)
feat_importances = pd.Series(clf.feature_importances_, index=X.columns)
# 筛选出特征的重要性程度最大的10个特征
feat_importances.nlargest(10)
我们同时也可以对特征的重要性程度进行可视化,
feat_importances.nlargest(10).plot(kind='barh', figsize = (8, 6))
output
除了随机森林之外,基于树的算法模型还有很多,如LightGBM、XGBoost等等,大家也都可以通过对特征重要性的计算来进行特征的筛选
Select_K_Best算法
在Sklearn模块当中还提供了SelectKBest的API,针对回归问题或者是分类问题,我们挑选合适的模型评估指标,然后设定K值也就是既定的特征变量的数量,进行特征的筛选。
假定我们要处理的是分类问题的特征筛选,我们用到的是iris数据集
iris_data = load_iris()
x = iris_data.data
y = iris_data.target
print("数据集的行与列的数量: ", x.shape)
output
数据集的行与列的数量: (150, 4)
对于分类问题,我们采用的评估指标是卡方,假设我们要挑选出3个对于模型最佳性能而言的特征变量,因此我们将K设置成3
select = SelectKBest(score_func=chi2, k=3)
# 拟合数据
z = select.fit_transform(x,y)
filter_1 = select.get_support()
features = array(iris.feature_names)
print("所有的特征: ", features)
print("筛选出来最优的特征是: ", features[filter_1])
output
所有的特征: ['sepal length (cm)' 'sepal width (cm)' 'petal length (cm)'
'petal width (cm)']
筛选出来最优的特征是: ['sepal length (cm)' 'petal length (cm)' 'petal width (cm)']
那么对于回归的问题而言,我们可以选择上面波士顿房价的例子,同理我们想要筛选出对于模型最佳的性能而言的7个特征变量,同时对于回归问题的评估指标用的是f_regression
boston_data = load_boston()
x = boston_data.data
y = boston_data.target
然后我们将拟合数据,并且进行特征变量的筛选
select_regression = SelectKBest(score_func=f_regression, k=7)
z = select_regression.fit_transform(x, y)
filter_2 = select_regression.get_support()
features_regression = array(boston_data.feature_names)
print("所有的特征变量有:")
print(features_regression)
print("筛选出来的7个特征变量则是:")
print(features_regression[filter_2])
output
所有的特征变量有:
['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO'
'B' 'LSTAT']
筛选出来的7个特征变量则是:
['CRIM' 'INDUS' 'NOX' 'RM' 'TAX' 'PTRATIO' 'LSTAT']
相关推荐
- 华硕人工客服24小时吗(华硕售后人工客服)
-
华硕服务中心广东省惠州市惠东县城平深路(创富斜对面)惠东同心电脑城1L11(1.3km)笔记本电脑,平板电脑华硕服务中心广东省惠州市惠东县平山镇同心电脑城1F26(1.3km)笔记本电脑,平...
- 电脑音量小喇叭不见了(电脑声音喇叭图标不见了怎么办)
-
如果您电脑上的小喇叭(扬声器)不见了,可以尝试以下方法找回:1.检查设备管理器:在Windows下,右键点击“我的电脑”(或此电脑)->点击“属性”->点击“设备管理器”,查看“声音、视...
- 腾达路由器手机设置教程(腾达路由器手机设置教程视频)
-
用手机设置腾达路由器的方法如下:1在手机上打开浏览器,输入路由器背面的管理IP和用户及对应的密码2一般第一次打开,默认会跳出设置向导,准备好宽带用户名和密码,3按向导提示输入相应内容4在无线设置的安全...
- 自配电脑配置推荐(自配电脑配置推荐百度)
-
首先,像这类软件最低要求不高。最高没上限。纯粹看你的工程量大小。CPU有双核,内存有4G,就可以运行。但是实际体验肯定比较差,卡是肯德。渲染时间也会超长,一个小作品渲染几小时是正常的。稍微大点的工程也...
- 2025年平板性价比排行(2020年值得买的平板)
-
推荐台电P30S好。 基本配置:10.1英寸IPS广视角屏幕,1280*800分辨率,16:10的黄金显示比例,K9高压独立功放,支持3.5mm耳麦接口,联发科MT8183八核处理器,4GB...
- 2020显卡天梯图10月(2020显卡天梯图极速空间)
-
排行球队名称积分已赛胜平负进球失球净胜球 1?诺维奇城974629107753639 2?沃特福德91462710...
-
- 笔记本电脑无线网络连接(笔记本电脑无线网络连接不上怎么办)
-
一、笔记本电脑怎么连接wifi---win7系统笔记本连接wifi1、要先创建无线网络连接,将鼠标移到Win7的开始菜单,然后点击“控制面板”。2、然后点击“网络和Internet”。3、再打开“网络和共享中心”,这是Win7系统必有的功...
-
2025-12-22 05:55 liuian
- wind数据库(wind数据库官网)
-
先购买wind数据库,安装好wind取得使用权后,按照wind所给提示,输入账户和密码可使用wind数据库。Wind资讯金融终端是一个集实时行情、资料查询、数据浏览、研究分析、新闻资讯为一体的金融数据...
- 如何关闭360家庭防火墙(如果关闭360家庭防火墙)
-
关闭方法如下:1.打开手机360主界面之后,点击“安全防护中心”。2.点击第三列“入口防护”下方的“查看状态”按钮。3.在列出的功能项中找到“局域网防护”,直接点击后面的“关闭”按钮,关闭所有的“局域...
- 笔记本电脑型号配置怎么看(怎么查自己电脑的型号)
-
查电脑的配置和型号方法:方法一:1、右键单击“此电脑”,点击属性2、这里可以看到操作系统,CPU等大致信息3、点击设备管理器4、这里可以查看具体硬件的详细信方法二:1、首先打开电脑上的“控制面板”2、...
- pscs6序列号是什么
-
AdobePhotoshopCS6就二个版本(测试版和正式版)1、AdobePhotoshopCS6是AdobePhotoshop的第13代,是一个较为重大的版本更新。2、Photoshop在前几...
- win7桌面图片怎么设置(win7如何设置桌面图片)
-
1、首先用鼠标右键单击桌面的空白处。然后在弹出的菜单上选择“个性化”选项。这样就弹出了的个性化窗口上能显示看到“桌面背景”按钮。点击它即可。2、继续打开了选择“桌面背景”选项,然后在上面选择你想要设置...
- windows安卓下载(win安卓版)
-
2265安卓网是安全的,2265安卓网成立于2012年初,网站一直努力为各位安卓爱好者提供最新、最全的安卓游戏软件资源下载。经过几个月的努力、和广大安卓用户的支持、2265安卓网截至到2012年6月已...
- 一周热门
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)
