字典特征提取、文本特征提取、jieba分词处理、tf-idf文本特征提取概念及代码实现

一、特征提取

特征提取:将任意数据(如文本或图像)转换为可用于机器学习的数字特征,特征值化是为了计算机更好的去理解数据

特征提取api:sklearn.feature_extraction

特征提取分类

  1. 字典特征提取(特征离散化)
  2. 文本特征提取
  3. 图像特征提取

二、字典特征提取

  • sklearn.feature_extraction.DictVectorizer(sparse=True,…):对字典数据进行特征值化
    • DictVectorizer.fit_transform(X):返回sparse矩阵,X为字典或包含字典的迭代器返回值
    • DictVectorizer.get_feature_names_out():返回类别名称
from sklearn.feature_extraction import DictVectorizer
def dict_demo():
    """
    对字典类型的数据进行特征抽取
    :return: None
    """
    data = [{'city': '北京', 'temperature': 100},
            {'city': '上海', 'temperature': 60},
            {'city': '深圳', 'temperature': 30}]
    transfer = DictVectorizer()  # 实例化一个转换器类
    # transfer = DictVectorizer(sparse=False)  # 实例化一个转换器类
    data = transfer.fit_transform(data)  # 调用fit_transform方法输入数据并转换(注意返回格式)
    print("返回的结果:\n", data)
    print("特征名字:", transfer.get_feature_names_out())     # 打印特征名字
    return None
if __name__ == '__main__':
    dict_demo()

输出:
返回的结果:
   (0, 1)	1.0
  (0, 3)	100.0
  (1, 0)	1.0
  (1, 3)	60.0
  (2, 2)	1.0
  (2, 3)	30.0
特征名字: ['city=上海' 'city=北京' 'city=深圳' 'temperature']
-----------------------------
指定sparse=False后的输出:
返回的结果:
 [[  0.   1.   0. 100.]
 [  1.   0.   0.  60.]
 [  0.   0.   1.  30.]]
特征名字: ['city=上海' 'city=北京' 'city=深圳' 'temperature']

one-hot热编码,为每个类别生成一个布尔值,对于特征当中存在类别信息的一般都会做one-hot编码处理

三、文本特征提取

  • sklearn.feature_extraction.text.CountVectorizer(stop_words=[]):对文本数据进行特征值化,返回词频矩阵,stop_words为停用词,即不想统计的词,单个字母和标点符号不做统计

    • CountVectorizer.fit_transform(X):X为文本或包含文本字符串的可迭代对象,返回sparse矩阵
    • CountVectorizer.get_feature_names_out():返回值单词列表
  • sklearn.feature_extraction.text.TfidfVectorizer

应用举例如下

from sklearn.feature_extraction.text import CountVectorizer

def text_count_demo():
    data = ["life is short,i like like python", "life is too long,i dislike python"]
    # 实例化一个转换器类
    # transfer = CountVectorizer(sparse=False) # 注意,没有sparse这个参数
    transfer = CountVectorizer()
    # 调用fit_transform方法输入数据并转换 (注意返回格式,利用toarray()进行sparse矩阵转换array数组)
    transfer_data = transfer.fit_transform(data)
    print('transfer_data值为:\n', transfer_data)
    print("文本特征抽取的结果:\n", transfer_data.toarray())
    print("返回特征名字:\n", transfer.get_feature_names_out())
    return None
if __name__ == '__main__':
    text_count_demo()

输出:
transfer_data值为:
   (0, 2)	1
  (0, 1)	1
  (0, 6)	1
  (0, 3)	2
  (0, 5)	1
  (1, 2)	1
  (1, 1)	1
  (1, 5)	1
  (1, 7)	1
  (1, 4)	1
  (1, 0)	1
文本特征抽取的结果:
 [[0 1 1 2 0 1 1 0]
 [1 1 1 0 1 1 0 1]]
返回特征名字:
 ['dislike' 'is' 'life' 'like' 'long' 'python' 'short' 'too']

