前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >特征提取之 DictVectorizer

特征提取之 DictVectorizer

作者头像
不可言诉的深渊
发布2020-02-17 15:45:47
1.7K0
发布2020-02-17 15:45:47
举报

特征提取是计算机视觉和图像处理中的一个概念。它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征。特征提取的结果是把图像上的点分为不同的子集,这些子集往往属于孤立的点、连续的曲线或者连续的区域。用 Python 进行特征提取的方法有很多,这里我使用 sklearn.feature_extraction.DictVectorizer 这个类来进行特征提取,毕竟新版本的 scikit-learn 在使用这个类的时候会遇到一些问题,在讲怎么用它进行特征提取的同时顺便把这些问题解决了。

检查版本

首先需要检查 scikit-learn 的版本,我的版本是 0.21.3,如图所示。

检查完版本之后就是讲解怎么使用 DictVectorizer 进行特征提取。

用 DictVectorizer 进行特征提取

虽然在开头我解释了特征提取主要用于提取图像数据的特征,但是提取其他类型数据的特征也是时常会有的。今天讲的 DictVectorizer 主要是用来提取字典数据的特征,当然也可以提取 DataFrame 格式的数据的特征(老版本 scikit-learn 里面的 DictVectorizer 应该或许可以直接用来提取 DataFrame 格式的数据的特征,毕竟我没用过老版本的这个类,但是我敢确定的是新版本需要做一些变换)。

首先跟着老版本的模式先来一波,代码如下:

from random import random
from pandas import DataFrame
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
df = DataFrame({'X1': [random()for _ in range(100)], 'X2': [random()for _ in range(100)]})
X_train, X_test = train_test_split(df, random_state=0)
dv = DictVectorizer().fit_transform(X_train)
print(dv)

在这里首先我是构造了一个随机生成 100 条数据的数据集,其中每个数据点有两个特征 X1 和 X2,没有目标值,毕竟特征提取和数据转换属于无监督学习的范畴。然后必然是拆分训练集与测试集,接着用 DictVectorizer 对象的 fit_transform 方法对训练集进行训练并转换,最后把转换后的东西做一个输出,这段代码逻辑就是如此,并没有特别复杂。知道了代码逻辑之后就要运行代码了,运行结果如图所示。

发现报错,而且这个错误非常莫名其妙,光看报错完全不知道问题出在哪里。看不出错误没关系,我们可以去看看 scikit-learn 的文档,或许是新版本的 scikit-learn 把 DictVectorizer 这个类的使用方法给改掉了,在文档中我们可以发现这么一个使用 DictVectorizer 的小例子,如图所示。

我们发现 fit_transform 方法里面传入的是一个字典列表格式的数据,而不是其他格式的数据。这个字典列表格式的数据看起来很简单,就是一个列表,其中的每个元素是一个字典,字典键对应着特征名,字典值对应着特征值。DataFrame 格式的数据是一个表格,表格中每一行对应着一条数据,有多少行就有多少条数据,每一列对应着一个特征,有多少列就有多少个特征。知道了这些把 DataFrame 格式的数据转换成字典列表格式的数据就是轻而易举的事情了,直接上代码,如下所示:

from random import random
from pandas import DataFrame
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
df = DataFrame({'X1': [random()for _ in range(100)], 'X2': [random()for _ in range(100)]})
X_train, X_test = train_test_split(df, random_state=0)
X_train = [{'X1': X_train['X1'][i], 'X2': X_train['X2'][i]}for i in range(75)]
dv = DictVectorizer().fit_transform(X_train)
print(dv)

一行代码就完成了数据格式的转换,这行代码没什么难的,就是一个列表推导式。在这里重点解释一下 75 这个数字,75 意味着 X_train 里面有 75 条数据(同时也暗示了 X_test 里面有 25 条数据),至于为什么是 75 只要记得是 train_test_split 这个函数里面默认规定的就行了。接下来还是运行一下看看,运行结果如图所示。

还是报错,更加莫名其妙,同样也是看不出错在了哪里,我们把那个列表推导式写完整一些,每次循环的时候顺便打印循环变量 i 的值,代码如下:

from random import random
from pandas import DataFrame
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
df = DataFrame({'X1': [random()for _ in range(100)], 'X2': [random()for _ in range(100)]})
X_train, X_test = train_test_split(df, random_state=0)
li = []
for i in range(75):
    print(i)
    li.append({'X1': X_train['X1'][i], 'X2': X_train['X2'][i]})
dv = DictVectorizer().fit_transform(X_train)
print(dv)

运行结果如图所示。

确实发现循环变量 i 一旦变成 2 就会出错,我目前敢肯定我的方向是对的,就是数据格式需要做转换,但是这里肯定有一些细节我没注意。我首先猜测问题出在 X_train,先打印一下 X_train 看看,代码如下:

from random import random
from pandas import DataFrame
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
df = DataFrame({'X1': [random()for _ in range(100)], 'X2': [random()for _ in range(100)]})
X_train, X_test = train_test_split(df, random_state=0)
print(X_train)
li = []
for i in range(75):
    print(i)
    li.append({'X1': X_train['X1'][i], 'X2': X_train['X2'][i]})
dv = DictVectorizer().fit_transform(X_train)
print(dv)

运行结果如图所示。

我们可以发现 X_train 最左边有一列是一列无序的整数,这一列是索引列,索引无序并且有大于 75 的数,这说明了在 train_test_split 里面进行训练集测试集分离的过程中是带着原来的索引进行分离,分离之后并不会对索引进行更新,既然如此只需要对索引进行迭代就行了,代码如下:

from random import random
from pandas import DataFrame
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
df = DataFrame({'X1': [random()for _ in range(100)], 'X2': [random()for _ in range(100)]})
X_train, X_test = train_test_split(df, random_state=0)
X_train = [{'X1': X_train['X1'][i], 'X2': X_train['X2'][i]}for i in X_train.index]
dv = DictVectorizer().fit_transform(X_train)
print(dv)

运行结果如图所示。

确实没有报错了,输出结果看看就好,毕竟我瞎构造的数据没有一点实际意义

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档