基于python实现TF-IDF算法_python tfidf-程序员宅基地

技术标签: 算法  python  tf-idf  自然语言处理  

标签:2021.09.27工作内容
参考资料:TF-IDF算法介绍及实现
声明:本文中大量内容转载至参考资料,仅归纳整理和加入部分个人观点心得,侵删

概念

  1. 定义
    TF-IDF(term frequency-inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术,常用于挖掘文章中的关键词。
  2. 特点:简单高效,用于最开始的文本数据清洗。
  3. TF-IDF
    (1)TF:词频
    可以统计到停用词,并把它们过滤,避免对结果造成影响。
    e.g.:“的”、“了”、“是”等等
    (2)IDF:逆文档频率
    在词的频率相同时,不同词的重要性却不同。IDF会给常见的词较小的权重。
    e.g.:假设“量化”和“系统”的词频相同,则重要性:“量化” > “系统”
  4. 实现方法
    当有TF和IDF后,将其相乘,能够得到一个词的TF-IDF的值。某个词在文章中的TF-IDF越大,那么它在文章中的重要性越高。

算法步骤

  1. 计算词频
    词频 = 某个词在文章中出现的次数 / 文章的总次数
  2. 计算逆文档的频率
    需要一个语料库(corpus)来模拟语言的使用环境。
    逆文档频率 = log(语料库的文档总数 / (包含该词的文档数 + 1))
  3. 计算TF-IDF
    TF-IDF= TF × IDF
    与一个词在文档中出现的次数成正比。
    与该词在整个语言中出现的次数成反比。

优缺点

  1. 优点
    简单高效,容易理解。
  2. 缺点
    (1)词频衡量此的重要性不够全面,有时重要的词出现得不多
    (2)无法体现位置信息=>无法体现该词在上下文中的重要性=>用word2vec算法来支持

python实现TF-IDF算法

  1. 自己构建语料库
    这个例子比较特殊,dataset既是语料库,可是我们要统计核心词的对象。
# -*- coding: utf-8 -*-
from collections import defaultdict
import math
import operator

"""
函数说明:创建数据样本
Returns:
    dataset - 实验样本切分的词条
    classVec - 类别标签向量
"""


def loadDataSet():
    dataset = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],  # 切分的词条
               ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
               ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'my'],
               ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
               ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
               ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0, 1, 0, 1, 0, 1]  # 类别标签向量,1代表好,0代表不好
    return dataset, classVec


"""
函数说明:特征选择TF-IDF算法
Parameters:
     list_words:词列表
Returns:
     dict_feature_select:特征选择词字典
"""
#dataset:文件夹,word_list:某一个文件,word某个词

def feature_select(dataset):
    # 总词频统计
    doc_frequency = defaultdict(int) #记录每个词出现的次数,可以把它理解成一个可变长度的list,只要你索引它,它就自动扩列
    for file in dataset:
        for word in file:
            doc_frequency[word] += 1
    # 计算每个词的TF值
    word_tf = {
    }  # 存储没个词的tf值
    for i in doc_frequency:
        word_tf[i] = doc_frequency[i] / sum(doc_frequency.values()) #sum(doc.frequency.values)

    # 计算每个词的IDF值
    doc_num = len(dataset)
    word_idf = {
    }  # 存储每个词的idf值
    word_doc = defaultdict(int)  # 存储包含该词的文档数
    for word in doc_frequency:
        for file in dataset:
            if word in file:
                word_doc[word] += 1
    #word_doc和doc_frequency的区别是word_doc存储的是包含这个词的文档数,即如果一个文档里有重复出现一个词则word_doc < doc_frequency
    for word in doc_frequency:
        word_idf[word] = math.log(doc_num / (word_doc[word] + 1))

    # 计算每个词的TF*IDF的值
    word_tf_idf = {
    }
    for word in doc_frequency:
        word_tf_idf[word] = word_tf[word] * word_idf[word]

    # 对字典按值由大到小排序
    dict_feature_select = sorted(word_tf_idf.items(), key=operator.itemgetter(1), reverse=True)
    return dict_feature_select


if __name__ == '__main__':
    data_list, label_list = loadDataSet()  # 加载数据
    features = feature_select(data_list)  # 所有词的TF-IDF值
    print(features)

运算结果:
在这里插入图片描述
2. NLTK实现TF-IDF算法
由于我的电脑安装了本地代理所以不能下载nltk的语料库,这里只贴代码供大家参考

