NLP(10)--TFIDF优劣势及其应用Demo

news2024/11/24 17:39:21

前言

仅记录学习过程,有问题欢迎讨论

TF*IDF:

在这里插入图片描述
优势:

  1. 可解释性好
    可以清晰地看到关键词
    即使预测结果出错,也很容易找到原因

  2. 计算速度快
    分词本身占耗时最多,其余为简单统计计算

  3. 对标注数据依赖小
    可以使用无标注语料完成一部分工作

  4. 可以与很多算法组合使用
    可以看做是词权重

劣势:
1.受分词效果影响大

2.词与词之间没有语义相似度

3.没有语序信息(词袋模型)

4.能力范围有限,无法完成复杂任务,如机器翻译和实体挖掘等

5.样本不均衡会对结果有很大影响

6.类内样本间分布不被考虑

代码

Demo1:手动实现TFIDF

"""
实现一个 TFIDF
"""
import jieba
import math
import os
import json
from collections import defaultdict


def build_tf_idf_dict(corpus):
    tf_dict = defaultdict(dict)  # key:文档序号,value:dict,文档中每个词出现的频率
    idf_dict = defaultdict(set)  # key:词, value:set,文档序号,最终用于计算每个词在多少篇文档中出现过
    for text_index, text_words in enumerate(corpus):
        for word in text_words:
            if word not in tf_dict[text_index]:
                tf_dict[text_index][word] = 0
            tf_dict[text_index][word] += 1
            idf_dict[word].add(text_index)
    idf_dict = dict([(key, len(value)) for key, value in idf_dict.items()])
    return tf_dict, idf_dict


# 根据tf值和idf值计算tfidf
def calculate_tf_idf(tf_dict, idf_dict):
    tf_idf_dict = defaultdict(dict)
    for text_index, word_tf_count_dict in tf_dict.items():
        for word, tf_count in word_tf_count_dict.items():
            tf = tf_count / sum(word_tf_count_dict.values())
            # tf-idf = tf * log(D/(idf + 1))
            tf_idf_dict[text_index][word] = tf * math.log(len(tf_dict) / (idf_dict[word] + 1))
    return tf_idf_dict


# 计算样本的 tfidf
def calculate_tfidf(corpus):
    corpus = [jieba.cut(text) for text in corpus]
    tf_dict, idf_dict = build_tf_idf_dict(corpus)
    tf_idf_dict = calculate_tf_idf(tf_dict, idf_dict)
    return tf_idf_dict


# 取出前k个 tfidf最大的数据
def tf_idf_topk(tfidf_dict, paths=[], top=10, print_word=True):
    topk_dict = {}
    for text_index, text_tfidf_dict in tfidf_dict.items():
        # idf 逆序
        word_list = sorted(text_tfidf_dict.items(), reverse=True, key=lambda x: x[1])
        # 去排序后的前top个
        topk_dict[text_index] = word_list[:top]
        if print_word:
            print(text_index, paths[text_index])
            for i in range(top):
                print(word_list[i])
            print("----------")
    return topk_dict


def main():
    dir_path = r"week4/category_corpus/"
    corpus = []
    paths = []
    for path in os.listdir(dir_path):
        path = os.path.join(dir_path, path)
        if path.endswith("txt"):
            corpus.append(open(path, encoding="utf8").read())
            paths.append(os.path.basename(path))
    tf_idf_dict = calculate_tfidf(corpus)
    tf_idf_topk(tf_idf_dict, paths)


if __name__ == "__main__":
    main()


Demo2:利用 tfidf 实现简单搜索引擎功能

"""
利用 tfidf 实现简单搜索引擎功能

"""

import jieba
import math
import os
import json
from collections import defaultdict

# 加载文档数据(可以想象成网页数据),计算每个网页的tfidf字典
from day0429_1 import calculate_tfidf


