python之sklearn-特征工程-1.2 特征抽取

本文将介绍 什么是特征提取、字典特征提取、"one-hot"编码、文本特征提取、jieba分词、Tf-idf文本特征提取

一,特征提取

目的:对特征当中有类别的信息做处理—>one-hot 编码

1,目的:

包括将任意数据(如文本或图像)转换为可用于机器学习的数字特征。

注:特征值化是为了计算机更好的去理解数据

2,特征提取类别:
  • 字典特征提取(特征离散化)
  • 文本特征提取
  • 图像特征提取(深度学习将介绍)
3,特征提取API
sklearn.feature_extraction

二,字典特征提取

1,字典特征提取api介绍

作用:对字典数据进行特征值化

  • sklearn.feature_extraction.DictVectorizer(sparse=True,…)
    • DictVectorizer.fit_transform(X) X:字典或者包含字典的迭代器返回值:返回sparse矩阵
    • DictVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式
    • DictVectorizer.get_feature_names() 返回类别名称
2,提取效果

我们对以下数据进行特征提取

datas = [{'city': '北京','temperature':100},
{'city': '上海','temperature':60},
{'city': '深圳','temperature':30}]
3,实例
  • 实例化类DictVectorizer
  • 调用fit_transform方法输入数据并转换(注意返回格式)
from sklearn.feature_extraction import DictVectorizer

d = [{'city': '北京','temperature':100},
{'city': '上海','temperature':60},
{'city': '深圳','temperature':30}]

def dictves():
    '''字典数据提取'''
     # sparse参数如果为True(默认),返回sparse矩阵---节约存储空间
    # sparse参数如果等于False则返回ndarray数组类型(one hot类型)
    dict = DictVectorizer(sparse=False)

    # fit_transform 返回sparse矩阵/ndarray数组(one hot类型)
    data = dict.fit_transform(d)

    # 返回类别名称
    name = dict.get_feature_names()

    # 将标准化的数据还原为原始数据
    d1 = dict.inverse_transform(data)

    print(name)
    print(data)
    print(d1)
if __name__ == '__main__':
    dictves()

# ---output---------------------
['city=上海', 'city=北京', 'city=深圳', 'temperature']
[[  0.   1.   0. 100.]
 [  1.   0.   0.  60.]
 [  0.   0.   1.  30.]]
[{'city=北京': 1.0, 'temperature': 100.0}, {'city=上海': 1.0, 'temperature': 60.0}, {'city=深圳': 1.0, 'temperature': 30.0}]
4,什么是"one-hot"编码

类似于pandas离散化,我们把这个处理数据的技巧用专业的称呼"one-hot"编码,是分析数据的一种手段。对于特征当中存在类别信息的我们都会做one-hot编码处理。
例如:
在这里插入图片描述
在这里插入图片描述

5,使用one-hot的目的
  • 如果两个特征值相等,用数字表示出来符合机器学习要求
  • 如果特征值用数字代指,可能会导致两个类别特征分大小的误判。

三,文本特征提取

作用:对文本数据进行特征值化

1,文本特征提取api介绍
  • sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
    • 返回词频矩阵
  • CountVectorizer.fit_transform(X) X:文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵
  • CountVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格
  • CountVectorizer.get_feature_names() 返回值:单词列表
  • sklearn.feature_extraction.text.TfidfVectorizer
2,提取效果

我们对以下数据进行特征提取

["life is short,i like python",
"life is too long,i dislike python"]

在这里插入图片描述

3,实例(数据为英文)
  • 实例化类CountVectorizer
  • 调用fit_transform方法输入数据并转换 (注意返回格式,利用toarray()进行sparse矩阵转换array数组)
from sklearn.feature_extraction.text import CountVectorizer

# t1 = 'Life is so short , i like python'
# t2 = 'Life is too log , i dislike python'
t3 = ['Life is so short , i like python','Life is too log , i dislike python']

def dictves():
    '''文本数据提取'''
    cv = CountVectorizer()
    data = cv.fit_transform(t3)
    
    # 默认会过滤到单个字母--对于文章主题没有影响
    print(cv.get_feature_names())
    print(data)
    print(data.toarray())

if __name__ == '__main__':
    dictves()
    
--------------------------------------
['dislike', 'is', 'life', 'like', 'log', 'python', 'short', 'so', 'too']
  (0, 2)	1
  (0, 1)	1
  (0, 7)	1
  (0, 6)	1
  (0, 3)	1
  (0, 5)	1
  (1, 2)	1
  (1, 1)	1
  (1, 5)	1
  (1, 8)	1
  (1, 4)	1
  (1, 0)	1
[[0 1 1 1 0 1 1 1 0]
 [1 1 1 0 1 1 0 0 1]]
4,实例(数据为中文)
"人生苦短,我喜欢Python" "生活太长久,我不喜欢Python"

那么最终得到的结果是

from sklearn.feature_extraction.text import CountVectorizer

t4 = ['人生 苦短,我喜 欢py thon','人生 漫长,我 不用 python']