from nltk.text import TextCollection
from nltk.tokenize import word_tokenize
 
#首先,构建语料库corpus
sents=['this is sentence one','this is sentence two','this is sentence three']
sents=[word_tokenize(sent) for sent in sents] #对每个句子进行分词
print(sents)  #输出分词后的结果
corpus=TextCollection(sents)  #构建语料库
print(corpus)  #输出语料库
 
#计算语料库中"one"的tf值
tf=corpus.tf('one',corpus)    # 1/12
print(tf)
 
#计算语料库中"one"的idf值
idf=corpus.idf('one')      #log(3/1)
print(idf)
 
#计算语料库中"one"的tf-idf值
tf_idf=corpus.tf_idf('one',corpus)
print(tf_idf)
  1. 利用sklearn做tf-idf
import sklearn
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

x_train = ['TF-IDF 主要 思想 是', '算法 一个 重要 特点 可以 脱离 语料库 背景',
           '如果 一个 网页 被 很多 其他 网页 链接 说明 网页 重要']
x_test = ['原始 文本 进行 标记', '主要 思想']

# 该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
vectorizer = CountVectorizer(max_features=10) #列数为10
# 该类会统计每个词语的tf-idf权值
tf_idf_transformer = TfidfTransformer()
# 将文本转为词频矩阵并计算tf-idf
tf_idf = tf_idf_transformer.fit_transform(vectorizer.fit_transform(x_train))
# 将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
x_train_weight = tf_idf.toarray()

# 对测试集进行tf-idf权重计算
tf_idf = tf_idf_transformer.transform(vectorizer.transform(x_test))
x_test_weight = tf_idf.toarray()  # 测试集TF-IDF权重矩阵

print('vectorizer.fit_transform(x_train) : ')
print(vectorizer.fit_transform(x_train))
print('输出x_train文本向量:')
print(x_train_weight)
print('输出x_test文本向量:')
print(x_test_weight)

在这里插入图片描述在这里插入图片描述
4. 利用Jieba实现tf-idf

import jieba.analyse
 
text='关键词是能够表达文档中心内容的词语,常用于计算机系统标引论文内容特征、
信息检索、系统汇集以供读者检阅。关键词提取是文本挖掘领域的一个分支,是文本检索、
文档比较、摘要生成、文档分类和聚类等文本挖掘研究的基础性工作'
 
keywords=jieba.analyse.extract_tags(text, topK=5, withWeight=False, allowPOS=())
print(keywords)

注:

jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
sentence 为待提取的文本
topK 为返回几个 TF/IDF 权重最大的关键词,默认值为 20
withWeight 为是否一并返回关键词权重值,默认值为 False
allowPOS 仅包括指定词性的词,默认值为空,即不筛选

运行结果:
在这里插入图片描述
(安装不了就pip install jieba; conda install jieba; pip3 install jieba;都尝试一边,我用pip3安装才成功的,如果还不成功可以去jieba官网手动下载后自行配置到anaconda环境)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Daisy_Wang777/article/details/120510366

智能推荐

P2196 挖地雷【dfs】_表示每个地窖中的地雷个数。 第 33 行至第 n+1n+1 行表示地窖之间的连接情况:-程序员宅基地

