特征选择和特征工程

特征选择和特征工程

特征选择(也称为变量选择,属性选择或变量子集选择)是一种用于从初始数据集中选择特征子集(变量,大小)的方法,可以:

  • 缩短训练时间
  • 简化模型并使它们更易于解释
  • 通过减少过拟合来增强测试集表现

删除特征的一个重要原因是输入变量之间的高度相关性和冗余性,或者某些特征的不相关性。 因此,可以删除这些输入变量,而不会造成很多信息丢失。 冗余和无关是两个截然不同的概念,因为一个相关特征在存在与之高度相关的另一个相关特征的情况下可能是多余的。

在某些方面,特征工程与特征选择相反。使用特征选择,可以删除变量。在特征工程中,可以创建新变量来增强模型。 在许多情况下,将使用领域知识进行增强。

特征选择

出于多种原因,降低输入特征的数量很重要,包括:

  • 减少输入特征的多重共线性将使机器学习模型参数更易于解释。多重共线性(也共线性)是在数据集中的特征中观察到的现象,在该数据集中可以从另一个模型的特征中线性预测另一个预测器特征,并且准确率很高。
  • 减少运行模型所需的时间和模型所需的存储空间
  • 模型需要的输入特征越少,模型就越简单。当特征数量增加时,模型的可解释性下降。减少输入特征的数量还可以简化为较小大小(例如 2D 或 3D)时可视化数据的过程。
  • 随着维数的增加 ,可能的配置呈指数增加,而观测值覆盖的配置数则减少。 随着数据特征的增加,虽然可以更精确地描述数据,但是模型将更容易过拟合数据。这就是维度诅咒。

本项目采用Zestimate数据集 展开介绍。 Zillow数据集需要估计,如果今天将其投放市场,房屋将要出售的价格。数据的特征主要包括:

  • 平方英尺:直观上来说,房屋越大,价格就越高。
  • 卧室数量:更多房间,更多费用。
  • 浴室数量:卧室需要浴室。
  • 抵押贷款利率:如果利率较低,则抵押贷款支付将降低,这意味着潜在的房主可以负担得起更昂贵的房屋。
  • 建成年份:通常,较新的房屋比旧的房屋更贵。 老房子通常需要更多的维修。
  • 财产税:如果财产税高,那将增加每月的还款额,房主将只能负担更便宜的房屋。
  • 房屋颜色:乍看之下,这似乎并不是一个相关变量,但是如果房屋涂成石灰绿色怎么办?
  • 邮政编码:位置,位置,位置。 在房地产中,房屋所在地是价格的重要决定因素。 在某些情况下,一个街区的房屋可能比下一个街区的房屋多几十万美元。 位置可能很重要。
  • 可比较的销售额:评估师和房地产经纪人通常用来评估房屋价值的一种指标是寻找与最近出售或至少列出的"标的"房地产相似的房地产,以查看销售价格或当前的上市价格。
  • 税收评估:财产税是根据县目前认为财产的价值来计算的。 这是可公开访问的信息。

这些都可能是具有较高预测能力的变量,但直觉上可以假设平方英尺,卧室数量和浴室数量高度相关。 同样,从直觉上讲,平方英尺比卧室或浴室的数量更精确。 因此,可以减少卧室和浴室的数量,并保持平方英尺,而不会损失太多精度。

在不影响模型精度的情况下可以删除的特征分为两类:

  • 冗余:此特征与其他输入特征高度相关,因此不会在信号中添加太多新信息。
  • 不相关:此特征与目标函数的相关性较低,因此提供的噪声大于信号。

数据分析是获得直观了解和深入了解正在使用的数据集的好方法,数据分析通常采用三种方法:

  • 特征重要性
  • 单变量选择
  • 变量的相关性矩阵热图

特征重要性

特征重要性为数据集中的每个特征提供分数 。 较高的分数意味着该特征相对于输出特征具有更高的重要性或相关性。特征重要性通常是采用基于树的分类器进行评估。 在以下示例中,使用ExtraTreesClassifier确定数据集中的前五项特征:

