机器学习———特征工程
1 特征工程概念
特征工程就是对特征进行相关的处理,一般使用pandas来进行数据清洗和数据处理、使用sklearn来进行特征工程,特征工程是将任意数据(如文本或图像)转换为可用于机器学习的数字特征,比如:字典特征提取(特征离散化)、文本特征提取、图像特征提取。
2 特征工程API
DictVectorizer 字典特征提取
CountVectorizer 文本特征提取
TfidfVectorizer TF-IDF文本特征词的重要程度特征提取
MinMaxScaler 归一化
StandardScaler 标准化
VarianceThreshold 底方差过滤降维
PCA 主成分分析降维
转换器对象调用fit_transform()进行转换, 其中fit用于计算数据,transform进行最终转换
fit_transform()可以使用fit()和transform()代替
data_new = transfer.fit_transform(data)
可写成
transfer.fit(data)
data_new = transfer.transform(data)
3 DictVectorizer 字典列表特征提取
稀疏矩阵
一个矩阵中大部分元素为零,只有少数元素是非零的矩阵。 例如,在一个1000 x 1000的矩阵中,如果只有1000个非零元素,那么这个矩阵就是稀疏的。
三元组表
三元组表就是一种稀疏矩阵类型数据,存储非零元素的行索引、列索引和值:
(行,列) 数据
(0,0) 10
(0,1) 20
(2,0) 90
(2,20) 8
(8,0) 70
表示除了列出的有值, 其余全是0
非稀疏矩阵(稠密矩阵)
矩阵中非零元素的数量与总元素数量相比接近或相等,也就是说矩阵中的大部分元素都是非零的。
api
- 创建转换器对象:
sklearn.feature_extraction.DictVectorizer(sparse=True)
参数:
sparse=True返回类型为csr_matrix的稀疏矩阵
sparse=False表示返回的是数组,数组可以调用.toarray()方法将稀疏矩阵转换为数组
- 转换器对象调用:
fit_transform(data)
参数:
data为一维字典数组或一维字典列表,返回转化后的矩阵或数组
转换器对象get_feature_names_out()方法获取特征名
示例:
from sklearn.feature_extraction import DictVectorizer
import pandas as pd
# sklearn.feature_extraction.DictVectorizer(sparse=True)
data = [{'city': '北京', 'temperature': 100},
{'city': '上海', 'temperature': 60},
{'city': '深圳', 'temperature': 30}]
# 初始化工具(字典变成向量的工具器)
# sparse=False表示返回的是数组
model=DictVectorizer(sparse=False)
data=model.fit_transform(data)
print(data,type(data))
# 获取所有的特征名称
print(model.get_feature_names_out())
# sparse=True返回类型为csr_matrix的稀疏矩阵,可以调用.toarray()方法将稀疏矩阵转换为数组
model=DictVectorizer(sparse=True)
data=model.fit_transform(data)
print(data,type(data))
print(model.get_feature_names_out())
arr=data.toarray()
print(arr)
sparse=False结果:
sparse=True结果:
4 CountVectorizer 文本特征提取
(1)API
sklearn.feature_extraction.text.CountVectorizer(stop_words=' ')
关键字:
参数stop_words,值为list,表示词的黑名单(不提取的词)
fit_transform函数的返回值为稀疏矩阵
(2) 英文文本提取
# CountVectorizer 文本特征提取
from sklearn.feature_extraction.text import CountVectorizer
corpus = [ 'I love machine learning. Its awesome.',
'Its a book amazon book',
'Amazon is a great company']
# 创建一个词频提取对象
# 构造函数关键字参数stop_words,值为list,表示词的黑名单(不提取的词)
vectorizer = CountVectorizer(stop_words=['amazon'])
# 提取词频
x=vectorizer.fit_transform(corpus)
print(x)
print(x.toarray())
print(vectorizer.get_feature_names_out())
输出结果:
(3) 中文文本提取
中文文本不像英文文本,中文文本文字之间没有空格,所以要先分词,一般使用jieba分词.
pip install jieba
jieba使用函数:jieba.cut(data)
示例:
# 中文文本提取
from sklearn.feature_extraction.text import CountVectorizer
import jieba
# 传入没有断词的文本
def my_cut(text):
return ' '.join(jieba.cut(text))
corpus = ['我来到北京清华大学',
'他来到了网易杭研大厦',
'小明硕士毕业与中国科学院']
vectorizer = CountVectorizer(stop_words=[])
x=vectorizer.fit_transform(my_cut(el) for el in corpus)
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), 表示一个词在当前篇文章中的重要性
逆文档频率(Inverse Document Frequency, IDF), 反映了词在整个文档集合中的稀有程度
(2) API
sklearn.feature_extraction.text.TfidfVectorizer()
构造函数关键字参数stop_words,表示词特征黑名单
fit_transform函数的返回值为稀疏矩阵
(3) 示例
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(res.toarray())
print(transfer.get_feature_names_out())
ddata=pd.DataFrame(res.toarray(),columns=transfer.get_feature_names_out())
ddata
输出结果:
6 无量纲化-预处理
无量纲,即没有单位的数据
(1) MinMaxScaler 归一化
通过对原始数据进行变换把数据映射到指定区间(默认为0-1)
1、公式:
若要缩放到其他区间,可以使用公式:x=x*(max-min)+min;
2、归一化API
sklearn.preprocessing.MinMaxScaler(feature_range)
参数:feature_range=(0,1) 归一化后的值域,可以自己设定
fit_transform函数归一化的原始数据类型可以是list、DataFrame和ndarray, 不可以是稀疏矩阵
fit_transform函数的返回值为ndarray
3、示例:
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
scaler=MinMaxScaler(feature_range=(0,1))
data=pd.read_excel('./src/test01.xlsx')
print(data.values)
arr=scaler.fit_transform(data.values)
print(arr)
4、缺点
最大值和最小值容易受到异常点影响,如一个异常值远远大于正常值,所以鲁棒性较差。所以常使用标准化的无量钢化
(2)StandardScaler 标准化
它的目的是将不同特征的数值范围缩放到统一的标准范围,以便更好地适应一些机器学习算法,特别是那些对输入数据的尺度敏感的算法。
1、标准化公式
最常见的标准化方法是Z-score标准化,也称为零均值标准化。它通过对每个特征的值减去其均值,再除以其标准差,将数据转换为均值为0,标准差为1的分布。这可以通过以下公式计算:
其中,z是转换后的数值,x是原始数据的值,μ是该特征的均值,σ是该特征的标准差
2、标准化 API
sklearn.preprocessing.StandardScale
与MinMaxScaler一样,原始数据类型可以是list、DataFrame和ndarray
fit_transform函数的返回值为ndarray, 归一化后得到的数据类型都是ndarray
3、标准化示例
from sklearn.preprocessing import StandardScaler
import numpy as np
# 初始化标准化工具
scaler=StandardScaler()
np.random.seed(7)
data=np.random.randint(0,100,(10,4))
print(data)
x=scaler.fit_transform(data)
print(x)
4、注意点
在数据预处理中,特别是使用如StandardScale这样的数据转换器时,fit、fit_transform和transform这三个方法的使用是至关重要的,它们各自有不同的作用:
-
fit:
-
这个方法用来计算数据的统计信息,比如均值和标准差(在StandardScale的情况下)。这些统计信息随后会被用于数据的标准化。
-
你应当仅在训练集上使用fit方法。
-
-
fit_transform:
-
这个方法相当于先调用fit再调用transform,但是它在内部执行得更高效。
-
它同样应当仅在训练集上使用,它会计算训练集的统计信息并立即应用到该训练集上。
-
-
transform:
-
这个方法使用已经通过fit方法计算出的统计信息来转换数据。
-
它可以应用于任何数据集,包括训练集、验证集或测试集,但是应用时使用的统计信息必须来自于训练集。
-
总结来说:我们常常是先fit_transform(x_train)然后再transform(x_text)
7 特征降维
实际数据中,有时候特征很多,会增加计算量,降维就是去掉一些特征,或者转化多个特征为少量个特征
特征降维其目的:是减少数据集的维度,同时尽可能保留数据的重要信息。
1 .特征选择
(a) VarianceThreshold 低方差过滤特征选择
如果一个特征的方差很小,说明这个特征的值在样本中几乎相同或变化不大,包含的信息量很少,模型很难通过该特征区分不同的对象
(b) 根据相关系数的特征选择
皮尔逊相关系数(Pearson correlation coefficient)是一种度量两个变量之间线性相关性的统计量。它提供了两个变量间关系的方向(正相关或负相关)和强度的信息。皮尔逊相关系数的取值范围是 [−1,1],相关系数$\rho$的绝对值为0-1之间,绝对值越大,表示越相关,当两特征完全相关时,两特征的值表示的向量是在同一条直线上,当两特征的相关系数绝对值很小时,两特征值表示的向量接近在同一条直线上。
api:
scipy.stats.personr(x, y) 计算两特征之间的相关性
返回对象有两个属性:
statistic皮尔逊相关系数[-1,1]
pvalue零假设(了解),统计上评估两个变量之间的相关性,越小越相关
示例:
from scipy.stats import pearsonr
import pandas as pd
def association_demo():
data = pd.read_csv('src/factor_returns.csv')
data = data.iloc[:, 1:-2]
# 计算某两个变量之间的相关系数
r1 = pearsonr(data["pe_ratio"], data["pb_ratio"])
print(r1.statistic) #-0.0043893227799362555 相关性, 负数表示负相关
print(r1.pvalue) #0.8327205496590723 正相关性
r2 = pearsonr(data['revenue'], data['total_expense'])
print(r2) #PearsonRResult(statistic=0.9958450413136111, pvalue=0.0)
return None
association_demo()