四.特征工程
1.概念
一般使用pandas来进行数据清洗和数据处理、使用sklearn来进行特征工程
将任意数据(文本或图像等)转换为数字特征,对特征进行相关的处理
步骤:1.特征提取;2.无量纲化(预处理):归一化、标准化;3.降维:底方差过滤特征选择,主成分分析-PCA降维
2.特征工程API
①.实例化转换器对象
DictVectorizer 字典特征提取 CountVectorizer 文本特征提取 TfidfVectorizer TF-IDF文本特征词的重要程度特征提取 MinMaxScaler 归一化 StandardScaler 标准化 VarianceThreshold 底方差过滤降维 PCA 主成分分析降维
②.fit,transform和fit_transform
fit:用于计算数据的统计信息,比如均值和标准差(在StandardScaler
的情况下),这些统计信息随后会被用于预测出来的数据
transform:使用已经通过fit
方法计算出的统计信息来转换数据。
fit_transform:两者结合,更高效
一旦scaler
对象在X_train
上被fit
,它就已经知道了如何将数据标准化。
先fit_transform(x_train)然后再transform(x_text)
fit只用一次
# fit 和 transform 和fittransform 区别
from sklearn.preprocessing import StandardScaler,MinMaxScaler
import numpy as np
transfer=StandardScaler()
x=np.random.randint(100,size=(3,4))
print(x)
transfer.fit(x)#计算出均值和标准差
x=transfer.transform(x)
# x=transfer.fit_transform(x)
print(x)
x2=np.array([[10,20,30,40]])
x2=transfer.transform(x2)
print(x2)
3.DictVectorizer 字典列表特征提取
1.稀疏矩阵
一个矩阵中大部分元素为0,常见于大规模数据分析、图形学、自然语言处理、机器学习等领域
常用存储方式:①.三元组表 (Coordinate List, COO):三元组表就是一种稀疏矩阵类型数据,存储非零元素的行索引、列索引和值:
(行,列) 数据
(0,0) 10
(0,1) 20
(2,0) 90
(2,20) 8
(8,0) 70
表示除了列出的有值, 其余全是0
②.压缩稀疏行 (CSR - Compressed Sparse Row):
-
CSR 格式将稀疏矩阵中的非零元素按行优先的方式存储。它使用了三个数组:
-
data
:存储非零元素的值。 -
indices
:存储data
中每个元素的列索引。 -
indptr
:存储每一行在data
和indices
数组中的起始位置。
-
-
CSR 格式非常适合快速地进行行访问和矩阵向量乘法。
③.压缩稀疏列 (CSC - Compressed Sparse Column):
-
CSC 格式类似于 CSR,但它是按列优先的方式来存储稀疏矩阵。同样也使用了三个数组:
-
data
:存储非零元素的值。 -
indices
:存储data
中每个元素的行索引。 -
indptr
:存储每一列在data
和indices
数组中的起始位置。
-
-
CSC 格式对于快速地进行列访问和某些类型的矩阵运算很有帮助。
④.字典 (Dictionary of Keys - DOK):
DOK 格式使用一个字典来存储非零元素,其中键是元素的位置(通常是元组 (row, column)),值是非零元素本身。
-
这种格式适合于动态地增加或修改矩阵中的非零元素。
⑤.链表 (List of Lists - LIL):
-
LIL 格式使用两个列表来表示稀疏矩阵。其中一个列表包含每一行的非零元素,另一个列表包含了这些非零元素的列索引。
-
LIL 格式适合于构建稀疏矩阵,特别是当矩阵的结构在构建过程中发生变化时。
⑥.块稀疏行 (BSR - Block Sparse Row):
-
BSR 格式类似于 CSR,但它不是处理单个非零元素,而是处理固定大小的非零元素块。
-
这种格式适用于那些非零元素倾向于形成小的密集子矩阵的情况。
2.非稀疏矩阵(稠密矩阵)
矩阵中的大部分元素都是非0的,矩阵的存储通常采用标准的二维数组形式。在数学计算、线性代数等通用计算领域更为常见。
3.API
创建转换器对象:
sklearn.feature_extraction.DictVectorizer(sparse=True)
DictVectorizer:字典向量化工具
参数:
sparse=True返回类型为csr_matrix的稀疏矩阵
sparse=False表示返回的是数组,数组可以调用.toarray()方法将稀疏矩阵转换为数组
转换器对象:
转换器对象调用fit_transform(data)函数,参数data为一维字典数组或一维字典列表,返回转化后的矩阵或数组
转换器对象get_feature_names_out()方法获取特征名
eg1.提取为稀疏矩阵对应的数组
# 字典列表特征提取
from sklearn.feature_extraction import DictVectorizer
import pandas as pd
data=[{'city':'北京','money':38,"age":20},
{'city':'上海','money':60,"age":29},
{'city':'深圳','money':30,"age":32},
{'city':'深圳','money':40,"age":49}]
# 初始化工具(字典变成向量的工具器)
model=DictVectorizer(sparse=False)#sparse是否转换成三元组形式
data=model.fit_transform(data)
# print(data,type(data))
# print(model.get_feature_names_out())#获取所有的特征名称
ddata=pd.DataFrame(data=data,columns=model.get_feature_names_out())
# print(ddata)
ddata
eg2.提取为稀疏矩阵
# 字典列表特征提取
from sklearn.feature_extraction import DictVectorizer
import pandas as pd
data=[{'city':'北京','money':38,"age":20},
{'city':'上海','money':60,"age":29},
{'city':'深圳','money':30,"age":32},
{'city':'深圳','money':40,"age":49}]
# 初始化工具(字典变成向量的工具器)
model=DictVectorizer(sparse=True)#sparse是否转换成三元组形式
data=model.fit_transform(data)
print(data,type(data))
arr=data.toarray()#把三元组(稀疏矩阵)转化为数组
print(arr)
4.CountVectorizer 文本特征提取
1.API
sklearn.feature_extraction.text.CountVectorizer
构造函数关键字参数stop_words,值为list,表示词的黑名单(不提取的词)
fit_transform函数的返回值为稀疏矩阵
eg3.英文文本提取
# CountVectorizer 文本特征提取
from sklearn.feature_extraction.text import CountVectorizer
corpus = ['I love machine learning. Its awesome.', 'Its a book amazon book', 'Amazon is book a great company']
# 创建一个词频提取对象
vectorizer = CountVectorizer(stop_words=[])
# 提取词频
x=vectorizer.fit_transform(corpus)
print(x)
print(x.toarray())
print(vectorizer.get_feature_names_out())
eg4.中文文本提取
! pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jieba
# CountVectorizer 中文本特征提取
from sklearn.feature_extraction.text import CountVectorizer
import jieba
import pandas as pd
# arr=list(jieba.cut("我爱北京天安门"))
# print(arr)
# str1=" ".join(arr)
# print(str1)
#传入的文本(没有断词的字符串) 用jieba分词工具转化为数据容器,然后再把数据容器中元素用空格连接成字符串
def my_cut(text):
return " ".join(jieba.cut(text))
corpus = ["教育学会会长期间,坚定支持民办教育事业!", "扶持民办,学校发展事业","事业做出重大贡献!"]
# # 创建一个词频提取对象
vectorizer = CountVectorizer(stop_words=[])
# 提取词频
data=[my_cut(el) for el in corpus]
print(data)
x=vectorizer.fit_transform(data)
print(x)
print(x.toarray())
print(vectorizer.get_feature_names_out())
ddata=pd.DataFrame(x.toarray(),columns=vectorizer.get_feature_names_out())
ddata
5.TfidfVectorizer TF-IDF文本特征词的重要程度特征提取
1.算法
词频(Term Frequency, TF), 表示一个词在当前篇文章中的重要性,是对词数的归一化
TF=某个词在文章中的出现次数/文章的总词数
逆文档频率(Inverse Document Frequency, IDF), 反映了词在整个文档集合中的稀有程度
IDF=lg((语料库的文档总数+1)/(包含该词的文档数+1))
TF-IDF=词频(TF)×逆文档频率(IDF)
2.API
sklearn.feature_extraction.text.TfidfVectorizer()
构造函数关键字参数stop_words,表示词特征黑名单
fit_transform函数的返回值为稀疏矩阵
eg5
from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer
import jieba
import pandas as pd
def my_cut(text):
return " ".join(jieba.cut(text))
data=["教育学会会长期间,坚定支持民办教育事业!", "扶持民办,学校发展事业","事业做出重大贡献!"]
data=[my_cut(i) for i in data]
print(data)
transfer=TfidfVectorizer(stop_words=[])
res=transfer.fit_transform(data)
print(transfer.get_feature_names_out())
print(res.toarray())
ddata=pd.DataFrame(res.toarray(),columns=transfer.get_feature_names_out())
ddata
6.无量纲化-预处理
1.MinMaxScaler 归一化
2.归一化API
sklearn.preprocessing.MinMaxScaler(feature_range)
参数:feature_range=(0,1) 归一化后的值域,可以自己设定
fit_transform函数归一化的原始数据类型可以是list、DataFrame和ndarray, 不可以是稀疏矩阵
fit_transform函数的返回值为ndarray
eg6.归一化
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
scaler=MinMaxScaler(feature_range=(0,1))
data=pd.read_excel("./src/test2.xlsx")
print(data.values)
# arr=scaler.fit_transform(data.values)
arr=scaler.fit_transform(data)
print(arr)
鲁棒性较差
# 字典列表特征提取后的结果归一化
from sklearn.feature_extraction import DictVectorizer
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
data=[{'city':'北京','money':38,"age":20},
{'city':'上海','money':60,"age":29},
{'city':'深圳','money':30,"age":32},
{'city':'深圳','money':40,"age":49}]
# 初始化工具(字典变成向量的工具器)
model=DictVectorizer(sparse=True)#sparse是否转换成三元组形式
data=model.fit_transform(data)
# print(data,type(data))
arr=data.toarray()#把三元组(稀疏矩阵)转化为数组
print(arr)
arr_1=MinMaxScaler().fit_transform(arr)
arr_1
3.StandardScaler 标准化
4.标准化API
sklearn.preprocessing.StandardScale
与MinMaxScaler一样,原始数据类型可以是list、DataFrame和ndarray
fit_transform函数的返回值为ndarray, 归一化后得到的数据类型都是ndarray
eg7.标准化
from sklearn.preprocessing import StandardScaler
import numpy as np
# 初始化标准化工具
scaler = StandardScaler()
np.random.seed(7)
data=np.array([[1,2,3,4],
[2,2,3,4],
[3,2,3,4],
[4,2,3,4]])
#np.random.randint(0,100,(30,4))
# print(data)
# 把data进行标准化
x=scaler.fit_transform(data)
print(x)
7.特征降维
降维:去掉一些特征或者将多个特征转化为少量个特征
在尽可能保留数据的重要信息上减少数据集维度,可以减少计算成本、去除噪声
方式:特征选择、主成份分析(PCA)
1.特征选择
①.VarianceThreshold 低方差过滤特征选择
计算方差-设定阈值-过滤特征
eg8
# 低方差过滤
from sklearn.feature_selection import VarianceThreshold
transfer=VarianceThreshold(threshold=0.01)
x=[[0,2,0,3],
[0,1,4,3],
[0,1,1,3]]
x=transfer.fit_transform(x)
print(x)
②.根据相关系数的特征选择
正相关性:一个变量增加通常伴随着另一个变量的增加。ρ=1,完全正相关
负相关性:一个变量减少通常伴随着另一个变量的减少。ρ=-1,完全负相关
不相关:两者的相关性很小,一个变量变化不会引起另外的变量变化。ρ=0,不存在线性关系
! pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scipy
皮尔逊相关系数(Pearson correlation coefficient)是一种度量两个变量之间线性相关性的统计量。它提供了两个变量间关系的方向(正相关或负相关)和强度的信息,取值范围是 [−1,1]。绝对值越大,表示越相关,当两特征完全相关时,两特征的值表示的向量是在同一条直线上,当两特征的相关系数绝对值很小时,两特征值表示的向量接近在同一条直线上。当相关系值为负数时,表示负相关
|ρ|<0.4为低度相关; 0.4<=|ρ|<0.7为显著相关; 0.7<=|ρ|<1为高度相关
API:
scipy.stats.personr(x, y) 计算两特征之间的相关性
返回对象有两个属性:
statistic皮尔逊相关系数[-1,1]
pvalue零假设(了解),统计上评估两个变量之间的相关性,越小越相关
from scipy.stats import pearsonr
import numpy as np
x1=[1,2,3,4,5]
y=[2,4,6,8,10]
r=pearsonr(x1,y)
print(r.statistic,r.pvalue)
2.主成份分析(PCA)
从原始特征空间中找到一个新的坐标系统,使得数据在新坐标轴的投影能够最大程度地保留数据的方差,同时减少维度。
保留信息/丢失信息=信息保留的比例
步骤:得到矩阵-用矩阵P对原始数据进行线性变换,得到新的数据矩阵Z-根据主成分的方差等,确定最终保留的主成分个数,留下方差大的
API
from sklearn.decomposition import PCA
PCA(n_components=None)
n_components:
-
实参为小数时:表示降维后保留百分之多少的信息
-
实参为整数时:表示减少到多少特征
eg9
#特征降维 减少到多少特征
from sklearn.decomposition import PCA
data=[[2,8,4,5],
[6,3,0,8],
[5,4,9,1]]
pca=PCA(n_components=2)
data=pca.fit_transform(data)
print(data)
#特征降维
from sklearn.decomposition import PCA
import numpy as np
data=np.random.rand(5,100)#5条数据,100个特征量
#print(data)
pca=PCA(n_components=0.8)
data=pca.fit_transform(data)
print(data.shape,data)