--------------------------------中文----------------------------------
将data改为: data = ["人 生 苦短,我喜欢 Python", "人生太长,我不喜欢Python"]
输出如下:
transfer_data值为:
   (0, 4)	1
  (0, 3)	1
  (0, 0)	1
  (1, 1)	1
  (1, 2)	1
文本特征抽取的结果:
 [[1 0 0 1 1]
 [0 1 1 0 0]]
返回特征名字:
 ['python' '人生太长' '我不喜欢python' '我喜欢' '苦短']

由上可知,英文默认以空格分隔来达到分词效果,中文以逗号或空格分隔,且不统计单个中文字符,即不支持中文分词

四、jieba分词处理

安装命令:pip install jieba
  • jieba.cut():返回词语组成的生成器
  • 使用
    • 准备句子,利用jieba.cut进行分词
    • 实例化CountVectorizer
    • 将分词结果变成字符串当作fit_transform的输入值

举例如下

from sklearn.feature_extraction.text import CountVectorizer
import jieba

def cut_words(text):
    result = list(jieba.cut(text))
    print('list(jieba.cut(text))结果为:', result)
    txt = ' '.join(result)
    return txt
def text_count_demo():  # 对中文进行特征提取
    data = ["愿中国青年都能摆脱冷气,只是向上走,不必听自暴自弃者流的话。能做事的做事,能发声的发声。", "有一分热,发一分光,就令萤火一般,也可以在黑暗里发一点光,不必等候炬火。此后如竟没有炬火:我便是唯一的光。"]
    txt_list = []
    for i in data:
        txt_list.append(cut_words(i))
    print('txt_list列表为:', txt_list)
    # 实例化一个转换器类
    # transfer = CountVectorizer(sparse=False) # 注意,没有sparse这个参数
    transfer = CountVectorizer()
    # 调用fit_transform方法输入数据并转换 (注意返回格式,利用toarray()进行sparse矩阵转换array数组)
    transfer_data = transfer.fit_transform(txt_list)
    # print('transfer_data值为:\n', transfer_data)
    print("文本特征抽取的结果:\n", transfer_data.toarray())
    print("返回特征名字:\n", transfer.get_feature_names_out())
    return None
if __name__ == '__main__':
    text_count_demo()

输出:
list(jieba.cut(text))结果为: ['愿', '中国', '青年', '都', '能', '摆脱', '冷气', ',', '只是', '向上', '走', ',', '不必', '听', '自暴自弃', '者', '流', '的话', '。', '能', '做事', '的', '做事', ',', '能', '发声', '的', '发声', '。']
list(jieba.cut(text))结果为: ['有', '一分', '热', ',', '发一分光', ',', '就', '令', '萤火', '一般', ',', '也', '可以', '在', '黑暗', '里发', '一点', '光', ',', '不必', '等候', '炬火', '。', '此后', '如竟', '没有', '炬火', ':', '我', '便是', '唯一', '的', '光', '。']
txt_list列表为: ['愿 中国 青年 都 能 摆脱 冷气 , 只是 向上 走 , 不必 听 自暴自弃 者 流 的话 。 能 做事 的 做事 , 能 发声 的 发声 。', '有 一分 热 , 发一分光 , 就 令 萤火 一般 , 也 可以 在 黑暗 里发 一点 光 , 不必 等候 炬火 。 此后 如竟 没有 炬火 : 我 便是 唯一 的 光 。']
文本特征抽取的结果:
 [[0 0 0 1 1 0 2 1 0 2 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0]
 [1 1 1 1 0 1 0 0 1 0 0 1 0 1 1 0 1 1 2 0 1 0 1 1 0 1]]
返回特征名字:
 ['一分' '一点' '一般' '不必' '中国' '便是' '做事' '冷气' '发一分光' '发声' '只是' '可以' '向上' '唯一'
 '如竟' '摆脱' '此后' '没有' '炬火' '的话' '等候' '自暴自弃' '萤火' '里发' '青年' '黑暗']