def load_data(path):
    # path = "/week4/news.json"
    corpus = []
    with open(path, encoding="utf8") as f:
        documents = json.loads(f.read())
        for document in documents:
            corpus.append(document['title'] + "\n" + document["content"])
        tf_idf_dict = calculate_tfidf(corpus)
    return tf_idf_dict, corpus


def search_engine(query_str, tf_idf_dict, corpus, top=3):
    query_words = jieba.lcut(query_str)
    res = []
    for doc_id, tf_idf in tf_idf_dict.items():
        score = 0
        for word in query_words:
            # 搜到关键词了 score++
            score += tf_idf.get(word, 0)
        res.append([doc_id, score])
    res = sorted(res, reverse=True, key=lambda x: x[1])
    for i in range(top):
        doc_id = res[i][0]
        print(corpus[doc_id])
        print("--------------")
    return res

if __name__ == "__main__":
    path = "C:\\Users\\Administrator\\Desktop\\LearnPython\\week4\\news.json"
    tf_idf_dict, corpus = load_data(path)
    while True:
        query = input("请输入您要搜索的内容:")
        search_engine(query, tf_idf_dict, corpus)

Demo3 :基于tfidf实现简单文本摘要

import jieba
import math
import os
import random
import re
import json
from collections import defaultdict

from day0429_1 import calculate_tfidf

"""
基于tfidf实现简单文本摘要
"""


# 加载文档数据(可以想象成网页数据),计算每个网页的tfidf字典
def load_data(file_path):
    corpus = []
    with open(file_path, encoding="utf8") as f:
        documents = json.loads(f.read())
        for document in documents:
            assert "\n" not in document["title"]
            assert "\n" not in document["content"]
            corpus.append(document["title"] + "\n" + document["content"])
        tf_idf_dict = calculate_tfidf(corpus)
    return tf_idf_dict, corpus


# 计算每一篇文章的摘要
# 输入该文章的tf_idf词典,和文章内容
# top为人为定义的选取的句子数量
# 过滤掉一些正文太短的文章,因为正文太短在做摘要意义不大
def generate_document_abstract(document_tf_idf, document, top=3):
    sentences = re.split("?|!|。", document)
    if len(sentences) < 5:
        return None
    res = []
    for index, sentence in enumerate(sentences):
        sentence_score = 0
        words = jieba.lcut(sentence)
        for word in words:
            sentence_score += document_tf_idf.get(word, 0)
        # 记录下每句话的分数和下标
        res.append([sentence_score, index])
    res = sorted(res, reverse=True, key=lambda x: x[0])
    # 权重最高的可能依次是第10,第6,第3句,将他们调整为出现顺序比较合理,即3,6,10
    important_sentence_indexs = sorted([x[1] for x in res[:top]])
    return "。".join([sentences[index] for index in important_sentence_indexs])


# 生成摘要
def generate_abstract(tf_idf_dict, corpus):
    res = []
    for index, document_tf_idf in tf_idf_dict.items():
        title, content = corpus[index].split("\n")
        abstract = generate_document_abstract(document_tf_idf, content)
        if abstract is None:
            continue
        corpus[index] = "\n" + abstract
        res.append({"标题": title, "正文": content, "摘要": abstract})
    return res

if __name__ == "__main__":
    path = "C:\\Users\\Administrator\\Desktop\\LearnPython\\week4\\news.json"
    tf_idf_dict, corpus = load_data(path)
    res = generate_abstract(tf_idf_dict, corpus)
    writer = open("abstract.json", "w", encoding="utf8")
    writer.write(json.dumps(res, ensure_ascii=False, indent=2))
    writer.close()


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1634044.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超级数据查看器 app v2.0发布 欢迎下载使用

超级数据查看器 app v2.0发布 欢迎下载使用 感谢大家的支持 &#xff1a;&#xff09; 点击访问APP下载界面 跳转 腾讯应用宝 简介 超级数据查看器软件&#xff08;简称超级数据查看器&#xff09;是一个提供数据查询和数据管理的手机APP&#xff0c;能导入文本数据&…

ubuntu neo4j 下载与配置(一)