python 复制代码
import pandas as pd 
from sklearn.ensemble import ExtraTreesClassifier
import numpy as np
import matplotlib.pyplot as plt 

data = pd.read_csv("train.csv")
X = data.iloc[:,0:20]  # independent columns
y = data.iloc[:,-1]    # pick last column for the target feature

model = ExtraTreesClassifier()
model.fit(X,y)
print(model.feature_importances_) # use inbuilt class
# feature_importances of tree based classifiers
# plot graph of feature importances for better visualization
feat_importances = pd.Series(model.feature_importances_, index=X.columns)
feat_importances.nlargest(5).plot(kind='barh')
plt.show() 

单变量选择

可以使用统计测试来确定哪些特征与输出变量具有最强的相关性 。 scikit-learn 库具有一个名为SelectKBest的类,该类提供一组统计测试以选择数据集中的K最佳特征。以下是一个示例,该示例对非负特征使用卡方(chi²)统计检验,以选择输入数据集中的五个最佳特征:

python 复制代码
import pandas as pd
import numpy as np
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

data = pd.read_csv("train.csv")
X = data.iloc[:,0:20]  #independent columns
y = data.iloc[:,-1]    #pick last column for the target feature 
#apply SelectKBest class to extract top 5 best features
bestfeatures = SelectKBest(score_func=chi2, k=5)
fit = bestfeatures.fit(X,y)
dfscores = pd.DataFrame(fit.scores_) 

dfcolumns = pd.DataFrame(X.columns)
scores = pd.concat([dfcolumns,dfscores],axis=1)
scores.columns = ['specs','score']  
print(scores.nlargest(5,'score'))  #print the 5 best features 

相关性热图

当特征的不同值之间存在关系时,两个特征之间存在相关性。 例如,如果房价随着平方英尺的增加而上涨,则这两个特征被认为是正相关的。 可能存在不同程度的相关性。 如果一个特征相对于另一个特征一致地改变,则这些特征被认为是高度相关的。相关可以是正的(特征的一个值的增加会增加目标变量的值)或负的(特征的一个值的增加会降低目标变量的值)。 相关值是 -1 和 1 之间的连续值。

  • 如果两个变量之间的相关性为 1,则存在完美的直接相关性。
  • 如果两个特征之间的相关性为 -1,则存在理想的逆相关性。
  • 如果两个特征之间的相关性为 0,则两个特征之间没有相关性。 热图可轻松识别与目标变量最相关的特征 。使用seaborn库并使用以下代码来绘制相关特征的热图:
python 复制代码
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt 

data = pd.read_csv("train.csv")
X = data.iloc[:,0:20]  #independent columns
y = data.iloc[:,-1]    # pick last column for the target feature
#get the correlations of each feature in the dataset
correlation_matrix = data.corr()
top_corr_features = correlation_matrix.index
plt.figure(figsize=(20,20))
#plot heat map
g=sns.heatmap(data[top_corr_features].corr(),annot=True,cmap="RdYlGn") 

基于过滤器的方法

指定度量,并基于该度量特征过滤。 基于过滤器的方法的包括:

  • 皮尔逊相关性:此算法用作量化两个连续变量X和Y之间的线性相关性的度量。 它的值可以介于 -1 到 +1 之间。
  • 线性判别分析(LDA):LDA 可用于查找特征的线性组合,这些特征描述或分隔了分类变量的两个或更多个级别(或类)。
  • 方差分析(ANOVA):ANOVA 类似于 LDA,不同之处在于它是使用一个或多个分类自变量和一个连续因变量计算的。 它提供了统计检验,以了解几组的平均值是否相等。
  • 卡方:卡方是一种统计测试,应用于类别变量组,以使用它们的频率分布确定它们之间相关或关联的可能性。 基于过滤器的方法不会消除多重共线性。 因此,在根据输入数据创建模型之前,必须执行其他处理以处理特征多重共线性。

