为什么需要特征工程 (Feature Engineering)
数据和特征决定了机器学习的上限, 而模型和算法只是逼近这个上限而已
什么是特征工程
帮助我们使得算法性能更好发挥性能而已
sklearn 主要用于特征工程
pandas 主要用于数据清洗, 数据处理
特征工程包含如下 3 个内容:
1, 特征抽取 / 特征提取
|__> 字典特征抽取
|__> 文本特征抽取
|__> 图像特征抽取 (深度学习)
2, 特征预处理
3, 特征降维
特征抽取 / 特征提取
我们常说的机器学习算法实际上就是我们统计学上的统计方法也就是我们数学上的数学公式
即 机器学习算法 --》统计方法 --》数学公式
字典特征抽取的应用场景: 1)pclass, sex 数据集当中类别特征比较多
1, 将数据集的特征 转换为字典类型
2, 利用 DictVectorizer 转换为二维数组
2) 本身拿到的数据就是字典类型
1- 字典特征提取:
当我们调用 sklearn.feature_extraction.DictVectorizer(sparse=True,...) 的时候, 实际上就是初始化了一个父类的转换器对象, 然后调用实例进行 fit_transform(X), 进行字典和数值的转换.
(下图) 有多少行数据就有多少个向量 (有方向和大小), 向量在计算机中以矩阵存储 (二维数组), 而矩阵的行和列都可以看做一个一维数组. 下图中一行数据可以看做一个向量, n 个样本有 n 个向量, 即将字典转换为了计算机识别的二维数组. 每一个样本有 2 个特征 (城市 + temperature), 正常应该返回一个 3 行 2 列的矩阵, 但是字典特征抽取后, 样本量没有变 (3 个样本), 但是特征量变成了 4 个 (当特征中有类别的时候, 要想表示成数值, 又想要公平的表示数据, 我们采用 one-hot 编码, 有 3 个类别, 就占用 3 列, 如果是北京, 则第二列的特征值就是 1, 最后添加上 temperature 就是 4 个特征了).
字典特征抽取 DEMO:
- from sklearn.feature_extraction.dict_vectorizer import DictVectorizer
- # 字典特征提取
- def dic_demo():
- data = [{'city': '北京', 'temperature': 100},
- {'city': '上海', 'temperature': 60},
- {'city': '深圳', 'temperature': 30}]
- # 1, 实例化一个转换器对象
- # transform = DictVectorizer(sparse=True) # 默认开启稀疏矩阵
- transform = DictVectorizer(sparse=False) # 默认 sparse=True,
- # 2, 调用 fit_transform()
- new_data = transform.fit_transform(data)
- # 3, 获取特征名称
- print("特征名字:\n", transform.get_feature_names()) # 特征名字:['city = 上海', 'city = 北京', 'city = 深圳', 'temperature']
- print('转换后的结果:\n', new_data)
- '''
- # sparse=True 时候的 new_data 的值: 返回的 new_data 是一个 sparse 的稀疏矩阵
- (0, 1) 1.0
- (0, 3) 100.0
- (1, 0) 1.0
- (1, 3) 60.0
- (2, 2) 1.0
- (2, 3) 30.0
- # sparse=True 时候的 new_data 的值, 返回的是一个二维数组
- [[ 0. 1. 0. 100.]
- [ 1. 0. 0. 60.]
- [ 0. 0. 1. 30.]]
- # 总结:
- 稀疏矩阵将非零值按位置表示出来, 这样做可以节省内存 - 提高加载效率
- '''if __name__ =='__main__':
- dic_demo()
结果截图:
附:
one-hot 编码:
对特征中的类别信息, 为了公平的表示每一组样本数据, 我们处理的时候, 就是根据类别进行划分, 样本中几个类别就有几列, 是这个数据则置该列的数值为 1, 否则为 0
2- 文本特征提取:
文本特征提取就是将单词, 字母, 短语作为主要的特征词进行特征提取
可以利用如下方法统计:
CountVectorizer: 统计的是文本中出现的特征词次数, stop_words 停用的停词表, toarray() 可以转换为二维数组
英文的测试 DEMO
- from sklearn.feature_extraction.text import CountVectorizer
- # 文本特征提取
- def text_count_demo():
- data = ["life is short,i like like python", "life is too long, i dislike python"]
- # 1, 实例化一个转换器类
- transfer = CountVectorizer()
- # transfer = CountVectorizer(stop_words=["is", "too"])
- '''
- 不添加 stop_words 的效果: transfer = CountVectorizer()
- 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']
- 添加 stop_words 的效果: transfer = CountVectorizer(stop_words=["is", "too"])
- data_new:
- [[0 1 2 0 1 1]
- [1 1 0 1 1 0]]
- 特征名字:
- ['dislike', 'life', 'like', 'long', 'python', 'short']
- '''
- # 2, 调用 fit_transform
- data_new = transfer.fit_transform(data)
- # data_new 返回的是一个 sparse 矩阵,
- print("矩阵_data_new:\n", data_new)
- # data_new.toarray() 返回的是一个二维数组
- print("数组_data_new:\n", data_new.toarray())
- '''
- 矩阵_data_new:
- (0, 5) 1
- (0, 3) 2
- (0, 6) 1
- (0, 1) 1
- (0, 2) 1
- (1, 0) 1
- (1, 4) 1
- (1, 7) 1
- (1, 5) 1
- (1, 1) 1
- (1, 2) 1
- 数组_data_new.toarray():
- [[0 1 1 2 0 1 1 0]
- [1 1 1 0 1 1 0 1]]
- ''' print(" 特征名字:\n", transfer.get_feature_names())
- return None
- if __name__ =='__main__':
- text_count_demo()
中文的分词 DEMO 效果:
- from sklearn.feature_extraction.text import CountVectorizer
- # 中文的需要进行分词, 否则是以整句作为分词的
- def chinese_text_count_demo():
- data = ["我爱北京天安门", "天安门上太阳升"]
- # data = ["我 爱 北京 天安门", "天安门 上 太阳 升"] # 添加了空格的中文分词
- '''
- 未添加空格的中文分词:
- data_new:
- [[0 1]
- [1 0]]
- 特征名字:
- ['天安门上太阳升', '我爱北京天安门']
- 添加了空格的中文分词:
- [[1 1 0]
- [0 1 1]]
- 特征名字:
- ['北京', '天安门', '太阳']
- '''
- # 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__':
- chinese_text_count_demo()
特征预处理
特征降维
来源: http://www.bubuko.com/infodetail-2980767.html