neo4j 官方下载页面 https://neo4j.com/deployment-center/#community 进入页面之后&#xff0c;往下滑 咱们在下载neo4j时&#xff0c;官方可能要咱们填写一下个人信息&#xff0c;比如&#xff1a;姓名组织结构邮箱等&#xff1a; 咱们可以观察一下&#xff0c;ne4j的下载链…

大数据学习笔记14-Hive基础2

一、数据字段类型 数据类型 &#xff1a;LanguageManual Types - Apache Hive - Apache Software Foundation 基本数据类型 数值相关类型 整数 tinyint smallint int bigint 小数 float double decimal 精度最高 日期类型 date 日期 timestamps 日期时间 字符串类型 s…

OpenAI 新推出 AI 问答搜索引擎——SearchGPT 震撼登场

您的浏览器不支持 video 标签。 OpenAI-SearchGPT 近日&#xff0c;OpenAI 曝光了自己的一款令人瞩目的 AI 问答搜索引擎——SearchGPT。这款搜索引擎带来了全新的搜索体验&#xff0c;给整个行业带来了巨大的压力。 SearchGPT 支持多种强大的功能。首先&#xff0c;它能够通过…

STM32CubeMX+MDK通过I2S接口进行音频输入输出(全双工读写一个DMA回调)续-音质问题解决总结

一、前言 之前进行了STM32CubeMXMDK通过I2S接口进行音频输入输出&#xff08;全双工读写一个DMA回调&#xff09;的研究总结&#xff1a; https://juejin.cn/post/7339016190612881408#heading-34 后续音质问题解决了&#xff0c;目前测试下来48khz的双声道使用效果很好&…

mySQL商城项目实战 (终)(全部表)(1-88张)

本章无sql语句&#xff0c;直接放转出的sql文件。 88张表结果如图! 资源在已经与文章绑定&#xff0c; 在navicat工具中&#xff0c;执行以下步骤 在新建的数据库中右键,点击【运行sql文件】&#xff0c;运行绑定的资源&#xff0c;之后您就可以在您的navicat中看到我建好的8…

Python数据分析大作业(ARIMA 自回归积分滑动平均模型) 4000+字 图文分析文档 销售价格库存分析+完整python代码

资源地址&#xff1a;Python数据分析大作业 4000字 图文分析文档 销售分析 完整python代码 完整代码分析 ​ 同时销售量后1000的sku品类占比中&#xff08;不畅销产品&#xff09;如上&#xff0c;精品类产品占比第一&#xff0c;达到66.7%&#xff0c;其次是香化类产品&#x…

在Android中,如何通过Kotlin协程处理多个API调用

在Android中&#xff0c;如何通过Kotlin协程处理多个API调用 在Android开发中&#xff0c;如何使用Kotlin协程处理多个API调用的示例呢&#xff1f;假设我们已经对Kotlin协程有了一定的了解&#xff0c;包括定义、简单用例和示例等。现在&#xff0c;让我们来看一些真实的Andr…

AD21技巧[更加便捷的DRC检查][把线框转成Keep-Out Layer板框]

AD10用了好久,之所以换到AD21并不是因为AD10功能不够强,而且因为别人用高版本设计的软件到我这里竟然打不开了,这个是我不能够接受的,所以开始使用AD21,使用之后发现AD21好多使用习惯和AD10有很大的区别! 更加便捷的DRC检查 本文摘录于&#xff1a;https://www.cnblogs.com/U…

[Android14] SystemUI的启动

1. 什么是System UI SystemUI是Android系统级应用&#xff0c;负责反馈系统及应用状态并与用户保持大量的交互。业务主要涉及的组成部分包括状态栏(Status Bar)&#xff0c;通知栏(Notification Panel)&#xff0c;锁屏(Keyguard)&#xff0c;控制中心(Quick Setting)&#xff…

基于H.264的RTP打包中的组合封包以及分片封包结构图简介及抓包分析