特征工程

特征工程过程可以描述如下:

  1. 讨论哪些特征相关
  2. 确定哪些特征可以改善模型表现
  3. 创建新特征
  4. 确定新特征是否会增加模型表现; 如果没有,丢弃它们
  5. 返回"步骤 1",直到模型的表现达到预期

数据清洗

数值插补:插补是处理缺失值的另一种方法,即将缺失的值替换为另一个"有意义的"值。 对于数字变量,常替换为:

  • 将0用作替换值
  • 计算整个数据集的平均值,然后用平均值替换缺失值
  • 计算整个数据集的中值,然后用中值替换缺失值 通常最好使用中值而不是平均值,因为平均值更容易受到异常值的影响。
python 复制代码
#Filling all missing values with 0
data = data.fillna(0) 

#Filling missing values with medians of the columns
data = data.fillna(data.median())
print(data) 

分类插补:分类变量不包含数字,而是包含类别。 例如,红色,绿色和黄色。 因此,平均值和均值不能与分类变量一起使用。常用的技术是用出现最多的值替换所有缺失值。 在存在许多类别或类别均匀分布的情况下,可以使用诸如"其他"之类的名称。

python 复制代码
#Max fill function for categorical columns
import pandas as pd 

data = pd.read_csv("dataset.csv") 
data['color'].fillna(data['color'].value_counts().idxmax(), inplace=True)
print(data) 

离群值管理

简单地删除异常值是处理异常值影响的简单而有效的方法。

  • 删除落在数据集中某个特征值的标准差的某个倍数的离群值
  • 使用百分位。使用这种方法,仅假设特征值的一定百分比是离群值。下降多少百分比值仍然是主观的,并且将取决于领域。
  • 设置值上限。封顶值允许保留数据点,并有可能提高模型的表现。 但是,保留数据点但限制值的上限会使该数据点成为估计值而不是实际观察值,这也可能会影响结果。决定使用哪种方法将取决于对特定数据集的分析。
python 复制代码
#Dropping the outlier rows with standard deviation
import pandas as pd 

data = pd.read_csv("train.csv") 
#Dropping the outlier rows with standard deviation
factor = 2
upper_lim = data['battery_power'].mean () + data['battery_power'].std () * factor
lower_lim = data['battery_power'].mean () - data['battery_power'].std () * factor 
data = data[(data['battery_power'] < upper_lim) & (data['battery_power'] > lower_lim)]
print(data) 

#Dropping the outlier rows with Percentiles
upper_lim = data['battery_power'].quantile(.99)
lower_lim = data['battery_power'].quantile(.01) 
data = data[(data['battery_power'] < upper_lim) & (data['battery_power'] > lower_lim)]
print(data) 

#Capping the outlier rows with percentiles
upper_lim = data['battery_power'].quantile(.99)
lower_lim = data['battery_power'].quantile(.01) 
data.loc[(data['battery_power'] > upper_lim), 'battery_power'] = upper_lim
data.loc[(data['battery_power'] < lower_lim), 'battery_power'] = lower_lim
print(data) 

one-hot编码

one-hot编码是机器学习中用于特征工程的一种常用技术。一些机器学习算法无法处理分类特征,因此one-hot编码是一种将这些分类特征转换为数值特征的方法。假设有一个标记为"状态"的特征,该特征可以采用三个值(红色,绿色或黄色)之一。由于这些值是分类的,因此不存在哪个值是较高或较低的概念。可以将这些值转换为数值,从而赋予它们这种特性。

python 复制代码
import pandas as pd 

data = pd.read_csv("dataset.csv") 
encoded_columns = pd.get_dummies(data['color'])
data = data.join(encoded_columns).drop('color', axis=1)
print(data) 

对数转换

