04机器学习——特征工程之特征抽取
每一条数据都被称为样本,目标值为房价,所以就需要收集会影响目标值的特征数据进行预测
数据中对特征的处理
特征工程其实就是对一个个的特征进行处理
数据的特征工程
1.特征工程是什么
目的其实就是为了提高预测的效果
2.特征工程的意义
·直接影响预测结果
3.scikit-learn库介绍
PS:安装教程见上一篇博客
里面包含了很多的算法
4.数据的特征抽取
(1)特征抽取实例演示
#特征抽取
#导入包
from sklearn.feature_extraction.text import CountVectorizer
#实例化CountVectorizer
vector=CountVectorizer()
#调用fit_transform输入并转换数据
res=vector.fit_transform(['life is short,i like python','life is too long,i dislike python'])
#打印结果
print(vector.get_feature_names())
print(res)
将文本或字符串转化为数字输出:
[‘dislike’, ‘is’, ‘life’, ‘like’, ‘long’, ‘python’, ‘short’, ‘too’]
(0, 2) 1
(0, 1) 1
(0, 6) 1
(0, 3) 1
(0, 5) 1
(1, 2) 1
(1, 1) 1
(1, 5) 1
(1, 7) 1
(1, 4) 1
(1, 0) 1
通过演示得出结论:
特征抽取对文本等数据进行特征值化
注:特征值化是为了计算机更好的去理解数据
(2)sklearn特征抽取API
sklearn.feature_extraction
(3)字典特征抽取
作用:对字典数据进行特征值化
类:sklearn.feature_extraction.DictVectorizer
流程
from sklearn.feature_extraction import DictVectorizer
def dictvec():
"""字典数据抽取
:return:None
"""
#实例化
dict=DictVectorizer()
# 调用fit_transform
data=dict.fit_transform([{'city':'北京','temperature':100},{'city':'上海','temperature':60},{'city':'深圳','temperature':30}])
print(data)
if __name__=="__main__":
dictvec()
输出:
(0, 1) 1.0
(0, 3) 100.0
(1, 0) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0
sparse矩阵格式,前面的两个数字是下标
这样的好处是:节约内存,方便读取数据
实例化时默认sparse=True
把sparse改为False:
from sklearn.feature_extraction import DictVectorizer
def dictvec():
"""字典数据抽取
:return:None
"""
#实例化
dict=DictVectorizer(sparse=False)
# 调用fit_transform
data=dict.fit_transform([{'city':'北京','temperature':100},{'city':'上海','temperature':60},{'city':'深圳','temperature':30}])
print(data)
if __name__=="__main__":
dictvec()
输出结果:
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
ndarray的形式 二维数组
第0行第一个位置是1.0,第0行第三个位置是100.0,没有值的默认为0
数据的意义:
get_feature_names()
from sklearn.feature_extraction import DictVectorizer
def dictvec():
"""字典数据抽取
:return:None
"""
#实例化
dict=DictVectorizer(sparse=False)
# 调用fit_transform
data=dict.fit_transform([{'city':'北京','temperature':100},{'city':'上海','temperature':60},{'city':'深圳','temperature':30}])
print(dict.get_feature_names())
print(data)
if __name__=="__main__":
dictvec()
结果:
[‘city=上海’, ‘city=北京’, ‘city=深圳’, ‘temperature’]
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
city=上海,值为1,不是就为0
字典数据抽取:把字典中一些类别数据,分别进行转换成特征
数组形式:有类别的这些特征先要转换字典数据
如果有很多种类别,比如几千上百个,就把用得到的进行转换,用不到的就不用转换了
我们把这些数据成为one-hot编码
某个样本属于哪个类别,就在相应的位置把它标记为1,不属于则标记为0
利于我们进行机器学习的分析和算法的编码
(4)文本特征抽取
作用:对文本数据进行特征值化
类:sklearn.feature_extraction.text.CountVectorizer
流程
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
"""
对文本进行特征值化
:return:None
"""
cv=CountVectorizer()
data=cv.fit_transform(['life is short,i like python','life is too long,i dislike python'])
print(data)
return None
if __name__=="__main__":
countvec()
结果:
toarray()
把一个sparse矩阵转换为二维数组的形式
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
"""
对文本进行特征值化
:return:None
"""
cv=CountVectorizer()
data=cv.fit_transform(['life is short,i like python','life is too long,i dislike python'])
print(data.toarray())
return None
if __name__=="__main__":
countvec()
结果:
get_feature_names()
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
"""
对文本进行特征值化
:return:None
"""
cv=CountVectorizer()
data=cv.fit_transform(['life is short,i like python','life is too long,i dislike python'])
print(cv.get_feature_names())
print(data.toarray())
return None
if __name__=="__main__":
countvec()
结果:
1.统计所有文章当中所有的词,重复的只看做一次——词的列表
2.对每篇文章,在词的列表里面进行统计每个词出现的次数
如:dislike没有在第一篇文章里出现,所以值为0
注意:单个字母不进行统计,因为一个字母并不能反应一篇文章的主题或反应这篇文章讲了什么
文本特征抽取的应用场景:文本分类、情感分析等
中文文本怎么办?
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
"""
对文本进行特征值化
:return:None
"""
cv=CountVectorizer()
data=cv.fit_transform(['人生苦短,我喜欢python','人生漫长,不用python'])
print(cv.get_feature_names())
print(data.toarray())
return None
if __name__=="__main__":
countvec()
结果:
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
"""
对文本进行特征值化
:return:None
"""
cv=CountVectorizer()
data=cv.fit_transform(['人生 苦短,我 喜欢 python','人生 漫长,不用 python'])
print(cv.get_feature_names())
print(data.toarray())
return None
if __name__=="__main__":
countvec()
结果:
这只是通过符号(逗号、空格等)来进行分割文本
因为英文是以空格分开所以不用进行分词处理,但是中文需要
需要对中文文本先进行分词
PS:jieba下载安装教程见下一篇
案例:对以下三段话进行特征值化
from sklearn.feature_extraction.text import CountVectorizer
import jieba
def cutword():
con1=jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2=jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看的宇宙时,我们是在看它的过去。")
con3=jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它,了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系")
# con1 con2 con3 :<generator object Tokenizer.cut at 0x000001DB4CB15570>
#转换成列表
content1 = list(con1)# ['今天', '很', '残酷', ',', '明天', '更', '残酷', ',', '后天', '很', '美好', ',', '但', '绝对', '大部分', ...]
content2 = list(con2)
content3 = list(con3)
#把列表转换成字符串
c1=' '.join(content1)# 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。
c2=' '.join(content2)
c3=' '.join(content3)
return c1,c2,c3
def hanzivec():
"""
中文特征值化
:return: None
"""
c1,c2,c3=cutword()
print(c1,c2,c3)# 打印分词结果
cv = CountVectorizer()
data = cv.fit_transform([c1,c2,c3])
print(cv.get_feature_names())
print(data.toarray())
return None
if __name__=="__main__":
hanzivec()
结果:
今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。 我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看 的 宇宙 时 , 我们 是 在 看 它 的 过去 。 如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 , 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系
[‘一种’, ‘不会’, ‘不要’, ‘之前’, ‘了解’, ‘事物’, ‘今天’, ‘光是在’, ‘几百万年’, ‘发出’, ‘取决于’, ‘只用’, ‘后天’, ‘含义’, ‘大部分’, ‘如何’, ‘如果’, ‘宇宙’, ‘我们’, ‘所以’, ‘放弃’, ‘方式’, ‘明天’, ‘星系’, ‘晚上’, ‘某样’, ‘残酷’, ‘每个’, ‘看到’, ‘真正’, ‘秘密’, ‘绝对’, ‘美好’, ‘联系’, ‘过去’, ‘这样’]
[[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 1 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比前面的count的方法要更好一点
tf:term frequency词的频率 出现的次数
idf:inverse document frequency逆文档频率 log(总文档数量/该词出现的文档数量)
如:“所以”这个词在很多文章中都有出现,那么该词出现的文档数量就大,根据公式得到的值就小
tf*idf ——重要性程度,根据这个重要性程度就可以得到每篇文章中哪些词是重要的
from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer
import jieba
def cutword():
con1=jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2=jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看的宇宙时,我们是在看它的过去。")
con3=jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它,了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系")
#转换成列表
content1 = list(con1)
content2 = list(con2)
content3 = list(con3)
#把列表转换成字符串
c1=' '.join(content1)
c2=' '.join(content2)
c3=' '.join(content3)
return c1,c2,c3
def tfidfvec():
"""
中文特征值化
:return: None
"""
c1,c2,c3=cutword()
print(c1,c2,c3)#打印分词结果
tf = TfidfVectorizer()
data = tf.fit_transform([c1,c2,c3])
print(tf.get_feature_names())
print(data.toarray())
return None
if __name__=="__main__":
tfidfvec()
结果:
为什么需要TfidfVectorize?
分类机器学习算法的重要依据