特征抽取:特征字典向量化和特征哈希变换

sklearn.feature_extaction模块提供了从原始数据如文本,图像等中抽取能够被机器学习算法直接处理的特征向量。

Feature extraction和Feature selection是不同的:前者将任意的数据变换成机器学习算法可用的数值型特征;后者是一个作用于特征空间上的机器学习技术,是对特征空间的再次变换。

image
  • Loading Features From Dicts
  • Features hashing
  • Text Feature Extraction
  • Image Feature Extraction

Loading Features From Dicts

DictVectorizer类可以用来把标准Python dict对象表示的特征数组转换成Numpy/Scipy的表示形式,以便于scikit-learn estimators的使用。

尽管速度不是很快,Python的dict使用起来还是相当方便的,而且还可以稀疏存储(absent feature need not be stored);字典的形式便于将特征的取值和名称一一对应起来。

DictVectorizer实现了one-of-K或者叫“one-hot”编码对标称型特征。标称型特征(Categorical feature)是“attribute-value”pairs,其中value是属性的可能的取值列表,必须是有限的离散的没有大小顺序的。(e.g 男女,话题类别)

下面的例子中,‘city’是一个categorical attribute而‘temperature’是一个典型的numerical feature。

measurements = [
    {'city': 'Dubai', 'temperature': 33.0},
    {'city': 'London', 'temperature': 12.0},
    {'city': 'San Fransisco', 'temperature': 18.0},
]

from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer()

print(vec.fit_transform(measurements).toarray())
print(vec.get_feature_names())
image

Features hashing

Features hashing是一个高速的,低存储的向量化的类。
一般的vectorizer是为训练过程中遇到的特征构建一个hash table,而FeatureHasher类则直接对特征应用一个hash函数来决定特征在样本矩阵中的列索引。这样的做法使得计算速度提升并且节省了内存,the hasher无法记住输入特征的样子,而且不逊在你想变换操作:inverse_transform。

因为哈希函数可能会导致本来不相关的特征之间发生冲突,所以使用了有符号的hash函数。对一个特征,其hash值的符号决定了被存储到输出矩阵中的值的符号。通过这种方式就能够消除特征hash映射时发生的冲突而不是累计冲突。而且任意输出的值的期望均值是0.

如果non_negative=True被传入构造函数,将会取绝对值。这样会发生一些冲突(collision)但是哈希特征映射的输出就可以被传入到一些只能接受非负特征的学习器对象比如:
sklearn.naive_bayes.MultinomialNB分类器和sklearn.feature_selection.chi2特征选择器。

Features hashing接受参数类型可以使:mappings(字典或者其变体容器)或者(feature,value)对,或者strings。这取决于构造器参数:input_type。

Mapping被看做是由(feature,value)构成的一个列表,而单个字符串隐式的等于1,所以['feat1', 'feat2', 'feat3']被解释成(feature,value)的列表:[('feat1', 1), ('feat2',2), ('feat3', 3)]。 如果一个特征在一个样本中出现了多次,相关联的值就会累加起来:(比如('feat', 2)和('feat', 3.5)会累计起来成为('feat', 5.5))。

FeatureHasher的输出通常是CSR格式的scipy.sparse matrix。

Feature hashing 可被用于文档分类中去,但是与text.CountVectorizer不同,FeatureHasher不做单词切分或其他的预处理操作,除了Unicode-to-UTF-8编码以外。

Text Feature Extraction

  • The Bag of Words represention 词袋模型
  • Sparsity
  • Common Vectorizer usage
  • TF-idf term weighting
  • Decoding text files
  • Limitations of the Bag of Words represention 词袋模型的局限性
  • Vertorizing a large text corpus with the hashing trick
  • Performing out-of-core scaling with HashingVectorizer
  • Customizing the vectorizer classes

The Bag of Words represention

文本分析是机器学习领域的重要应用。然而文本数据是由一系列符号构成的,
无法直接被计算机以及机器学习算法处理。绝大多数机器学习算法都是建立在
数值特征空间上,而且特征向量的长度也是固定的,但是文本的长度却
千差万别。

为了解决这一问题,sklearn提供了最通用的工具来从文本内容中抽取
数值型特征,这些工具如下:

  1. 标记字符串,为每一个可能的标记分配一个整型id,
    如使用white-spaces和punctuation作为token。
  2. 统计每个文档中各个token的出现次数。
  3. 归一化(Normalizing)和加权(Weighting)。

在这样的机制下,特征和样本如下定义:
每个token出现的频率被当做一个特征。
给定文本中所有token的频率组成的向量被当做多维样本。

Sparsity

绝大多数的文档都只使用了一个词汇子集,与整个语料的词汇集合相比起来,是非常小的。所以最终的特征向量矩阵中有很多的特征取值是0(通常是99%)。

例如: 对于一个有10000个短文本的集合来来说,它可能包含的所有的独立的词汇量是100000个,但是其中的任意一个独立的文档可能只有100到1000个词汇量。

为了存储这样的稀疏矩阵而且不影响矩阵/向量的运算速度,特征向量矩阵通常会使用稀疏矩阵来存储。

Common Vectorizer usage

from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(min_df=1)
print(vectorizer)
corpus = [
    'This is the first documents.',
    'This is the second documents.',
    'And the third document.',
    'Is this the first documents?',
]

X = vectorizer.fit_transform(corpus)
print(X)
image

在默认的设置中,提取的字符串长度至少要有两个字符,低于两个字符的会被忽略,比如'a'

analyze = vectorizer.build_analyzer()
analyze('This is a text document to analyze.') == (['this', 'is', 'text', 'document', 'to', 'analyze'])
image

在fit阶段被analyser发现的每一个词语(term)都会被分配一个独特的整数索引(unique interger index), 该索引对应于特征向量矩阵中的一列,全部小写化。

image

使用下面的方法获取某一个词语在矩阵中的第几列。

image

因此,在训练语料中没有见到过的单词将会被未来的转换方法完全忽略。

image

注意到前面的语料库中,第一个和最后一个句子中单词是一模一样的,只是顺序是不一样的。他们会被编码成相同的特征向量,所以词袋表示法丢失了单词顺序的前后相关性信息。为了保持某些局部的顺序性信息,我们可以抽取2-grams of words和1-grams(individual words)。

bigram_vectorizer = CountVectorizer(ngram_range=(1,2), 
                                    token_pattern=r'\b\w+\b', min_df=1)
analyze = bigram_vectorizer.build_analyzer()
analyze('Bi-grams are cool!') == (['bi', 'grams', 'are', 'cool', 'bi grams', 'grams are', 'are cool'])
image

这时候,vectorizer抽取的词汇表就会更大,而且可以解析编码在局部位置模式里面的模糊性和歧义性。

X_2 = bigram_vectorizer.fit_transform(corpus).toarray()
X_2
image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容