五、tf-idf文本特征提取

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

 \operatorname{tfidf}_{\mathrm{i}, \mathrm{j}}=\mathrm{tf}_{\mathrm{i}, \mathrm{j}} \times \operatorname{idf}_{\mathrm{i}}

其得出结果可以理解为重要程度 

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

举例

from sklearn.feature_extraction.text import TfidfVectorizer
import jieba

def cut_words(text):
    result = list(jieba.cut(text))
    print('list(jieba.cut(text))结果为:', result)
    txt = ' '.join(result)
    return txt
def text_count_demo():  # 对中文进行特征提取
    data = ["愿中国青年都能摆脱冷气,只是向上走,不必听自暴自弃者流的话。能做事的做事,能发声的发声。", "有一分热,发一分光,就令萤火一般,也可以在黑暗里发一点光,不必等候炬火。此后如竟没有炬火:我便是唯一的光。"]
    txt_list = []
    for i in data:
        txt_list.append(cut_words(i))
    print('txt_list列表为:', txt_list)
    # 实例化一个转换器类
    transfer = TfidfVectorizer()
    # 调用fit_transform方法输入数据并转换 (注意返回格式,利用toarray()进行sparse矩阵转换array数组)
    transfer_data = transfer.fit_transform(txt_list)
    # print('transfer_data值为:\n', transfer_data)
    print("文本特征抽取的结果百分占比为:\n", transfer_data.toarray())
    print("返回特征名字:\n", transfer.get_feature_names_out())
    return None
if __name__ == '__main__':
    text_count_demo()

输出:
list(jieba.cut(text))结果为: ['愿', '中国', '青年', '都', '能', '摆脱', '冷气', ',', '只是', '向上', '走', ',', '不必', '听', '自暴自弃', '者', '流', '的话', '。', '能', '做事', '的', '做事', ',', '能', '发声', '的', '发声', '。']
list(jieba.cut(text))结果为: ['有', '一分', '热', ',', '发一分光', ',', '就', '令', '萤火', '一般', ',', '也', '可以', '在', '黑暗', '里发', '一点', '光', ',', '不必', '等候', '炬火', '。', '此后', '如竟', '没有', '炬火', ':', '我', '便是', '唯一', '的', '光', '。']
txt_list列表为: ['愿 中国 青年 都 能 摆脱 冷气 , 只是 向上 走 , 不必 听 自暴自弃 者 流 的话 。 能 做事 的 做事 , 能 发声 的 发声 。', '有 一分 热 , 发一分光 , 就 令 萤火 一般 , 也 可以 在 黑暗 里发 一点 光 , 不必 等候 炬火 。 此后 如竟 没有 炬火 : 我 便是 唯一 的 光 。']
文本特征抽取的结果百分占比为:
 [[0.         0.         0.         0.17512809 0.24613641 0.
  0.49227283 0.24613641 0.         0.49227283 0.24613641 0.
  0.24613641 0.         0.         0.24613641 0.         0.
  0.         0.24613641 0.         0.24613641 0.         0.
  0.24613641 0.        ]
 [0.23245605 0.23245605 0.23245605 0.1653944  0.         0.23245605
  0.         0.         0.23245605 0.         0.         0.23245605
  0.         0.23245605 0.23245605 0.         0.23245605 0.23245605
  0.4649121  0.         0.23245605 0.         0.23245605 0.23245605
  0.         0.23245605]]
返回特征名字:
 ['一分' '一点' '一般' '不必' '中国' '便是' '做事' '冷气' '发一分光' '发声' '只是' '可以' '向上' '唯一'
 '如竟' '摆脱' '此后' '没有' '炬火' '的话' '等候' '自暴自弃' '萤火' '里发' '青年' '黑暗']

学习导航:http://xqnav.top

猜你喜欢

转载自blog.csdn.net/qq_43874317/article/details/128565651