1 实验介绍
1.1 关天本实验
特征是指区分事物的属性。特征工程是指通过规范化、标准化、鲁棒化和正则化等方法将数据转换成符合算法要求的数据。重点介绍词袋模型和词向量,特别是独热编码和TF-IDF。
1.2 实验目的
了解特征工程的基本概念;掌握归一化、标准化、鲁棒化、正则化等特征预处理方法;理解独热编码和TF-IDF技术的作用,掌握独热编码和TF-IDF的实现。
2 特征预处理
特征预处理就是对特征进行集成、转换、规约等处理,主要包括特征的归一化、标准化、鲁棒化、正则化等方法。Sklearn的preprocessing模块提供的相关函数如下:
(1)归一化:preprocessing.MinMaxScaler
(2)标准化:preprocessing.StandardScaler
(3)鲁棒化:preprocessing.RobustScaler
(4)正则化:preprocessing.Normalize
2.1 归一化
不同特征往往具有不同的量纲,其差别较大的数值影响数据分析结果。为了让不同特征具有同等的特性,往往需要进行归一化处理,通过对原始数据进行线性转换,将数据归一到[0,1]。
Sklearn提供MinMaxScaler方法进行规范化,具体语法如下所示:
MinMaxScaler(feature_range=(0,1))
【任务1】规范化举例
from sklearn.preprocessing import MinMaxScaler
def Normalization(): #实例化一个转换器类
Normalization = MinMaxScaler(feature_range=(0,1)) #范围设置为0~1之间
data=[[90,2,10,40],[60,4,15,45],[75,3,13,46]]
print(data)
#调用fit_transform
data_Normal = Normalization.fit_transform(data)
print(data_Normal)
return None
if __name__=='__main__':
Normalization()
程序运行结果如下:
[[90, 2, 10, 40], [60, 4, 15, 45], [75, 3, 13, 46]]
[[1. 0. 0. 0. ]
[0. 1. 1. 0.83333333]
[0.5 0.5 0.6 1. ]]
2.2 标准化
标准化可以将数据按比例缩放到特定区间。z-score标准化又称为标准差标准化,指将数据处理成符合标准正态分布的数据,下面是使用NumPy模块和Sklearn模块实现标准化的两种方法。
方法一:采用NumPy模块实现。
【任务2】采用numpy模块实现标准化举例
import numpy as np
def z_norm(data_list):
data_len=len(data_list)
if data_len==0:
raise "数据为空"
data_list=np.array(data_list)
mean_v=np.mean(data_list,axis=0)
std_v=np.std(data_list,axis=0)
print('该矩阵的均值为:{}\n 该矩阵的标准差为:{}'.format(mean_v,std_v))
#if std_v==0:
# raise "标准差为0"
return(data_list-mean_v)/std_v
if __name__ == '__main__':
data_list =[[1.5, -1., 2.],
[2., 0., 0.]]
print('矩阵初值为:{}'.format(data_list))
print("z-score标准化 \n",z_norm(data_list))
程序运行结果如下:
矩阵初值为:[[1.5, -1.0, 2.0], [2.0, 0.0, 0.0]]
该矩阵的均值为:[ 1.75 -0.5 1. ]
该矩阵的标准差为:[0.25 0.5 1. ]
z-score标准化
[[-1. -1. 1.]
[ 1. 1. -1.]]
方法二:Sklearn模块提供StandardScaler()实现标准化,具体语法形式如下:
StandardScaler(copy,with_mean)
具体说明如下:
(1)copy:取值为True或False,False意味着用归一化的值替代原来的值。
(2)with_mean:取值为True或False,False意味着是稀疏矩阵。
【任务3】采用Sklearn模块实现标准化举例
import numpy as np
from sklearn.preprocessing import StandardScaler
def Standardization():
data_list =[[1.5, -1., 2.], [2., 0., 0.]]
print('矩阵初值为:{}'.format(data_list))
scaler = StandardScaler()
data_Standard = scaler.fit_transform(data_list)
print('该矩阵的均值为:{}\n 该矩阵的标准差为:{}'.format(scaler.mean_,np.sqrt(scaler.var_)))
print('标准差标准化的矩阵为:{}'.format(data_Standard))
return None
if __name__=='__main__':
Standardization()
程序运行结果如下:
矩阵初值为:[[1.5, -1.0, 2.0], [2.0, 0.0, 0.0]]
该矩阵的均值为:[ 1.75 -0.5 1. ]
该矩阵的标准差为:[0.25 0.5 1. ]
标准差标准化的矩阵为:[[-1. -1. 1.]
[ 1. 1. -1.]]
2.3 鲁棒化
异常值往往出现在最大值或最小值处,可以使用鲁棒化进行处理。RobustScaler函数使用中位数和四分位数进行数据转换,具体语法形式如下:
RobustScaler(quantile_range,with_centering,with_scaling)
具体说明如下:
(1)with_centering:布尔值(默认值为True),在缩放之前将数据居中。
(2)with_scaling:布尔值(默认值为True),将数据缩放到四分位数据范围。
(3)quantile_range:元组(默认值为(25.0,75.0)),用于计算分位数范围。
【任务4】鲁棒化举例
from sklearn.preprocessing import RobustScaler
X = [[ 1., -2., 2.],[ -2., 1., 3.],[ 4., 1., -2.]]
transformer = RobustScaler().fit(X)
RobustScaler(quantile_range=(25.0,75.0),with_centering=True,with_scaling=True)
print(transformer.transform(X))
程序运行结果如下:
[[ 0. -2. 0. ]
[-1. 0. 0.4]
[ 1. 0. -1.6]]
2.4 正则化
Preprocessing模块提供normalize()函数实现正则化,具体语法形式如下:
normalize(X,norm=‘l2’)
具体说明如下:
(1)X:样本数据。
(2)norm=‘l2’:L2范式。
【任务5】正则化举例
from sklearn.preprocessing import normalize
X = [[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]]
X_normalized = normalize(X, norm='l2')
print(X_normalized)
程序运行结果如下:
[[ 0.40824829 -0.40824829 0.81649658]
[ 1. 0. 0. ]
[ 0. 0.70710678 -0.70710678]]
3 独热编码
3.1 认识独热编码
词向量是将词语转换成向量矩阵的计算模型,是自然语言处理中的一组语言建模和特征学习技术的统称。最常用的词向量是独热编码(One-Hot编码),又称为一位有效编码,文本中的n个单词构成n个词向量,单词所在位置为k,则词向量为“第k位为1,其他位置都为0”,独热编码保证了每一个取值只会使得一种状态处于“激活态”,具有操作简单、容易理解的优点。但是,当词汇表内容较多时,必然导致词向量的维度较大,独热编码多数位置会出现0,出现稀疏编码。另外,独热编码完全割裂了词与词之间的联系。
【例1】One-Hot编码
步骤1:确定编码对象:[”中国”,"美国”,"日本”,"美国“]。
步骤2:确定分类变量:中国、美国、日本共3种类别。
步骤3:进行特征编码:中国一0,美国一1,日本一2。
["中国”,“美国”,“日本”,“美国”]进行One-Hot编码为[[1,0,0],[0,1,0],[0,0,1],[0,1,0]]。
3.2 Pandas实现
Pandas的get_dummies()函数实现one-hot编码,具体语法形式如下:
Pandas.get_dummies(data,sparse=False)
具体说明如下:
(1)data:数组类型、Series、DataFrame等。
(2)sparse=False:稀疏矩阵。
【任务6】采用pandas实现one-hot编码举例
import pandas as pd
s= pd.Series(list("abcd"))
print(s)
s1= pd.get_dummies(s,sparse=True)
print(s1)
程序运行结果如下:
0 a
1 b
2 c
3 d
dtype: object
a b c d
0 1 0 0 0
1 0 1 0 0
2 0 0 1 0
3 0 0 0 1
3.3 Sklearn 实现
Sklearn库Preprocessing模块中的OneHotEncoder()函数实现One-Hot编码。
【任务7】采用sklearn实现one-hot编码举例
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
enc.fit([[0, 0, 3],
[1, 1, 0],
[0, 2, 1] ,
[1, 0, 2]
]) # fit编码
ans1 = enc.transform([[0, 1, 3]]) #输出稀疏矩阵
ans2 = enc.transform([[0, 1, 3]]).toarray() #输出数组格式
print("稀疏矩阵\n",ans1)
print("数组格式\n",ans2)
程序运行结果如下:
稀疏矩阵
(0, 0) 1.0
(0, 3) 1.0
(0, 8) 1.0
数组格式
[[1. 0. 0. 1. 0. 0. 0. 0. 1.]]
3.4 DictVectorizer
当数据以”字典“数据结构进行存储,Sklearn提供DictVectorizer实现特征提取,具体语法形式如下:
sklearn.feature_extraction DictVectorizer(sparse=True)
sparse=True表示返回稀疏矩阵,只矩阵中非零值按位置表示。
【任务8】字典特征抽取举例
from sklearn.feature_extraction import DictVectorizer
def dictvec1():
# 定义一个字典列表,表示多个数据样本
data = [ {"city": "上海", 'temperature': 100},
{"city": "北京", 'temperature': 60},
{"city": "深圳", 'temperature': 30} ]
#1、转换器
DictTransform = DictVectorizer( )
#DictTransform = DictVectorizer(sparse=True) 输出为稀疏矩阵
#DictTransform = DictVectorizer(sparse=False) 输出为二维数组
#2、调用fit_transform方法,返回sparse矩阵
data_new = DictTransform.fit_transform(data)
print(DictTransform.get_feature_names_out())
print(data_new)
return None
if __name__ == '__main__':
dictvec1()
程序运行结果如下:
[‘city=上海’, ‘city=北京’, ‘city=深圳’, ‘temperature’]
(0, 0) 1.0
(0, 3) 100.0
(1, 1) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0
4 CountVectorizer
4.1 认识CountVectorizer
Count Vectorizer适合于主题较多的语料集。Count Vectorizer构成特征矩阵的每一行表示一个训练文本的词频统计结果,只考虑每个单词在文本中出现的频率。其思想是,将文本中每个单词视为一个特征,构成一个词汇表,不考虑单词出现的先后次序,该方法又称为词袋法(Bag of Words)。词袋模型是最早的自然语言处理模型,将文章中的词语通过计数的方式转换为数字。
4.2 Sklearn调用CountVectorizer
Sklearn提供Count Vectorizer方法实现,具体语法形式如下。
sklearn.feature_extraction.text.CountVectorizer(stop_words)
stop_words:停止词表。
【任务9】CountVectorizer举例
from sklearn.feature_extraction.text import CountVectorizer
texts=["orange banana apple grape","banana apple apple","grape", 'orange apple']
#1.实例化一个转换器类
cv = CountVectorizer()
#2.调用fit_transform()
cv_fit=cv.fit_transform(texts)
print(cv.vocabulary_)
print(cv_fit.shape)
print(cv_fit)
print(cv_fit.toarray())
程序运行结果如下:
{‘orange’: 3, ‘banana’: 1, ‘apple’: 0, ‘grape’: 2}
(4, 4)
(0, 3) 1
(0, 1) 1
(0, 0) 1
(0, 2) 1
(1, 1) 1
(1, 0) 2
(2, 2) 1
(3, 3) 1
(3, 0) 1
[[1 1 1 1]
[2 1 0 0]
[0 0 1 0]
[1 0 0 1]]
5 TF-IDF
5.1 认识TF-IDF
词语对于篇章的重要性与其在文中出现的词频往往成正比。但是,停用词的词频虽然很大,信息量却几乎为0,因此,只是根据词频评价词语的重要性是不准确的,由此引人TF-IDF。TF-IDF(Term Frequency-Inverse Document Frequency,词频与逆向文件频率)是一种用于信息检索与数据挖掘的常用加权技术,通过衡量一个词语重要程度的统计指标,用于评估词语对于文件的重要程度。
TFDF不仅考虑了词频,更考虑词语的稀有程度,词语的重要程度正比于其在文档中出现的频次,反比于其存在于多少篇文章中。当一个词语在某文章中出观较高频次,在其他文章中出现较低频次,说明该词语具有较好的区分度。
5.2 计算TF-IDF
TF-IDF计算步骤如下:
步骤一:计算TF
TF计算统计文本中某个词的出现次数,计算公式如下。
步骤二:计算IDF
IDF计算用于计算某词频的腻向文件频率,计算公式如下。
步骤三:计算TF-IDF
TF-IDF算法=TF算法*IDF算法。
【例2】TF-IDF计算
(1)计算TF:某文件共有100个词语,“苹果”出现3次,“苹果”在该文件中的词频就是3/100=0.03。
(2)计算IDF:“苹果”在1000个文档中出现,全部文件总数是10000000个,逆向文件频率是1og(10000000/1000)=4。
(3)计算TF-IDF:TF-IDF的值就是0.03×4=0.12。
5.3 Sklearn调用TF-IDF
计算TF-IDF可以采用Sklearn提供的TfidfVectorizer()函数实现,具体语法形式如下。
TfidfVectorizer(stop_words,sublinear_tf,max df)
参数说明如下:
(1)stop_words:停止词表。
(2)sublinear_tf:取值为True或False。
(3)max_df:文件频率阈值。
【任务10】TfidfVectorizer举例
from sklearn.feature_extraction.text import TfidfVectorizer
texts=["orange banana apple grape","banana apple apple","grape", 'orange apple']
cv = TfidfVectorizer()
cv_fit=cv.fit_transform(texts)
print(cv.vocabulary_)
print(cv_fit)
print(cv_fit.toarray())
程序运行结果如下:
{‘orange’: 3, ‘banana’: 1, ‘apple’: 0, ‘grape’: 2}
(0, 2) 0.5230350301866413
(0, 0) 0.423441934145613
(0, 1) 0.5230350301866413
(0, 3) 0.5230350301866413
(1, 0) 0.8508160982744233
(1, 1) 0.5254635733493682
(2, 2) 1.0
(3, 0) 0.6292275146695526
(3, 3) 0.7772211620785797
[[0.42344193 0.52303503 0.52303503 0.52303503]
[0.8508161 0.52546357 0. 0. ]
[0. 0. 1. 0. ]
[0.62922751 0. 0. 0.77722116]]