您的位置:首页 > 其它

特征工程之特征抽取

2018-02-07 13:57 225 查看
机器学习(Machine Learning, ML)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。它是人工智能的核心,是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域,它主要使用归纳、综合而不是演绎。(本文是个人的笔记,有些内容是引用)

有这么一句话在业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。那特征工程到底是什么呢?顾名思义,其本质是一项工程活动,目的是最大限度地从原始数据中提取特征以供算法和模型使用。说白了特征工程就是将你自己收集到的数据转化为算法需要的数据形式。下图是一个例子



接下来介绍几种比较常见的特征抽取

字典特征抽取(使用sklearn)

字典数据抽取:把字典中一些类别数据,分别进行转换成特征,对于本来就是数值型的数据比如说温度等直接保留,而对于有类别的数据则要先转化为字典数据,sklearn中采用one-hot编码的方式处理。

下面是one-hot编码的举例:

原字典

{'city':'北京','temperature':100},{'city':'上海','temperature':20},{'city':'杭州','temperature':90}

one-hot编码后的字典:

{'city=北京': 1.0, 'temperature': 100.0}, {'city=上海': 1.0, 'temperature': 20.0}, {'city=杭州': 1.0, 'temperature': 90.0}

经过sklearn处理后转化成的数组:



可以清楚的看到city是用类别的,所以说先将city=城市名转化为特征名(一个类别对应一个特征名),接着如果1代表符合特征,0代表不符合。

下面是使用sklearn编写的简单字典数据抽取的代码:

from sklearn.feature_extraction import DictVectorizer

def dictvec():
"""
字典数据抽取
:return: None
"""
#实例化
dict = DictVectorizer()
#调用fit_transform()
data = dict.fit_transform([{'city':'北京','temperature':100},{'city':'上海','temperature':20},{'city':'杭州','temperature':90}])
print('默认返回sparse矩阵')#好处在于节约内存,方便存储
print(data)

#对比
dict1 = DictVectorizer(sparse=False)
data1 = dict1.fit_transform([{'city': '北京', 'temperature': 100}, {'city': '上海', 'temperature': 20}, {'city': '杭州', 'temperature': 90}])
print('原数组')
print(dict1.get_feature_names())#查看特征名称
print(data1)

return None

if __name__ == "__main__":
dictvec()运行结果:



文本特征抽取(使用sklearn库)

CounterVectorizer方法


a、统计所有文章中当前所有的词,重复的字看做一次->词的列表

b、对每一篇文章,在词的列表里面进行统计每个词出现的次数(其中单个字母不统计)

下面是Python代码:

def countvec():
"""
对文本进行特征值化
:return: None
"""
cv = CountVectorizer()

#默认返回sparse矩阵
data = cv.fit_transform(["life is short,i like python is","life is too too long,i dislike python"])

print(cv.get_feature_names())
print(data.toarray())

return None

运行结果:



如果要想处理中文则需要先进行分词处理(这里使用jieba进行分词)

下面是对中文文本进行特征抽取的Python代码:

def cutword():
con1 = jieba.cut("有这么一句话在业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。那特征工程到底是什么呢?顾名思义,其本质是一项工程活动,目的是最大限度地从原始数据中提取特征以供算法和模型使用。")
con2 = jieba.cut("信息冗余:对于某些定量特征,其包含的有效信息为区间划分,例如学习成绩,假若只关心“及格”或不“及格”,那么需要将定量的考分,转换成“1”和“0”表示及格和未及格。二值化可以解决这一问题。")

#转化成列表
content1 = list(con1)
content2 = list(con2)

#把列表转换成字符串
c1 = ' '.join(content1)
c2 = ' '.join(content2)

return c1,c2

def hanzivec():
"""
中文特征值化
:return: None
"""
c1,c2 = cutword()
print(c1,c2)
cv = CountVectorizer()

# 默认返回sparse矩阵
data = cv.fit_transform([c1,c2])

print(cv.get_feature_names())
print(data.toarray())

return None运行结果:



tfidf

在文章分类的应用场景中,只使用词语出现的次数进行特征抽取是没有用的,因为会有很多其他词(例如所以等中性词)

会影响算法对于文本的分析,所以我们需要将其他词汇归于一类。达到下图的效果



TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。具体实现如下:

 Tf:term frequency词的频率

 idf:inverse document frequency:log(总文档数量/该次出现的文档数量)

 词的重要性=tf*idf

 这样可以算出哪些词对于当篇文章的重要性比较大,也就可以实现文章分类的需求

下面是用TF-IDF进行文本特征提取的Python代码:

def tfidfvec():
"""
中文特征值化
:return: None
"""
c1,c2 = cutword()
print(c1,c2)
tf = TfidfVectorizer()

# 默认返回sparse矩阵
data = tf.fit_transform([c1,c2])

print(tf.get_feature_names())
print(data.toarray())

return None下面是运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: