数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限
特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好作用的过程。
sklearn 特征工程
pands 数据处理
特征提取
机器学习算法--统计方法--数学
文本类型 -> 数值
sklearn.feature_extraction
字典特征提取:
采用的 one-hot 编码
字典特征提取
from sklearn.feature_extraction import DictVectorizer
def dict_demo():
data = [{'city': '北京', 'temperature': 100}, {'city': '上海', 'temperature': 60}, {'city': '深圳', 'temperature': 30}]
# 1、实例化一个转换器,默认返回的是稀疏矩阵(sparse),如果不想返回稀疏矩阵,要用sparse=False,稀疏矩阵指标是非零值
# 稀疏矩阵可以节省内存,只表示非0的有效值
transfer = DictVectorizer(sparse=False) # sparse为稀疏矩阵,默认返回为true
# 2、调用fit_transform(),返回的data_new的类型是一个sparse矩阵的对象
data_new = transfer.fit_transform(data)
print('转换结果\n', data_new)
print('特征名字:\n', transfer.get_feature_names())
return None
if __name__ == "__main__":
# 1、数据集使用
dict_demo()
文本特征提取
单词作为特征
特征:特征词
方法1:
# 文本特征抽取,统计每个样本出现特征词的个数,如果是处理中文的话,“特征词”与“特征词”之间要加上空格(但这种方法并不实用)
def count_demo():
data = ["life is short,i like like python", "life is too long,i dislike python"]
# 1 实例化一个转换器类,默认返回稀疏矩阵,有参数stop_words 停用词(比如 if ,too这些实际意义不大的词,可以不统计),如:停用词表
transfer = CountVectorizer(stop_words=['is', 'too'])
# 2 调用fit_transform方法
data_new = transfer.fit_transform(data)
# toarray()方法变成二维数组
print("data_new:\n", data_new.toarray())
# 查看特征名字
print("特征名字:\n", transfer.get_feature_names())
return None
上述方法并不适用于中文文本,对于中文文本的提取比较复杂,可以引用另一个库jieba
关键词:在某一个类别的文章中,出现的次数很多,但在其他类别的文章中出现的很少,这可以在transform矩阵中体现出来。
# 定义分词的函数,可以用来中文文本分词,为中文文本提取做准备
def cut_word(text):
'''
进行中文分词
:param text:
:return:
'''
# " ".join把列表变成列表内的元素
text = " ".join(list(jieba.cut(text)))
return text
# 中文文本特征提取
def count_chinese_demo():
# 带自动分词的中文文本特征抽取
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的.这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系."]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
print(data_new)
transfer = CountVectorizer()
# 2 调用fit_transform方法
data_final = transfer.fit_transform(data_new)
# toarray()方法变成二维数组
print("datanew:\n", data_final.toarray())
# 查看特征名字
print("特征名字:\n", transfer.get_feature_names())
return None
方法2:
TfidfVectorizer
可以自动找出哪一个词更为重要等优势
Tf--term frequncy--词频:给定词在文章中的频率
idf--inverse document frequency--逆向文档频率:重要性度量,总文件量除包含该词语的文件数,再对商取以10为底的对数。
库函数的API:
def tfidf_demo():
'''
用tf_idf的方法进行文本特征抽取 只需要修改转换器就行 transfer = TfidfVectorizer
其余与上述方法1写的count_chinese_demo一样
:return:
'''
# 带自动分词的中文文本特征抽取
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的.这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系."]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# print(data_new)
transfer = TfidfVectorizer(stop_words=['一种', '所以'])
# 2 调用fit_transform方法'
data_final = transfer.fit_transform(data_new)
# toarray()方法变成二维数组
print("data_new:\n", data_final.toarray())
# 查看特征名字
print("特征名字:\n", transfer.get_feature_names())
return None
数值型数据的无量纲化:
归一化
标准化
目的就是为了使不同规格的数据转换到同一规格
特征预处理API
sklearn.preprocessing
归一化:
为最终结果,mx,mi分别为指定区间,默认mx=1,mi=0
API:
# 数据的归一化 def minmax_demo(): ''' 数据的归一化 :return: ''' # 1 获取数据, 明确数据编码方式比较好,默认为asic编码 data = pd.read_csv("水垢数据(带标签).csv", encoding="utf-8") # 只要数据的前三列 data = data.iloc[:, :3] # print(data) # 2 实例化一个转换器类(可以设置归一化范围,如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
缺点:数据中如果有异常值(最大或最小值)所以鲁棒性较差,适合传统小数据场景
标准化:
mean 为均值,
为标准差
因为引入了均值和标准差,能够有效克服异常值的影响所以更为通用
API:
# 数据的标准化(消除最大最小值出现异常而影响了归一化的问题) def stand_demo(): ''' 数据的标准化 :return: ''' # 1 获取数据 data = pd.read_csv("水垢数据(带标签).csv", encoding="utf-8") # 只要数据的前三列 data = data.iloc[:, :3] print(data) # 2 实例化一个转换器类 transfer = StandardScaler() # 3 调用fit_transform data_new = transfer.fit_transform(data) print('data_new:\n', data_new) return None
应用场景较多
降维:
降低维度:在特定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程
目标:特征与特征之间不相关(减少冗余信息)
0维:标量
1维:向量
2维:矩阵
这里处理对象是二维数组
两种方法:
特征选择
主成分分析
特征选择:
数据中包含冗余相关变量,旨在从原有特征中找出主要特征
![]()
方法:
低方差特征过滤:
API:
# 特征值的低方差过滤 def variance_demo(): ''' 过滤低方差的特征 :return: ''' # 1 获取数据 data = pd.read_csv("水垢数据(带标签).csv", encoding="utf-8") # 保留数据额所有行,和第1到倒数第1列 data = data.iloc[1:, 0:-1] # 返回data.shape可以直接显示特征个数 # print(data, data.shape) # 2 实例化一个转换器类,threshold设置阈值,特征值的方差低于5的特征都会被删除 tranfer = VarianceThreshold(threshold=10) # 3 调用fit_transform data_new = tranfer.fit_transform(data) print('data_new:\n', data_new, data_new.shape) # 相关系数就表示了特征间的相关程度(这里采用皮尔逊相关系数api:pearsonr) # 计算两个变量的相关系数,返回结果的第一个值是相关系数,大于0是正相关,小于0是负相关 r1 = pearsonr(data['w1'], data['w3']) r2 = pearsonr(data['w2'], data['w4']) print('相关系数是:\n', r1) print('相关系数是:\n', r2) return None
主成分分析:
API:
案例:探究用户对物品类别的喜好细分
1、需要将user_id和aisle放在同一个表中
2、找到 user_id和aisle之间的关系 - 交叉表和透视表
3、特征冗余过多 -> PCA降维