对数转换是常见的特征工程转换。对数转换有助于展开高度偏斜的值。应用对数转换后,数据分布将被标准化。使用此技术时要考虑的一个关键限制是,仅当所有数据点均为正值时才应应用对数转换。另外,可以在应用转换之前将 1 加到数据中。

python 复制代码
#Log Transform Example
data = pd.DataFrame({'value':[3,67, -17, 44, 37, 3, 31, -38]})
data['log+1'] = (data['value']+1).transform(np.log) 

#Negative Values Handling
#Note that the values are different
data['log'] = (data['value']-data['value'].min()+1) .transform(np.log)
print(data) 

缩放

在许多情况下,数据集中的数字特征在规模上会与其他特征有很大差异。应用缩放后,连续特征在范围上变得可比。 并非所有算法都需要标定值,但是如果未事先对数据集进行标定,则其他算法将产生无意义的结果(例如 K 近邻或 K 均值)。

  • 归一化(或 min-max 归一化)将的所有值缩放到介于 0 到 1 之间的固定范围内。规范化不会更改特征的分布,并且由于减少的标准差,离群值的影响会增加。 因此,建议在规范化之前处理离群值。
  • 标准化(或 z 分数标准化)是一种缩放方法,其中包括标准差作为其计算的一部分。 标准化最小化并平滑了缩放中异常值的影响。
python 复制代码
data = pd.DataFrame({'value':[7,25, -47, 73, 8, 22, 53, -25]}) 
data['normalized'] = (data['value'] - data['value'].min()) / (data['value'].max() - data['value'].min())
print(data) 

data = pd.DataFrame({'value':[7,25, -47, 73, 8, 22, 53, -25]}) 
data['standardized'] = (data['value'] - data['value'].mean()) / data['value'].std()
print(data) 

日期操作

对于某些数据科学问题,时间特征可能至关重要。在时间序列分析中,日期显然至关重要。如果没有在预测中附加日期,则预测 S&P 500 将达到 3000 将毫无意义。

没有进行任何处理的日期可能对大多数模型没有多大意义,并且这些值将太独特而无法提供任何预测能力。如果使用某些领域知识,则可能能够极大地增加特征的信息价值。 例如,将日期转换为分类变量可能会有所帮助。

如果目标函数是确定何时支付租金,则将日期转换为二进制值,其中可能的值为: 该月的前 5 天= 1 当月的前 5 天之后= 0

如果要求预测餐厅的人流和销售情况,那么看每个月的 21 日可能没有任何流量,但是可以想象,如果日期是星期日,或者是10月1日。如果这是一家国际连锁餐厅,那么餐厅位置和月份可能就非常重要(美国的圣诞节与印度的排灯节)。

可以操纵日期的其他可能方式包括:

  • 将日期分为不同的部分:年,月,日等
  • 以年,月,日等方式计算当前日期与所讨论的值之间的时间段
  • 从日期中提取特定的特征:
  • 星期几(星期一,星期二,依此类推)
  • 周末与否
  • 是否休假
相关推荐
LNTON羚通3 小时前
摄像机视频分析软件下载LiteAIServer视频智能分析平台玩手机打电话检测算法技术的实现
算法·目标检测·音视频·监控·视频监控
湫ccc3 小时前
《Python基础》之字符串格式化输出
开发语言·python
mqiqe4 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin4 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python
哭泣的眼泪4084 小时前
解析粗糙度仪在工业制造及材料科学和建筑工程领域的重要性
python·算法·django·virtualenv·pygame
湫ccc5 小时前
《Python基础》之基本数据类型
开发语言·python
Microsoft Word5 小时前
c++基础语法
开发语言·c++·算法
天才在此5 小时前
汽车加油行驶问题-动态规划算法(已在洛谷AC)
算法·动态规划
drebander6 小时前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
莫叫石榴姐6 小时前
数据科学与SQL:组距分组分析 | 区间分布问题
大数据·人工智能·sql·深度学习·算法·机器学习·数据挖掘