文章浏览阅读357次。题目描述在一个地图上有NN个地窖(N \le 20)(N≤20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。输入格式有若干行。第11行只有一个数字,表示地窖的个数NN。第22行有NN个数,分别表示每个地窖中的地雷个数。第33行至第N+1N+1行表示地窖之间的连接情况:第33行有n-1n_表示每个地窖中的地雷个数。 第 33 行至第 n+1n+1 行表示地窖之间的连接情况:

Oracle分析函数七——函数案例-程序员宅基地

文章浏览阅读135次。环比  环比就是现在的统计周期和上一个统计周期比较。例如2008年7月份与2008年6月份相比较称其为环比。  环比发展速度是报告期水平与前一时期水平之比,表明现象逐期的发展速度。如计算一..._oracle 去年同期 分析函数

Vue3-生命周期_vue3建议在哪个生命周期函数中调用接口-程序员宅基地

文章浏览阅读1.7k次。Vue3-生命周期vue2与vue3生命周期对比在setup组合式api中使用生命周期同时在配置项和setup中使用生命周期的调用顺序vue2与vue3生命周期对比左边是vue3右边是vue2,对比两图我们发现vue创建方式由new Vue(), 更改为 Vue.createApp(oprions).mount(el)。在vue3中先将配置项传入,一切准备就绪后再开始创建实例。生命周期 beforeDestroy改为 beforeUnmount生命周期 destroyed改为 unmounte_vue3建议在哪个生命周期函数中调用接口

Building Performance Metrics into ASP.NET MVC Applications-程序员宅基地

文章浏览阅读1.2k次。https://www.simple-talk.com/dotnet/performance/building-performance-metrics-into-asp.net-mvc-applications/https://technet.microsoft.com/en-us/library/ee176961.aspxWhen you're ins_performance metrics into asp.net mvc applications

【PythonDjango后台实例 第一章】Python3.6.1+Pyserial 实现读取STM32蓝牙串口_python3.6不支持pyserial吗-程序员宅基地

文章浏览阅读4.2k次,点赞3次,收藏49次。在Baidu,Google寻找了一大堆帖子,最后索性自己看文档自己研究。最后发现实现非常容易,得益于Python强大的串口库Pyserial可以直接调用串口第一步:下载pyserial本人是windows环境,所以其他环境请自行切换1,windows按 + R 打开搜索2,输入CMD进入终端3. 输入pip install pyserial 下载最新版第_python3.6不支持pyserial吗

rust 使用 ffi 调用 C 静态链接库_rustc-link-lib-程序员宅基地

文章浏览阅读4.4k次,点赞2次,收藏4次。创建build.rs //build.rsexterncratedunce;usestd::{env,path::PathBuf};fnmain(){letlibrary_name="r2c";letroot=PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());..._rustc-link-lib

随便推点

解决wordpress无法升级、主题和插件无法更新问题_wordpress主题更新没反应-程序员宅基地

文章浏览阅读6.3k次。本文基于阿里云服务器centos 7 x64系统,利用xftp和xshell管理软件(若为学校和家庭用户,可免费申请该软件的使用权限,申请链接https://www.netsarang.com/zh/free-for-home-school/),部署lnmp环境(部署方法见“linux运维笔记”),利用wordpress建站。wordpress出现以下情况时,可通过修改文件夹用户组改善通过 Xf..._wordpress主题更新没反应

jmeter的压测_jmeter 找不到serveragent文件-程序员宅基地

文章浏览阅读2.6k次。Jmeter扩展插件 (显示内存效果图)Jmeter本身是不能够展示内存,cpu和吞吐量的,但是可以通过添加插件的方式来对jmeter添加这些功能需要将两个插件复制到lib>>extwindows本机进行监听在jmeter文件夹中找到 ServerAgent-2.2.1点击打开在ServerAgent-2.2.1文件夹中,找到startAgent..._jmeter 找不到serveragent文件

eCharts----legend不显示_echart legend无法显示-程序员宅基地

文章浏览阅读2.9w次,点赞28次,收藏15次。不显示的原因:配置中的legend的属性 data和另一个属性 series数组中的 name属性不一致;修改的方法也就不言而语了 只需要对应起来即可比如后面太长 只截图部分。..._echart legend无法显示

【Go】Go的 9个常用基本命令_go build命令-程序员宅基地

文章浏览阅读1.5w次,点赞4次,收藏14次。golang.org在国内由于一些众所周知的原因无法直接访问,因为golang.org被墙的原因,可以使用github.com/golang/tools 和 golang.org/x/tools 是一样的,下载后复制到golang.org中。为了减少浪费在排版上的时间,go 工具集中提供了一个 go fmt 命令它可以帮你格式化你写好的代码文件,使你写代码的时候不需要关心格式,只需要在写完之后执行go fmt .go ,代码就会被修改成了标准格式。单元测试——测试和验证代码的框架。_go build命令

shiro550反序列化-程序员宅基地

文章浏览阅读547次。java反序列化_shiro550反序列化

hive中多行合并一行concat_ws(去重及不去重)_concat_ws 去重-程序员宅基地

文章浏览阅读1.7w次,点赞6次,收藏13次。原始数据:id scoreaaa 1aaa 2aaa 3预期结果:id scoreaaa 1,2,3可使用select id,concat_ws(',',collect_set(cast(colname as string))) from table;使用concat_ws函数,需将字段转成string格式,collect_set会对该..._concat_ws 去重

推荐文章

热门文章

相关标签