H.264视频流的RTP封装类型分析&#xff1a; 前言&#xff1a; NULL Hearder简介(结构如下)&#xff1a; ---------------|0|1|2|3|4|5|6|7|--------|F|NRI| Type |--------------- F&#xff1a;forbidden_zero_bit&#xff0c; 占1位&#xff0c;在 H.264 规范中规定了这…

RustGUI学习(iced)之小部件(四):如何使用单选框radio部件?

前言 本专栏是学习Rust的GUI库iced的合集&#xff0c;将介绍iced涉及的各个小部件分别介绍&#xff0c;最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个&#xff0c;目前处于发展中&#xff08;即版本可能会改变&#xff09;&#xff0c;本专栏基于版本0.12.1. 概述…

【酱浦菌-爬虫技术细节】解决学术堂爬虫翻页(下一页)问题

首先我们通过css选择器获取页码信息&#xff0c;这里的css选择器&#xff0c;选择的是含有a标签的所有li标签&#xff0c;代码如下&#xff1a; li html_web.css(div.pd_c_xslb_left_fenye ul li>a) for li in li:li_url li.css(a::attr(href)).get()li_num li.css(a::t…

基于FPGA的数字信号处理(6)--如何确定Verilog表达式的符号

前言 尽管signed语法的使用能带来很多便利&#xff0c;但同时也给表达式的符号确定带来了更多的不确定性。比如一个有符号数和一个无符号数的加法/乘法结果是有符号数还是无符号数&#xff1f;一个有符号数和一个无符号数的比较结果是有符号数还是无符号数&#xff1f;等等。接…

IOT病毒分析

前言&#xff1a; 最近审计报警日志&#xff0c;发现了一个IOT病毒&#xff0c;利用的是CVE-2023-1389漏洞扫描tplink&#xff0c;进行攻击&#xff0c;有点意思&#xff0c;拿出来分析下。 发现&#xff1a; 查看流量日志&#xff0c;发现了一个有问题的访问&#xff1a; 访…

【架构】后端项目如何分层及分层领域模型简化

文章目录 一. 如何分层1. 阿里规范2. 具体案例分析 二. 分层领域模型的转换1. 阿里规范2. 模型种类简化分析 三. 小结 本文描述后端项目中如何进行分层&#xff0c;以及分层领域模型简化 一. 如何分层 1. 阿里规范 阿里的编码规范中约束分层逻辑如下: 开放接口层&#xff1a…

CSS实现各种优惠券效果

一、左半圆效果 <style style"text/css">.coupon {width: 240px;height: 100px;margin-top: 15px;background-color: #ff6347;-webkit-mask: radial-gradient(circle at left center, transparent 20px, red 20px); } </style><div class"coupon…

摩根大通推出创新工具 FlowMind,引领金融自动化新变革

近日&#xff0c;摩根大通人工智能研究部推出了一款极具创新性的工具——FlowMind&#xff0c;为金融行业带来了全新的工作模式和效率提升。 FlowMind 能够自动化金融工作流程&#xff0c;在信贷审批、风险评估、合规监测等重要任务中发挥着关键作用。它利用 GPT 自动生成工作…

张鸣独到政治观,规矩与自信新解

张鸣独解规矩与自信&#xff0c;社政新影响揭秘。张鸣独到政治观&#xff0c;规矩与自信新解在当今社会政治的大背景下&#xff0c;学者张鸣的每一次公开演讲无疑都是一次思想的盛宴。最近&#xff0c;他就当前的社会政治问题提出了自己独特的观点&#xff0c;特别是他对规矩和…

【网络原理】UDP协议 | UDP报文格式 | 校验和 | UDP的特点 | 应用层的自定义格式

文章目录 一、UDP协议1.UDP的传输流程发送方接收方 2.UDP协议报文格式&#xff1a;长度受限校验和如何校验&#xff1a;CRC算法&#xff1a;循环冗余算法md5算法&#xff1a; 2.UDP的特点 二、开发中常见的自定义格式1.xml&#xff08;古老&#xff09;2.json&#xff08;最流行…