• TF-IDF的原理与实际应用


    TF-IDF的原理与实际应用

    在这里插入图片描述

    一、TF-IDF简介

    TF-IDF(term frequency-inverse document frequency) 是一种统计方法,用以评估一个字词对于一个文本集或一个语料库中的其中一份文件的重要程度,是用于信息检索和文本挖掘的常用加权技术。
    tf-idf = tf(词频) × idf (逆向文档频率) 利用逆向文档频率来控制约束词频
    tf = n / N
    n: 词语在某篇文本中出现的频率 ;
    n / N 的目的是实现归一化, N :该文件中所有词汇的数目
    idf = log(D / d)
    D: 总的文档数
    d: 词语所在的文档数

    在公式中,我们能够发现,总的文档数是固定不变的,词语所在的文档数越少,idf值越大;词语所在的文档数越多,idf值越小。
    这样的话,我们总体来看,tf-idf的值会与tf(词语的频率)成正比,但是会随着词语所在的文档数越多而减少。这样,tf-idf就达到了突出重要词语,抑制次要词语的效果

    二、TF-IDF的缺陷
    单纯的认为频率越小的词越重要;频率越大的词越无用;同时无法体现上下文信息。
    三、sklearn中的TF-IDF
    https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html?highlight=tfidf#sklearn.feature_extraction.text.TfidfVectorizer

    tf = n 没有对tf进行归一化 ,但是对 tf-idf的整个值进行了归一化
    idf = log[ ( D + 1 ) / (d + 1) ] + 1 平滑处理保证分母不为0
    注: sklearn是一个开源的基于python语言的机器学习工具包。它通过NumPy, SciPy和Matplotlib等python数值计算的库实现高效的算法应用,并且涵盖了几乎所有主流机器学习算法。分类classification、回归 regression、聚类 clustering、降维 dimensionality reduction 、模型选择 model selection 、预处理 preprocessing

    四、归一化问题
    (一)不归一化

    from sklearn.feature_extraction.text import TfidfVectorizer
    # 使用之前实例化 tf实例
    tv = TfidfVectorizer(use_idf=True, smooth_idf=True, norm=None) # norm=None表示不做归一化处理,默认采用l2的方式 
    # 输入训练集矩阵,每行表示一个文本
    # train = ["Chinese Beijing Chinese",
    #           "Chinese Chinese Shanghai",
    #           "Chinese Macao",
    #           "Tokyo Japan Chinese"]
    train = ["I love nlp nlp",
             "nlp loves me",
             "I love China",
             "China Chinese"]   
    # 训练,构建词汇表以及词项idf值,并将输入文本列表转成VSM矩阵形式(向量空间模型)
    tv_fit = tv.fit_transform(train)
    # 打印构建的词汇表
    print(tv.get_feature_names()) 
    
    tv_fit.toarray().tolist() # 将每个词对应的tf-idf值以列表的形式输出  由于没有采用归一化,这样tf-idf的值就不会在0-1之间
    

    在这里插入图片描述
    为了验证,我们可以通过公式进行计算:
    以词语 nlp 为例,在第一篇文档中出现的次数为2,所有文档中包含nlp的文档数为2

    import math
    tf = 2
    idf = math.log((4+1)/(2+1))+1
    print(tf*idf)
    '
    运行

    在这里插入图片描述
    可以看到两者值相等。
    (二)以l2的方式归一化
    在这里插入图片描述
    从sklearn提供的官方文档中,我们可以发现,sklearn默认以l2的方式进行归一化操作;
    l2: sum of sqquares of vector elements is 1. 每一行的平方和为1

    tv = TfidfVectorizer(use_idf=True, smooth_idf=True,norm = 'l2')#Sum of squares of vector elements is 1 表示 每一行平方和为1
    # 输入训练集矩阵,每行表示一个文本
    train = ["I love nlp nlp",
             "nlp loves me",
             "I love China",
             "China Chinese"]
    # 训练,构建词汇表以及词项idf值,并将输入文本列表转成VSM矩阵形式
    tv_fit = tv.fit_transform(train)
    # 查看一下构建的词汇表
    print(tv.get_feature_names())
    
    # 查看输入文本列表的VSM矩阵
    tv_fit.toarray().tolist()
    

    在这里插入图片描述

    通过验证:
    在这里插入图片描述
    (三)以l1的方式归一化
    l1:Sum of absolute values of vector elements is 1. 每一行的绝对值之和为1

    from sklearn.feature_extraction.text import TfidfVectorizer
    # 表示l1归一化的方式为每一行相加之和为1
    tv = TfidfVectorizer(use_idf=True, smooth_idf=True,norm = 'l1') # l1 Sum of absolute values of vector elements is 1
    # 输入训练集矩阵,每行表示一个文本
    train = ["I love nlp nlp",
             "nlp loves me",
             "I love China",
             "China Chinese"]
    # train = ["我 爱 自然语言处理",
    #         "自然语言处理 也爱 我",
    #         "我 是 中国人",
    #         "自然语言处理 是一门 课程"]
    # 训练,构建词汇表以及词项idf值,并将输入文本列表转成VSM矩阵形式
    tv_fit = tv.fit_transform(train)
    # 查看一下构建的词汇表
    print(tv.get_feature_names())
    # 查看输入文本列表的VSM矩阵
    tv_fit.toarray().tolist()
    

    在这里插入图片描述
    验证:
    在这里插入图片描述
    (四)传统方式归一化
    需要导入TfidfTransformer和CountVectorizer这两个第三方库

    from sklearn.feature_extraction.text import TfidfTransformer
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.preprocessing import Normalizer # sklearn中实现归一化的方法Normalizer
    vectorizer = CountVectorizer()  # 实例化 计数文本中出现的单词个数
    transformer = TfidfTransformer(norm = None)
    # corpus = ["我 来到 中国 旅游", "中国 欢迎 你","我 喜欢 来到 中国 天安门"]
    train = ["I love nlp nlp",
             "nlp loves me",
             "I love China",
             "China Chinese"]
    
    norm1 = Normalizer(norm='l1') # 采用l1的方式 相加之和为1
    a = vectorizer.fit_transform(train)
    print(vectorizer.get_feature_names())
    print(a.toarray().tolist())  # 制作频率统计的矩阵之后就可以对矩阵进行归一化
    

    在这里插入图片描述

    a = norm1.fit_transform(a)   
    print(a.toarray().tolist()) # n/N 1/3  2/3
    

    在这里插入图片描述

    result_list2 = transformer.fit_transform(a).toarray().tolist()
    word = vectorizer.get_feature_names()
    #print(transformer.get_params())
    print('词典为:')
    print(word)
    print('tf-idf值(没有归一化)为:')
    for weight in result_list2:
        print(weight)
    

    在这里插入图片描述

    import math
    tf =2/3
    idf = math.log((4+1)/(2+1))+1
    tf*idf
    '
    运行

    在这里插入图片描述

  • 相关阅读:
    面试官:我看你简历上写了MySQL,对MySQL InnoDB引擎的索引了解吗?
    关于fastdds相关问题
    图像增强之灰度变换和直方图均衡化(附代码python+opencv)
    SpringBoot 整合 WebSocket 实现长连接,将数据库中的数据进行推送
    Libtorch教程(一):Libtorch的下载与介绍
    如何让Nginx更安全?
    实现页面全局Loading进度条实现
    千万注意!使用GetAsyncKeyState检测窗口按键时要检查是否为前端窗口!
    Karmada 多云容器编排引擎支持多调度组,助力成本优化
    【MindSpore易点通机器人-03】迭代0的准备工作
  • 原文地址:https://blog.csdn.net/qq_45556665/article/details/127046829