python机器学习--特征抽取
特征抽取
一个文本转换小实例
# 导入包(feature_extraction是特征抽取的API)
from sklearn.feature_extraction.text import CountVectorizer
# 实例化CountVectorizer
vector = CountVectorizer()
# 调用fit_transform输入并转换数据
res = vector.fit_transform(["河南","福建","life is short,i like python"])
print(res.toarray())
[[0 0 0 0 0 1 0]
[0 0 0 0 0 0 1]
[1 1 1 1 1 0 0]]
字典数据抽取
- DictVectorizer.fit_transform(X)
- X:字典或者包含字典的迭代器
- 返回值:返回sparse矩阵
- DictVectorizer.inverse_transform(X)
- X:array数组或者sparse矩阵
- 返回值:转换之前数据格式
- DictVectorizer.get_feature_names()
- 返回类别名称
- DictVectorizer.transform(X)
- 按照原先的标准转换
# 导入包
from sklearn.feature_extraction import DictVectorizer
# 实例化
# sparse表示是否压缩矩阵,默认True
dict = DictVectorizer(sparse=True)
data = dict.fit_transform([{'city': '北京','temperature': 100},
{'city': '上海','temperature':60},
{'city': '深圳','temperature': 30}])
print(data)
print(dict.get_feature_names())
(0, 1) 1.0
(0, 3) 100.0
(1, 0) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0
[‘city=上海’, ‘city=北京’, ‘city=深圳’, ‘temperature’]
字典数据抽取:把字典中一些类别数据,分别进行转换成特征
数组形式数据,先转换字典数据进行处理,将变成One-hot编码,如图1.1.1
文本数据抽取(第一种方式)
类:sklearn.feature_extraction.text.CountVectorizer
作用:对文本数据进行特征值化
CountVectorizer语法
-
CountVectorizer(max_df=1.0,min_df=1,…)
- 返回词频矩阵
-
CountVectorizer.fit_transform(X,y)
- X:文本或者包含文本字符串的可迭代对象
- 返回值:返回sparse矩阵
-
CountVectorizer.inverse_transform(X)
- X:array数组或者sparse矩阵
- 返回值:转换之前数据格式
-
CountVectorizer.get_feature_names()
- 返回值:单词列表
# 先实例化,在转化
# 文本次数的统计,多用于文本分类和情感分析
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer()
data = cv.fit_transform(["life is is short,i like python",
"life is too long,i dislike python"]
)
print(cv.get_feature_names())
print(data.toarray())
[‘dislike’, ‘is’, ‘life’, ‘like’, ‘long’, ‘python’, ‘short’, ‘too’]
[[0 2 1 1 0 1 1 0]
[1 1 1 0 1 1 0 1]]
- 统计文本所有的词,重复的只看做一种
- 对每篇文章,在词的列表里面进行统计每个词的次数
- 单个字母不统计,一个字母不具备分类依据
# 中文处理
data = cv.fit_transform(["人生 苦短,我 喜欢 python", "人生漫长,不用 python"])
print(cv.get_feature_names())
print(data.toarray())
[‘python’, ‘不用’, ‘人生’, ‘人生漫长’, ‘喜欢’, ‘苦短’]
[[1 0 1 0 1 1]
[1 1 0 1 0 0]]
对于中文默认不支持抽取,必须需要将词语用空格分词,再进行抽取,可以使用jieba.cut分词
# 导入包将中文进行分词
import jieba
con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")
con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")
# 将生成器转化成列表
content1 = list(con1)
content2 = list(con2)
content3 = list(con3)
print(content1)
# 再把列表变成字符串
c1 = ' '.join(content1)
c2 = ' '.join(content2)
c3 = ' '.join(content3)
data = cv.fit_transform([c1,c2,c3])
print(cv.get_feature_names())
print(data.toarray())
[‘今天’, ‘很’, ‘残酷’, ‘,’, ‘明天’, ‘更’, ‘残酷’, ‘,’, ‘后天’, ‘很’, ‘美好’, ‘,’, ‘但’, ‘绝对’, ‘大部分’, ‘是’, ‘死’, ‘在’, ‘明天’, ‘晚上’, ‘,’, ‘所以’, ‘每个’, ‘人’, ‘不要’, ‘放弃’, ‘今天’, ‘。’]
[‘一种’, ‘不会’, ‘不要’, ‘之前’, ‘了解’, ‘事物’, ‘今天’, ‘光是在’, ‘几百万年’, ‘发出’, ‘取决于’, ‘只用’, ‘后天’, ‘含义’, ‘大部分’, ‘如何’, ‘如果’, ‘宇宙’, ‘我们’, ‘所以’, ‘放弃’, ‘方式’, ‘明天’, ‘星系’, ‘晚上’, ‘某样’, ‘残酷’, ‘每个’, ‘看到’, ‘真正’, ‘秘密’, ‘绝对’, ‘美好’, ‘联系’, ‘过去’, ‘这样’]
[[0 0 1 0 0 0 2 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 2 0 1 0 2 1 0 0 0 1 1 0 0 0]
[0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 1 1]
[1 1 0 0 4 3 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 2 1 0 0 1 0 0]]
文本抽取(第二种方式)
问题如图
可以使用tf-idf,求出tf * idf , 分类机器学习算法的的重要依据
- tf:词的频率
- idf:逆文档数量------log(总文档数量/该词出现的文档数)
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,
并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分
能力,适合用来分类。
TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
类:sklearn.feature_extraction.text.TfidfVectorizer
# 导包
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()
data = tf.fit_transform([c1,c2,c3])
# print(tf.get_feature_names())
# print(tf.inverse_transform(data))
# print(tf.inverse_transform(data))
# print(tf.inverse_transform(data.toarray()))
# # print(type(data))
# # print(data)
# print(data.toarray())
# print(np.sort(data.toarray(),axis = 1))
[[0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0.21821789 0.21821789 0.21821789 0.21821789 0.21821789 0.21821789
0.21821789 0.21821789 0.21821789 0.43643578 0.43643578 0.43643578]
[0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0.2410822 0.2410822 0.2410822 0.2410822
0.2410822 0.2410822 0.2410822 0.2410822 0.48216441 0.55004769]
[0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0.1193896 0.15698297 0.15698297
0.15698297 0.15698297 0.15698297 0.15698297 0.15698297 0.15698297
0.15698297 0.15698297 0.15698297 0.31396594 0.47094891 0.62793188]]
数据的特征处理
通过特定的统计方法(数学方法)将数据转换成算法要求的数据
- 数值型数据:标准缩放:
- 归一化
- 标准化
- 缺失值
- 类别型数据:one-hot编码
- 时间类型:时间的切分
sklearn特征处理API:sklearn. preprocessing
归一化:
- 特点:通过对原始数据进行变换把数据映射到(默认为[0,1])之间
- sklearn归一化API: sklearn.preprocessing.MinMaxScaler
- MinMaxScaler语法
- MinMaxScalar(feature_range=(0,1)…)
- 每个特征缩放到给定范围(默认[0,1])
- MinMaxScalar.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后的形状相同的array
- MinMaxScalar(feature_range=(0,1)…)
from sklearn.preprocessing import MinMaxScaler
mm = MinMaxScaler(feature_range=(0, 1))
data = mm.fit_transform([[90,2,10,40],[60,4,15,45],[75,3,13,46]])
print(data)
[[1. 0. 0. 0. ]
[0. 1. 1. 0.83333333]
[0.5 0.5 0.6 1. ]]
目的是让某一特征对最终结果不会造成太大影响
但是注意:在特定场景下最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性较差,只适合传统精确小数据场景。
标准化(使用最常见)
- 特点:通过对原始数据进行变换把数据变换到均值为0,方差为1范围内
- 对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小。
- sklearn特征化API: scikit-learn.preprocessing.StandardScaler
- StandardScaler语法
- StandardScaler(…)
- 处理之后每列来说所有数据都聚集在均值0附近方差为1
- StandardScaler.fit_transform(X,y)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后的形状相同的array
- StandardScaler.mean_
- 原始数据中每列特征的平均值
- StandardScaler.std_
- 原始数据每列特征的方差
- StandardScaler(…)
from sklearn.preprocessing import StandardScaler
std = StandardScaler()
data = std.fit_transform([[ 1., -1., 3.],[ 2., 4., 2.],[ 4., 6., -1.]])
print(data)
[[-1.06904497 -1.35873244 0.98058068]
[-0.26726124 0.33968311 0.39223227]
[ 1.33630621 1.01904933 -1.37281295]]
在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。
缺失值处理
- 缺失值处理方法
删除 | 插补 |
---|---|
如果每列或者行数据缺失值达到一定的比例,建议放弃整行或者整列 | 可以通过缺失值每行或者每列的平均值、中位数来填充 |
- sklearn缺失值API: sklearn.preprocessing.Imputer
- Imputer语法
- Imputer(missing_values=‘NaN’, strategy=‘mean’, axis=0)
- 完成缺失值插补
- Imputer.fit_transform(X,y)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后的形状相同的array
- Imputer(missing_values=‘NaN’, strategy=‘mean’, axis=0)
panda处理:
- dropna
- fillna
- replace("?",np.nan)
from sklearn.preprocessing import Imputer
import numpy as np
im = Imputer(missing_values='NaN', strategy='mean', axis=0)
data = im.fit_transform([[1, 2], [np.nan, 3], [7, 6]])
print(data)
[[1. 2.]
[4. 3.]
[7. 6.]]
1、 numpy的数组中可以使用np.nan/np.NaN来代替缺失值,属于float类型
2、如果是文件中的一些缺失值,可以替换成nan,通过np.array转化成float
型的数组即可
数据降温
特征选择
-
特征选择原因
- 冗余:部分特征的相关度高,容易消耗计算性能
- 噪声:部分特征对预测结果有负影响
-
特征选择就是单纯地从提取到的所有特征中选择部分特征作为训练集特征,特征在选择前和选择后可以改变值、也不改变值,但是选择后的特征维数肯定比选择前小,毕竟我们只选择了其中的一部分特征。
-
主要方法(三大武器):
- Filter(过滤式):VarianceThreshold
- Embedded(嵌入式):正则化、决策树
- Wrapper(包裹式)
-
sklearn特征选择API:sklearn.feature_selection.VarianceThreshold
-
VarianceThreshold语法
- VarianceThreshold(threshold = 0.0)
- 删除所有低方差特征
- Variance.fit_transform(X,y)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:训练集差异低于threshold的特征将被删除。
- 默认值是保留所有非零方差特征,即删除所有样本
- 中具有相同值的特征。
- VarianceThreshold(threshold = 0.0)
from sklearn.feature_selection import VarianceThreshold
var = VarianceThreshold(threshold=0.0)
data = var.fit_transform([[0, 2, 0, 3],
[0, 1, 4, 3],
[0, 1, 1, 3]])
print(data)
[[2 0]
[1 4]
[1 1]]
其他特征选择方法:神经网络
PCA(主成分分析)—特征数量达到上百的时候
- 本质:PCA是一种分析、简化数据集的技术
- 目的:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。
- 作用:可以削减回归分析或者聚类分析中特征的数量
- 特点:考虑数据的简化
- 高维度数据容易出现的问题: 特征之间通常是线性相关的
- PCA语法
- PCA(n_components=None)
- n_components:小数表示百分比,整数表示减少的特征数量
- 将数据分解为较低维数空间
- PCA.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后指定维度的array
- PCA(n_components=None)
from sklearn.decomposition import PCA
pca = PCA(n_components=0.9)
data = pca.fit_transform([[2,8,4,5],[6,3,0,8],[5,4,9,1]])
print(data)
[[ 1.22879107e-15 3.82970843e+00]
[ 5.74456265e+00 -1.91485422e+00]
[-5.74456265e+00 -1.91485422e+00]]