文章目录
前言
在数据科学的世界里,有一句话广为流传:“数据决定模型的上限,而特征工程决定你离这个上限有多近。”这句话道出了特征工程在机器学习和数据分析中的重要性。那么,什么是特征工程?为什么它如此关键?本文将带你一探究竟。
什么是特征工程
特征工程是指从原始数据中提取、选择和转换特征的过程,目的是为了提高机器学习模型的性能。特征可以是数据的任何属性或变量,例如数值型特征(如年龄、收入)、分类型特征(如性别、颜色)、文本特征(如新闻文章的内容)、图像特征(如图片的颜色、纹理)等。
为什么要进行特征工程
一、提升模型性能:
- 增强模型准确性:原始数据有噪声和无关信息,特征工程能提取关键特征,让模型更好地捕捉规律和模式,提高预测准确性。比如在图像识别中可提取边缘、纹理等特征帮助识别物体。
- 减少过拟合:复杂模型易对训练数据过拟合。特征工程可通过选合适特征、降维等减少模型复杂度,降低过拟合风险。如在文本分类中去除停用词、提取词干来减少特征数量。
- 加快模型训练速度:数据规模增大使训练时间变长,特征工程可通过选重要特征、降维等减少输入维度,加快训练速度。例如用主成分分析将高维数据压缩到低维空间。
二、改善数据质量:
- 处理缺失值:现实数据常存在缺失值影响模型效果。特征工程可填充缺失值或删除含缺失值样本。如用均值、中位数、众数填充数值型特征缺失值,用最频繁类别填充分类型特征缺失值。
- 处理异常值:异常值会不良影响模型,特征工程可识别并处理异常值提高数据质量。如用箱线图识别后进行删除、替换或修正。
- 标准化和归一化:不同特征取值范围和单位不同影响模型,可通过标准化和归一化将数据转换到同一尺度,使特征具有可比性。如用 Z-score 标准化或 Min-Max 归一化方法。
特征工程包含内容
1.特征抽取/特征提取
在机器学习中,算法可类比为统计方法,而统计方法往往由一个又一个数学公式构成。然而,数学公式通常无法直接处理字符串。因此,需要将文本类型的字符串转换为数值类型。关键问题在于如何进行这种转换以及转换成何种形式才能被算法有效地处理。此即为特征提取,特征提取一般分为两种。
1.1 字典特征提取
- 作用:对字典数据进行特征化处理
- sklearn.feature_extraction.DictVectorizer(sparse=True,…)
- DictVectorizer.fit_transform(X)X:字典或者包含字典的迭代器返回值:返回sparse矩阵
- DictVectorizer.inverse_transform(X)X:array数组或者sparse矩阵 返回值:0转换之前数据格式
- DictVectorizer.get_feature_names() 返回类别名称
案例:
from sklearn.feature_extraction import DictVectorizer
"""字典特征提取"""
def dict_demo():
data = [{'city':'北京','temperature':100},
{'city':'上海','temperature':60},
{'city':'深圳','temperature':30}]
#实例化一个转换器类
transfer = DictVectorizer(sparse=False)
#调用fit_transform()
#fit() 计算每一列的平均值、标准差
#transform() 进行最终的转换
data_new = transfer.fit_transform(data)
#输出结果
print("data_new:\n",data_new)
print("特征名字:\n",transfer.get_feature_names_out())
return None
if __name__ == '__main__':
dict_demo()
运行结果:
应用场景:
- 数据集中类型比较多时
- 将数据集中的特征转换成字典类型
- 使用 DictVectorizer 转换
- 本身拿到的数据就是字典类型
1.2 文本特征提取
- 作用:对文本数据进行特征值化
- sklearn.feature_extraction.text.CountVectorizer(stopIwords=[]),返回词频矩阵
- CountVectorizer.fit_transform(X)X:文本或者包含文本字符串的可迭代对象 ,返回sparse矩阵
- CountVectorizer.inverse_transform(X)X:array数组或者sparse矩阵 返回值:转换之前数据格
- CountVectorizer.get_feature_names() 返回值:单词列表
案例:
from sklearn.feature_extraction.text import CountVectorizer
"""文本特征抽取"""
def test_demo():
text_data = [
"This is the first document.",
"This document is the second document.",
"And this is the third one.",
"Is this the first document?"
]
# 创建实例化对象
transfer = CountVectorizer()
# 对文本数据进行特征提取
data = transfer.fit_transform(text_data)
print("查看特征名字:\n",transfer.get_feature_names_out())
# 以稀疏矩阵形式查看提取的特征
print(data.toarray())
return None
if __name__ == '__main__':
test_demo()
应用场景:
- 情感分析
- 文本分类
2.特征预处理
当我们面对原始数据时,它往往是粗糙且不规整的。可能存在缺失值、异常值,不同特征的取值范围和单位也千差万别。如果直接将这样的数据输入到机器学习模型中,就如同让一位顶尖运动员穿着不合脚的鞋子去参加比赛,很难发挥出最佳水平。特征预处理的目的就是要把这些原始数据整理得井井有条,使其更适合模型的 “口味”,从而提高模型的性能和效果,特征预处理主要方法有
2.1 数据归一化
在进行特征转换的过程中,一旦出现特征的单位或者大小存在显著差异的情况,又或者某一特征的方差与其他特征相比,大出了好几个数量级,那么这种状况将会对数据分析的结果产生影响。总的来说归一化是将原始数据缩放到[0,1]区间
- 公式为:
x ′ = x − min ( x ) max ( x ) − min ( x ) x' = \frac{x - \min(x)}{\max(x) - \min(x)} x′=max(x)−min(x)x−min(x)
其中 x x x 是原始数据点, min ( x ) \min(x) min(x) 和 max ( x ) \max(x) max(x) 分别是数据的最小值和最大值。
案例:
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
def minmax_demo():
# 1.获取数据
data = pd.read_csv("dating.txt")
#选择每一行数据,只取前3列
data = data.iloc[:, :3]
#查看结果
#print("data:\n",data)
# 2.实例化一个转换器类(创建归一化类)
transfer = MinMaxScaler() #默认区间0到1
#也可以设置区间【2,3】
#transfer = MinMaxScaler(feature_range=(2,3))
# 3.调用fit_transform
data_new = transfer.fit_transform(data)
#打印输出
print("data_new:\n",data_new)
return None
if __name__ == '__main__':
minmax_demo()
运行结果:
- 数据归一化通常使用最大值和最小值来进行计算,但这种方法容易受到异常值的影响,稳定性较差,只适合传统精确的小数据场景。那么,当在对数据进行归一化时出现异常值该如何解决呢?
2.2 数据标准化
数据标准化可以更好解决归一化的缺点,如常见的 Z-score 标准化,是通过计算数据的均值和标准差,将数据转换为均值为 0、标准差为 1 的分布。这样做的好处在于,它是基于数据的整体分布情况进行转换,而不是仅仅依赖于最大值和最小值。异常值对均值和标准差的影响相对较小,所以标准化后的结果相对更稳健。总的来说 标准化 是将数据转换为平均值为0,标准差为1的分布,公式为:
z
=
x
−
μ
σ
z = \frac{x - \mu}{\sigma}
z=σx−μ
其中
x
x
x 是原始数据点,
μ
\mu
μ 是数据的平均值,
σ
\sigma
σ 是数据的标准差。
注:标准差越大,数据越离散,反之,标准差越小,数据越集中
案例:
from sklearn.preprocessing import StandardScaler
import pandas as pd
def stand_demo():
# 1.获取数据
data = pd.read_csv("dating.txt")
#选择每一行数据,只取前3列
data = data.iloc[:, :3]
#查看结果
#print("data:\n",data)
# 2、实例化一个转换器类
transfer = StandardScaler()
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
# 4、输出
print("data_new:\n", data_new)
return None
if __name__ == '__main__':
stand_demo()
运行结果:
3.特征降维/数据降维
降维就是降低维度,在数据中,若两个变量高度相关即提供相似信息,可通过降维去掉其中一个,留下相互独立且能提供不同信息的主要变量,从而使数据分析更简洁高效,也有助于更好地理解数据本质特征。
正是因为在进行训练的时候,我们都是使用特征进行学习。如果特征本身存在问题或者特征之间相关性较强,对于算法学习预测会影响较大,降维的两种方式:
特征选择
数据中包含冗余或相关变量(或特征、属性、指标等),旨在从原有特征中找出主要特征
- Filter过滤
- 方差过滤法:过滤低方差特征
- 删除低方差的一些特征,前面讲过方差的意义。方差越小特征样本越接近,方差越大特征样本差别越大
- 方差过滤法:过滤低方差特征
案例:
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
def variance_demo():
#1. 读取数据
data = pd.read_csv("factor_returns.csv",encoding="utf8")
#取所有行,只取第一列和倒数第二列
data = data.iloc[:,1:-2]
print("data数据:\n",data)
#2. 实例化一个转换器
transfer = VarianceThreshold()
#3. 调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n",data_new)
return None
if __name__ == '__main__':
variance_demo()
运行结果:
- 相关系数:特征与特征之间的相关程度
两两特征之间相关计算
import pandas as pd
from scipy.stats import pearsonr
def pearsonr_demo():
#1. 读取数据
data = pd.read_csv("factor_returns.csv")
# print("data数据:", data.columns)
factor = ['pe_ratio', 'pb_ratio', 'market_cap','return_on_asset_net_profit',
'earnings_per_share', 'revenue', 'total_expense']
for i in range(len(factor)):
for j in range(i, len(factor) - 1):
corr, _ = pearsonr(data[factor[i]], data[factor[j + 1]])
print("指标%s与指标%s之间的相关性大小为%f" % (factor[i], factor[j + 1], corr))
return None
if __name__ == '__main__':
pearsonr_demo()
运行结果:
- Embeded嵌入式
- 决策树:信息熵、信息增益
- 正则化:L1、L2
- 深度学习 :卷积神经网络等
主成分分析(可以理解一种特征提取的方式)
主成分分析是将高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量,其主要作用是对数据进行维数压缩,尽可能降低原数据的维数(复杂度),但只损失少量信息。
案例:
from sklearn.decomposition import PCA
def pca_demo():
#1.获取数据
data = [[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]]
#2. 实例化转换类
#将数据降维到 2 维
transfer = PCA(n_components=2)
#3.调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new\n",data_new)
return None
if __name__ == '__main__':
pca_demo()
结果:
总结
特征工程是从原始数据中提取有用特征的过程,旨在提高模型性能和泛化能力。它包括特征抽取、预处理和降维等步骤,如从文本中提取信息(文本特征提取),对数据进行归一化或标准化处理,以及通过主成分分析等方法降低数据维度。这些过程有助于更好地理解数据,提升机器学习模型的效果。