def dictves():
    '''文本数据提取'''
    # 实例化
    cv = CountVectorizer()
    res = cv.fit_transform(t4)

    # 不支持单个中文
    print(cv.get_feature_names())
    print(res.toarray())

if __name__ == '__main__':
    dictves()
    
-----------------------------------------------------------------------
['python', 'thon', '不用', '人生', '我喜', '欢py', '漫长', '苦短']
[[0 1 0 1 1 1 0 1]
 [1 0 1 1 0 0 1 0]]
5,jieba分词处理
1) jieba分词的api
  • jieba.cut()
    • 返回词语组成的生成器
2) 安装库

需要安装下jieba库

pip3 install jieba
3)效果

对以下三句话进行特征值化
今天很残酷,明天更残酷,后天很美好,
但绝对大部分是死在明天晚上,所以每个人不要放弃今天。

我们看到的从很远星系来的光是在几百万年之前发出的,
这样当我们看到宇宙时,我们是在看它的过去。

如果只用一种方式了解某样事物,你就不会真正了解它。
了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。

  • 分析
    • 准备句子,利用jieba.cut进行分词
    • 实例化CountVectorizer
    • 将分词结果变成字符串当作fit_transform的输入值
      在这里插入图片描述
4)实例
import jieba
from sklearn.feature_extraction.text import CountVectorizer

t1 = '今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。'
t2 = '我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。'
t3 = '如果只用一种方式了解某样事物,你就不会真正了解它。'

def cutword(t1,t2,t3):
    # jieba.cut(t1) 返回的是一个生成器
    t1 = list(jieba.cut(t1))
    t2 = list(jieba.cut(t2))
    t3 = list(jieba.cut(t3))

    t1 = ' '.join(t1)
    t2 = ' '.join(t2)
    t3 = ' '.join(t3)
    return t1,t2,t3

def main():
    # 调用切词函数
    a,b,c = cutword(t1,t2,t3)

    # 实例化; stop_words是不统计该列表中的特征
    cv = CountVectorizer(stop_words=['不要', '我们', '所以'])
    # 返回sparse矩阵
    data = cv.fit_transform([a,b,c])

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

if __name__ == '__main__':
    main()

-------------------------------------------------------
['一种', '不会', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '只用', '后天', '大部分', '如果', '宇宙', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '绝对', '美好', '过去', '这样']
[[0 0 0 0 0 2 0 0 0 0 1 1 0 0 1 0 2 0 1 0 2 1 0 0 1 1 0 0]
 [0 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 2 0 0 0 1 1]
 [1 1 0 2 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0]]
6,Tf-idf文本特征提取

在这里插入图片描述

1)Tf-idf简介
  • TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
  • TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
2)计算公式
  • 词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率
  • 逆向文档频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到
3)eg:

注:假如一篇文件的总词语数是100个,而词语"非常"出现了5次,那么"非常"一词在该文件中的词频就是5/100=0.05。而计算文件频率(IDF)的方法是以文件集的文件总数,除以出现"非常"一词的文件数。所以,如果"非常"一词在1,000份文件出现过,而文件总数是10,000,000份的话,其逆向文件频率就是lg(10,000,000 / 1,0000)=3。最后"非常"对于这篇文档的tf-idf的分数为0.05 * 3=0.15

4)实例
import jieba
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer

t1 = '今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。'
t2 = '我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。'
t3 = '如果只用一种方式了解某样事物,你就不会真正了解它。'

def cutword(t1,t2,t3):
    t1 = list(jieba.cut(t1))
    t2 = list(jieba.cut(t2))
    t3 = list(jieba.cut(t3))

    t1 = ' '.join(t1)
    t2 = ' '.join(t2)
    t3 = ' '.join(t3)
    return t1,t2,t3

def main():
    # 调用切词函数
    a,b,c = cutword(t1,t2,t3)

    # 实例化; stop_words是不统计该列表中的特征
    cv = TfidfVectorizer(stop_words=['不要', '我们', '所以'])
    # 返回sparse矩阵
    data = cv.fit_transform([a,b,c])

	# 1,查看文本特征
    print(cv.get_feature_names())

	# 2,查看词汇表
    print(cv.vocabulary_)
    print(cv.vocabulary_.items())
	
	# 3,查看词-文档矩阵
    print(data.toarray())

if __name__ == '__main__':
    main()
5)Tf-idf的重要性

分类机器学习算法进行文章分类中前期数据处理方式

6)TfidfVectorizer和TfidfTransformer的区别
vectorizer=CountVectorizer()
transformer=TfidfTransformer()
tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))
等价于:
transformer=TfidfVectorizer()
tfidf2=transformer.fit_transform(corpus)

大白话的说,

CountVectorizer(),该类数字频,也就是汉字变数字

TfidfTransformer(),该类变换Tfidf,字频变Tfid这个量

TfidfVectorizer()就把这个两个类合一起了。

猜你喜欢

转载自blog.csdn.net/TFATS/article/details/108144821