一、什么是特征工程
机器学习领域的大神Andrew Ng(吴恩达)老师说“Coming up with features is difficult, time-consuming, requires expert knowledge. “Applied machine learning” is basically feature engineering. ”
注:业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已
特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程
意义:会直接影响机器学习的效果
二、用什么做特征工程
目前就是sklearn
三、特征工程的位置与数据处理的比较
1、pandas
一个数据读取非常方便以及基本的处理格式的工具
2、sklearn
对于特征的处理提供了强大的接口
3、特征工程包含内容
(1)特征抽取
(2)特征预处理
(3)特征降维
4、特征抽取/特征提取
比如有一篇英文短文,要对文章进行分类:
机器学习算法 -- 统计方法 -- 数学公式
数学公式不能处理字符串,要把文本字符串转换成数值的类型
问题:文本类型转换成数值怎么转?
分类船仓位
问题:类型转换成数值?
onehot编码或者哑变量
四、特征提取
1、什么是特征提取
将任意数据(如文本或图像)转换为可用于机器学习的数字特征
注:特征值化是为了计算机更好的去理解数据
(1)字典特征提取(特征离散化)
(2)文本特征提取
(3)图像特征提取(深度学习将介绍)
2、特征提取API
sklearn.feature_extraction
五、字典的特征提取
sklearn.feature_extraction.DictVectorizer(sparse=True, ...)
作用:对字段数据进行特征值化
说明:
vector 数学里是向量,物理里是矢量
matrix 矩阵,二维数组
如果将向量存储在计算机中,可以用一维数组来存储
1、DicVectorizer.fit_transform(X)
X:字段或者包含字典的迭代器
返回值:返回sparse矩阵
2、DicVectorizer.inverse_transform(X)
X:array数组或者sparse矩阵
返回值:转换之前数据格式
3、DicVectorizer.get_feature_names()
返回值:返回类别名称
4、例子
我们对以下数据进行特征提取
[{'city': '北京','temperature':100}
{'city': '上海','temperature':60}
{'city': '深圳','temperature':30}]
上面一行代表feature_names,下面三行就是data
解释一下,如果有三个城市就有3个0,字典排列顺序是几第几个0就变成1,有点像二进制编码
样本是一个三行两列的矩阵,当进行字典特征抽取之后,样本量变成4列了
把城市类别转换成了one-hot编码
5、修改day01_machine_learning.py
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
def datasets_demo():
"""
sklearn数据集使用
"""
#获取数据集
iris = load_iris()
print("鸢尾花数据集:\n", iris)
print("查看数据集描述:\n", iris["DESCR"])
print("查看特征值的名字:\n", iris.feature_names)
print("查看特征值几行几列:\n", iris.data.shape)
#数据集的划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
print("训练集的特征值:\n", x_train, x_train.shape)
return None
def dict_demo():
"""
字典特征抽取
"""
data = [{'city': '北京','temperature':100},{'city': '上海','temperature':60},{'city': '深圳','temperature':30}]
# 1、实例化一个转换器类
transfer = DictVectorizer()
# 2、调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
if __name__ == "__main__":
# 代码1:sklearn数据集使用
#datasets_demo()
# 代码2:字典特征抽取
dict_demo()
运行结果:
data_new:
(0, 1) 1.0
(0, 3) 100.0
(1, 0) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0
为什么是这个结果:
这个API将X传进来之后,返回sparse矩阵(sparse英文是稀疏的意思,就是稀疏矩阵)
如果设置:transfer = DictVectorizer(sparse=False)
就会得到预想的结果:
data_new:
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
怎么看稀疏矩阵:某些矩阵中,非0元素远少于0元素。典型存储方法:三元组法,(行,列,元素值)
就是标注了稀疏矩阵中的非零元素的位置以及对应的值,通俗点讲:0行1列的数值是1,在预想结果里就能找到
好处是节省内存,提高加载效率
增加打印特征名:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
def datasets_demo():
"""
sklearn数据集使用
"""
#获取数据集
iris = load_iris()
print("鸢尾花数据集:\n", iris)
print("查看数据集描述:\n", iris["DESCR"])
print("查看特征值的名字:\n", iris.feature_names)
print("查看特征值几行几列:\n", iris.data.shape)
#数据集的划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
print("训练集的特征值:\n", x_train, x_train.shape)
return None
def dict_demo():
"""
字典特征抽取
"""
data = [{'city': '北京','temperature':100},{'city': '上海','temperature':60},{'city': '深圳','temperature':30}]
# 1、实例化一个转换器类
transfer = DictVectorizer(sparse=False)
# 2、调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
print("特征名字:\n", transfer.get_feature_names())
return None
if __name__ == "__main__":
# 代码1:sklearn数据集使用
#datasets_demo()
# 代码2:字典特征抽取
dict_demo()
data_new:
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
特征名字:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
六、文本特征提取
1、作用
对文本数据进行特征值化
单词作为特征,特征词
2、方法一:CountVectorizer
sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
返回值:返回词频矩阵
3、CountVectorizer.fit_transform(X)
X:文本或者包含文本字符串的可迭代对象
返回值:返回sparse矩阵
4、CountVectorizer.inverse_transform(X)
X:array数组或者sparse矩阵
返回值:转换之前的数据格式
5、CountVectorizer.get_feature_names()
返回值:单词列表
6、例子
我们对一下数据进行特征提取
["life is short,i like python",
"life is too long,i dislike python"]
为什么没有i,因为api设计的时候认为单词做分类或情感分析意义不大
7、修改day01_machine_learning.py
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer
def datasets_demo():
"""
sklearn数据集使用
"""
#获取数据集
iris = load_iris()
print("鸢尾花数据集:\n", iris)
print("查看数据集描述:\n", iris["DESCR"])
print("查看特征值的名字:\n", iris.feature_names)
print("查看特征值几行几列:\n", iris.data.shape)
#数据集的划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
print("训练集的特征值:\n", x_train, x_train.shape)
return None
def dict_demo():
"""
字典特征抽取
"""
data = [{'city': '北京','temperature':100},{'city': '上海','temperature':60},{'city': '深圳','temperature':30}]
# 1、实例化一个转换器类
transfer = DictVectorizer(sparse=False)
# 2、调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
print("特征名字:\n", transfer.get_feature_names())
return None
def count_demo():
"""
文本特征抽取
"""
data = ["life is short,i like like python", "life is too long,i dislike python"]
# 1、实例化一个转换器类
transfer = CountVectorizer()
# 2、调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new.toarray())
print("特征名字:\n", transfer.get_feature_names())
return None
if __name__ == "__main__":
# 代码1:sklearn数据集使用
#datasets_demo()
# 代码2:字典特征抽取
#dict_demo()
# 代码3:文本特征抽取
count_demo()
运行结果:
data_new:
[[0 1 1 2 0 1 1 0]
[1 1 1 0 1 1 0 1]]
特征名字:
['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']
统计每个样本特征词出现的个数
8、中文文本特征抽取
问题:如果我们将数据替换成中文?
那么得到的结果是把整句作为了一个词,手工打空格则不支持单个中文词!