1、42 特征提取 scikitlearn 0194.2. 特征提取模块 sklearn.feature_extraction 可用于提取符合机器学习算法支持的特征,比如文本和图片。Note特征特征提取与 特征选择 有很大的不同:前者包括将任意数据(如文本或图像)转换为可用于机器学习的数值特征。后者是将这些特征应用到机器学习中。4.2.1. 从字典类型加载特征类 DictVectorizer 可用于将标准的Python字典(dict)对象列表的要素数组转换为 scikit-learn 估计器使用的 NumPy/SciPy 表示形式。虽然 Python 的处理速度不是特别快,但 Python 的 d
2、ict 优点是使用方便,稀疏(不需要存储的特征),并且除了值之外还存储特征名称。类 DictVectorizer 实现了 “one-of-K” 或 “one-hot” 编码,用于分类(也称为标称,离散)特征。分类功能是 “属性值” 对,其中该值被限制为不排序的可能性的离散列表(例如主题标识符,对象类型,标签,名称)。在下面的例子,”城市” 是一个分类属性,而 “温度” 是传统的数字特征: measurements=. city:Dubai,temperature:33.,. city:London,temperature:12.,. city:San Francisco,temperature
3、:18.,. fromsklearn.feature_extractionimportDictVectorizer vec=DictVectorizer() vec.fit_transform(measurements).toarray()array( 1., 0., 0., 33., 0., 1., 0., 12., 0., 0., 1., 18.) vec.get_feature_names()city=Dubai, city=London, city=San Francisco, temperature类 DictVectorizer 也是对自然语言处理模型中训练序列分类器的有用的表示变
4、换,通常通过提取围绕感兴趣的特定的词的特征窗口来工作。例如,假设我们具有提取我们想要用作训练序列分类器(例如:块)的互补标签的部分语音(PoS)标签的第一算法。以下 dict 可以是在 “坐在垫子上的猫” 的句子,围绕 “sat” 一词提取的这样一个特征窗口: pos_window=. . word-2:the,. pos-2:DT,. word-1:cat,. pos-1:NN,. word+1:on,. pos+1:PP,. ,. # in a real application one would extract many such dictionaries. 该描述可以被矢量化为适合于呈
5、递分类器的稀疏二维矩阵(可能在被管道 text.TfidfTransformer 进行归一化之后): vec=DictVectorizer() pos_vectorized=vec.fit_transform(pos_window) pos_vectorized1x6 sparse matrix of type with 6 stored elements in Compressed Sparse . format pos_vectorized.toarray()array( 1., 1., 1., 1., 1., 1.) vec.get_feature_names()pos+1=PP, po
6、s-1=NN, pos-2=DT, word+1=on, word-1=cat, word-2=the你可以想象,如果一个文本语料库的每一个单词都提取了这样一个上下文,那么所得的矩阵将会非常宽(许多 one-hot-features),其中大部分通常将会是0。为了使结果数据结构能够适应内存,该类DictVectorizer 的 scipy.sparse 默认使用一个矩阵而不是一个 numpy.ndarray。4.2.2. 特征哈希(相当于一种降维技巧)类 FeatureHasher 是一种高速,低内存消耗的向量化方法,它使用了特征散列 feature hashing _ 技术 ,或可称为 “散
7、列法” (hashing trick)的技术。代替在构建训练中遇到的特征的哈希表,如向量化所做的那样 FeatureHasher 将哈希函数应用于特征,以便直接在样本矩阵中确定它们的列索引。结果是以牺牲可检测性为代价,提高速度和减少内存的使用; 哈希表不记得输入特性是什么样的,没有 inverse_transform 办法。由于散列函数可能导致(不相关)特征之间的冲突,因此使用带符号散列函数,并且散列值的符号确定存储在特征的输出矩阵中的值的符号。这样,碰撞可能会抵消而不是累积错误,并且任何输出要素的值的预期平均值为零。默认情况下,此机制将使用 alternate_sign=True 启用,对于
8、小型哈希表大小(n_features fromsklearn.feature_extraction.textimportCountVectorizer这个模型有很多参数,但参数的默认初始值是相当合理的(请参阅 参考文档 了解详细信息): vectorizer=CountVectorizer() vectorizerCountVectorizer(analyzer=.word, binary=False, decode_error=.strict, dtype=, encoding=.utf-8, input=.content, lowercase=True, max_df=1.0, max_f
9、eatures=None, min_df=1, ngram_range=(1, 1), preprocessor=None, stop_words=None, strip_accents=None, token_pattern=.(?u)bww+b, tokenizer=None, vocabulary=None)我们用它来对简约的文本语料库进行 tokenize(分词)和统计单词出现频数: corpus=. This is the first document.,. This is the second second document.,. And the third one.,. Is t
10、his the first document?,. X=vectorizer.fit_transform(corpus) X4x9 sparse matrix of type with 19 stored elements in Compressed Sparse . format默认配置通过提取至少 2 个字母的单词来对 string 进行分词。做这一步的函数可以显式地被调用: analyze=vectorizer.build_analyzer() analyze(This is a text document to analyze.)=(. this,is,text,document,to
11、,analyze)Trueanalyzer 在拟合过程中找到的每个 term(项)都会被分配一个唯一的整数索引,对应于 resulting matrix(结果矩阵)中的一列。此列的一些说明可以被检索如下: vectorizer.get_feature_names()=(. and,document,first,is,one,. second,the,third,this)True X.toarray()array(0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1
12、, 0, 0, 1, 0, 1.)从 feature 名称到 column index(列索引) 的逆映射存储在 vocabulary_ 属性中: vectorizer.vocabulary_.get(document)1因此,在未来对 transform 方法的调用中,在 training corpus (训练语料库)中没有看到的单词将被完全忽略: vectorizer.transform(Something completely new.).toarray(). array(0, 0, 0, 0, 0, 0, 0, 0, 0.)请注意,在前面的 corpus(语料库)中,第一个和最后一个文
13、档具有完全相同的词,因为被编码成相同的向量。特别是我们丢失了最后一个文件是一个疑问的形式的信息。为了防止词组顺序颠倒,除了提取一元模型 1-grams(个别词)之外,我们还可以提取 2-grams 的单词: bigram_vectorizer=CountVectorizer(ngram_range=(1,2),. token_pattern=rbw+b,min_df=1) analyze=bigram_vectorizer.build_analyzer() analyze(Bi-grams are cool!)=(. bi,grams,are,cool,bi grams,grams are,a
14、re cool)True由 vectorizer(向量化器)提取的 vocabulary(词汇)因此会变得更大,同时可以在定位模式时消除歧义: X_2=bigram_vectorizer.fit_transform(corpus).toarray() X_2. array(0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1
15、, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1.)特别是 “Is this” 的疑问形式只出现在最后一个文档中: feature_index=bigram_vectorizer.vocabulary_.get(is this) X_2:,feature_indexarray(0, 0, 0, 1.)4.2.3.4. Tfidf 项加权在一个大的文本语料库中,一些单词将出现很多次(例如 “the”, “a”, “is” 是英文),因此对文档的实际内容没有什么有意义的信息
16、。如果我们将直接计数数据直接提供给分类器,那么这些频繁词组会掩盖住那些我们关注但很少出现的词。为了为了重新计算特征权重,并将其转化为适合分类器使用的浮点值,因此使用 tf-idf 变换是非常常见的。Tf表示*术语频率*,而 tf-idf 表示术语频率乘以*转制文档频率*:.使用 TfidfTransformer 的默认设置,TfidfTransformer(norm=l2,use_idf=True,smooth_idf=True,sublinear_tf=False) 术语频率,一个术语在给定文档中出现的次数乘以 idf 组件, 计算为,其中 是文档的总数, 是包含术语 的文档数。然后,所得到
17、的 tf-idf 向量通过欧几里得范数归一化:.它源于一个词权重的信息检索方式(作为搜索引擎结果的评级函数),同时也在文档分类和聚类中表现良好。以下部分包含进一步说明和示例,说明如何精确计算 tf-idfs 以及如何在 scikit-learn 中计算 tf-idfs, TfidfTransformer 并 TfidfVectorizer 与定义 idf 的标准教科书符号略有不同在 TfidfTransformer 和 TfidfVectorizer 中 smooth_idf=False,将 “1” 计数添加到 idf 而不是 idf 的分母:该归一化由类 TfidfTransformer 实
18、现: fromsklearn.feature_extraction.textimportTfidfTransformer transformer=TfidfTransformer(smooth_idf=False) transformerTfidfTransformer(norm=.l2, smooth_idf=False, sublinear_tf=False, use_idf=True)有关所有参数的详细信息,请参阅 参考文档。让我们以下方的词频为例。第一个次在任何时间都是100出现,因此不是很有重要。另外两个特征只占不到50的比例,因此可能更具有代表性: counts=3,0,1,. 2
19、,0,0,. 3,0,0,. 4,0,0,. 3,2,0,. 3,0,2. tfidf=transformer.fit_transform(counts) tfidf6x3 sparse matrix of type with 9 stored elements in Compressed Sparse . format tfidf.toarray()array( 0.81940995, 0. , 0.57320793, 1. , 0. , 0. , 1. , 0. , 0. , 1. , 0. , 0. , 0.47330339, 0.88089948, 0. , 0.58149261, 0
20、. , 0.81355169)每行都被正则化,使其适应欧几里得标准:例如,我们可以计算计数数组中第一个文档中第一个项的 tf-idf ,如下所示:现在,如果我们对文档中剩下的2个术语重复这个计算,我们得到:和原始 tf-idfs 的向量:然后,应用欧几里德(L2)规范,我们获得文档1的以下 tf-idfs:此外,默认参数 smooth_idf=True 将 “1” 添加到分子和分母,就好像一个额外的文档被看到一样包含集合中的每个术语,这样可以避免零分割:使用此修改,文档1中第三项的 tf-idf 更改为 1.8473:而 L2 标准化的 tf-idf 变为: transformer=Tfidf
21、Transformer() transformer.fit_transform(counts).toarray()array( 0.85151335, 0. , 0.52433293, 1. , 0. , 0. , 1. , 0. , 0. , 1. , 0. , 0. , 0.55422893, 0.83236428, 0. , 0.63035731, 0. , 0.77630514)通过 拟合 方法调用计算的每个特征的权重存储在模型属性中: transformer.idf_array( 1. ., 2.25., 1.84.)由于 tf-idf 经常用于文本特征,所以还有一个类 TfidfVectorizer ,它将 CountVectorizer和 TfidfTransformer 的所有选项组合在一个单例模型中: fromsklearn.feature_extraction
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1