• TFIDF介绍


    简介

    • 全称: Term Frequency-inverse document frequency(文本频率与逆文档频率指数)

    • 目的: 表征一个token(可以是一个字或者一个词)的重要程度

    • 是ElasticSearch的评分算法

    • TF - 如果该token出现的频率很高, 且不是常用连接词或语气词, 那么该词的重要程度就更高。

    • 如果该词是常用连接词或语气词, 那该词即使出现很多次也不是很重要。为了处理该种情况, 出现了逆文档频率指数(idf)。

    • 逆文档评率指数(idf)公式: log(所有的文档条数/有这个词的文档条数) => 这个词尽可能的只在某几条文档中出现过, 那样才更有区分性。

    • 举个小栗子:

      (a, b, c, d, e) 五个词, 所有词汇总数是5,若词d出现了1次, 那么其tf=1/5
      若文档总数为4条, d的idf=log(4/1), 实际操作中会加入平滑因子, 防止统计数为0出现。
      该词d的权重为 tf * idf = 1/5 * log(4 / 1)
      
      • 对每个词都做一下这样的计算,最后得到的是一个样品数量 * 唯一token总数维度的矩阵,在例子中样本数量为3,唯一token总数为5,那么我们会得到一个3*5的矩阵,如果这一条文档中没有这个词就直接赋值0就可以了。

    使用python调numpy库实现

    #!/usr/bin/env python
    # encoding: utf-8
    
    import numpy as np
    
    class TFIDF(object):
        """TFIDF简单实现"""
        def __init__(self, corpus):
            self.word_id = {}
            self.vocabulary_count = {}
            self.corpus = corpus
            self.smooth_idf = 0.01
    
        def fit_transform(self, corpus):
            pass    
            
        def get_vocabulary_frequency(self):
            """
            计算文本特征的出现次数, 返回self.vocabulary_count     
            """  
    
            # 统计各词出现个数
            id = 0
            for single_corpus in self.corpus:
                # 判断单个corpus是否为list类型
                if isinstance(single_corpus, list):
                    pass
                # 判断是否为string类型    
                if isinstance(single_corpus, str):
                    # 去除换行符, 再按空格分开, 返回的应该是一个list
                    single_corpus = single_corpus.strip("
    ").split(" ")
                for word in single_corpus:
                    # 如果该词不在词汇统计表的key中
                    if word not in self.vocabulary_count:
                        # 将该词放入到词汇统计表及词汇编码表中
                        self.vocabulary_count[word] = 1
                        self.word_id[word] = id
                        id += 1
                    else:
                        # 如果已经在了, 词频统计加一就ok
                        self.vocabulary_count[word] += 1  
    
            # 生成corpus长度 X 词频统计表长度的全零矩阵
            X = np.zeros((len(self.corpus), len(self.vocabulary_count)))
            for i in range(len(self.corpus)):
                # 如果是string类型, 就去换行符并分割
                if isinstance(self.corpus[i], str):
                    single_corpus = self.corpus[i].strip("
    ").split(" ")
                else:
                    single_corpus = self.corpus[i]
                # 遍历单个single_corpus
                for j in range(len(single_corpus)):
                    # 获取特征值和特征id, 并将他们放入矩阵对应的位置上
                    feature = single_corpus[j]
                    feature_id = self.word_id[feature]
                    X[i, feature_id] = self.vocabulary_count[feature]
            return X.astype(int)   # 需要转为int  
    
    
        def get_tf_tdf(self):
            """
            计算idf并生成最后的TFIDF矩阵
            """       
            X = self.get_vocabulary_frequency()
            num_samples, n_features = X.shape
            df = []
            for i in range(n_features):
                # 统计每个特征的非0的数量,也就是逆文档频率指数的分式中的分母,是为了计算idf
                # bincount: 传入一个数组, 返回对应索引出现的次数的数组(大致可以这么理解)
                df.append(num_samples - np.bincount(X[:,i])[0]) 
            df = np.array(df)
            # 是否需要添加平滑因子
            df += int(self.smooth_idf)
            num_samples += int(self.smooth_idf)
            idf = np.log(num_samples / df) + 1 # 核心公式
            return X*idf/len(self.vocabulary_count)
    
    
    if __name__ == '__main__':
        corpus = [["此", "生", "不", "换"],["此", "情", "此", "景"],["不", "蔓", "不", "枝"]]
        test = TFIDF(corpus)
        print(test.get_tf_tdf())
    
  • 相关阅读:
    python打包生成exe文件
    Django建表
    Pycharm 激活码2017最新
    源码包安装Mysql
    Python 的PIL,可以解决ImportError The _imagingft C module is not installed
    远方的塔--Pylons
    Flask 框架入门
    缓动公式
    js源生惯性滚动与回弹(备用)
    javascript实现继承的12种套路
  • 原文地址:https://www.cnblogs.com/ronnieyuan/p/11943458.html
Copyright © 2020-2023  润新知