精华内容
下载资源
问答
  • 统计十篇新闻TF-IDF 统计TF-IDF词频,每篇文章的 top10 的高频词存储为 json 文件 TF-IDF TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与文本挖掘的常用加权技术。TF-IDF是一种统计方法...
  • td-idf的理解

    千次阅读 2017-06-27 12:36:51
    何为TF-IDFTF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。假设有...

    何为TF-IDF

    TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。

    假设有如下一篇文档集

    文档1: Human machine
    文档2: System human
    ---------------------------------
    则有语料库(各个词在文档出现次数)为:   
    单词\文档  文档1     文档2    总计
    human     1(a表示)  1       2(c表示)
    machine   1        0       1
    system    0        1       1
    总计词     2(b表示)  2    文档总数为2(d表示)
    ------------------------------
    td-idf计算什么? : 如计算human在文档1中的权重
    td-idf计算公式为: 该文档词频 * 逆向文件频率
    如human在文档1的td-idf为:0.5 * 0 = 0,其中:
    词频 = a/b = 1/2=0.5
    逆向文件频率 = log(d/c) = log(1) = 0
    又如machine在文档1的td-idf为: 0.5 * log(2) = 0.35
    -------------------------------
    本文档集的td-idf为:
    单词\文档   文档1      文档2
    human      0         0
    machine    0.35      0       
    system     0         0.35       
    

    gensim中从一个文档集中获得一个td-idf的代码如下:

    关于gensim语料库的介绍,可参考
    http://blog.csdn.net/m0_37681914/article/details/73744685

    #文档集,每一行表示一篇文档
    documents = ["Human machine interface for lab abc computer applications",
                  "A survey of user opinion of computer system response time",
                  "The EPS user interface management system",
                  "System and human system engineering testing of EPS",
                  "Relation of user perceived response time to error measurement",
                  "The generation of random binary unordered trees",
                  "The intersection graph of paths in trees",
                  "Graph minors IV Widths of trees and well quasi ordering",
                  "Graph minors A survey"]
    stoplist = set('for a of the and to in'.split())
    texts = [[word for word in document.lower().split() if word not in stoplist]
             for document in documents]
    from collections import defaultdict
    frequency = defaultdict(int)
    for text in texts:
        for token in text:
            frequency[token] += 1
    texts = [[token for token in text if frequency[token] > 1]
              for text in texts]
    from gensim import corpora
    dictionary = corpora.Dictionary(texts)
    corpus = [dictionary.doc2bow(text) for text in texts]
    #------------以上代码均是为了获取语料库corpus--------------------
    #------------以下步入正题-------------
    #获取文档集的tf-idf,得到的tfidf即是一个不可变的权重模板
    tfidf = models.TfidfModel(corpus)
    #用tfidf模板来计算文档doc_bow(矢量空间表示)的td-idf值
    doc_bow = [(0, 1), (1, 1)]
    print(tfidf[doc_bow])
    #对整个语料库应用转换
    corpus_tfidf = tfidf[corpus]
    for doc in corpus_tfidf:
        print(doc)
    展开全文
  • MapReduce ---- TD-IDF

    2019-09-30 18:17:21
    1、TF-IDF  TF-IDF(term frequency/inverse document frequency) 的概念被公认为信息检索中最重要的发明。描述单个term与特定document的相关性。  TF(Term Frequency): 表示一个term与某个document的相关性。...

    1、TF-IDF

      TF-IDF(term frequency/inverse document frequency) 的概念被公认为信息检索中最重要的发明。描述单个term与特定document的相关性。

      TF(Term Frequency): 表示一个term与某个document的相关性。公式为: term在document中出现的次数/document中所有term出现的总次数.

      IDF(Inverse Document Frequency):表示一个term表示document的主题的权重大小。

      主要是通过包含了该term的docuement的数量和docuement set的总数量来比较的。出现的次数越多,权重越小。公式是log(D/Dt)   D是文档集合大小

    Dw是包含了该Word的文档的总数。根据关键字k1,k2,k3进行搜索结果的相关性就变成TF1*IDF1 + TF2*IDF2 + TF3*IDF3。比如document1的term总量

    为1000,k1,k2,k3在document1出现的次数是100,200,50。包含了 k1, k2, k3的docuement总量分别是1000, 10000,5000。document set的总

    量为10000。

      TF1 = 100/1000 = 0.1;                           TF2 = 200/1000 = 0.2;                           TF3 = 50/1000 = 0.05;

      IDF1 = log(10000/1000) = log(10) = 2.3; IDF2 = log(10000/100000) = log(1) = 0;  IDF3 = log(10000/5000) = log(2) = 0.69;

      这样关键字k1,k2,k3与docuement1的相关性= 0.1*2.3 + 0.2*0 + 0.05*0.69 = 0.2645;其中k1比k3的比重在document1要大,k2的比重是0.

      TF/IDF 的概念就是一个特定条件下、关键词的概率分布的交叉熵(Kullback-Leibler Divergence)。

      TF和IDF的其他解释可参阅《数学之美》(吴军著),这本书超赞。

    2、MapReduce 计算

      不讨论实现的细节,只考虑如何构造其中的Key和value。

      为了计算TF-IDF ,需要分别计算TF和IDF,TF为单词在文档中的频率,因此首先需要知道单词 word在文档Doc中出现的频度,其次需要知道当前Doc中单词的个数。

          第一个JOB计算word在Doc中的频度。

      MAP的输入:Key:行号 Value为对应文档的一行。在map函数中将每一行切分为一个个的单词,当然这么做其实是不完全正确的,比如对于词组 set

    out,其原本的意思是出发,但是将其按单词进行划分后变为 set 和out,这不是我们原本的意愿。在此,为了简单起见我们忽略这些细节。MAP的输出:

    Word@Doc   1。也就是 单词@文档名称 作为Key,Value为 1,表示 单词Word在Doc中出现了一次。

      MapReduce的会根据Key排序并组合相应的Value,因此JOB1的Reduce输入为:Key:Word@Doc  Value:1,1,1,1... 因此可以统计出单词Word在

    Doc中一共 出现了多少次。将Reduce的输出设为:Key:Doc  Value:Word->N。表示文档Doc中单词Word出现了N次。经过MapReduce的shuffle过程

    后,Reduce的输出变为:Key:Doc  Value:Word1->N1  Word2->N2,... ... ,Wordk->Nk。JOB1的Reduce输出可以作为JOB2-Map的输入。

      到此,第一个JOB就统计了单词在不同文档的频度,Reduce的输出为第二个JOB的输入。

      第二个JOB计算一个文档所有单词的个数和某一单词在文档中的频率TF。

      MAP的输入:Key:Doc  Value:Word1->N1,Word2->N2,... ...  。因此Map函数中可以计算一个文档中单词的总数Total,文档中每个单词的

    个数是已知的,因此可以计算单词Word针对文档Doc的TF。将当前MAP的输出设为:Key:Word,Value:Doc  N/Total ,也就是单词作为Key,所在文档

    Doc和对应的TF作为Value。经过shuffle后,JOB2-Reduce的输入:Key:Word,Value:Doc1 N1/Total  Doc2 N2/Total ... ... ,此时知道单词Word

    在Doc1,Doc2... 等文档中出现,通过MapReduce获取文档总数,就可以计算Word针对每个文档Doc的IDF值,此时Reduce的输出变为:Key:Word@Doc Value:TF IDF TF*IDF。

      至此,TF-IDF的计算完毕。对上述过程的优化,后续探讨。

      

     

      

    转载于:https://www.cnblogs.com/tju-gsp/p/4130788.html

    展开全文
  • TD-IDF在spark中的使用(ml方式)

    千次阅读 2016-12-20 10:56:34
    上一篇 文章提到了TD-IDF的原理和大致使用方式, 现在我写了一个比较完整的例子来展示一下, 该例子包含了数据导入(为了统一, 将文件导入了数据库),处理, 以及结果导出功能.import org.apache.spark.mllib.linalg....

    上一篇 文章提到了TD-IDF的原理和大致使用方式, 现在我写了一个比较完整的例子来展示一下, 该例子包含了数据导入(为了统一, 将文件导入了数据库),处理, 以及结果导出功能.

    import org.apache.spark.mllib.linalg.Vector
    import com.zte.bigdata.vmax.machinelearning.common.{LogSupport, CreateSparkContext}
    import org.apache.spark.ml.feature.{IDF, HashingTF, Tokenizer}
    import org.apache.spark.sql.DataFrame
    import org.apache.spark.sql.functions.{col, udf}
    import scala.collection.mutable.ArrayBuffer
    import org.apache.spark.mllib.feature.{HashingTF => MllibHashingTF}
    import scala.util.Try
    /*
    * table_tf_idf表是输入表, 其结构为theme+content, content表示主题theme下的某一篇文章,
    * 下图显示了一个主题, 其实有很多.
    * 
    * +--------------+--------------------+
    * |         theme|             content|
    * +--------------+--------------------+
    * |comp.windows.x|From: chongo@toad...|
    * |comp.windows.x|From: chongo@toad...|
    * |comp.windows.x|From: steve@ecf.t...|
    * |comp.windows.x|From: ware@cis.oh...|
    * |comp.windows.x|From: stevevr@tt7...|
    * ...
    */
    
    class TFIDFModel extends CreateSparkContext {
    // CreateSparkContext中包含sc, hc(sqlContext)的创建
    
      // 保证RDD可以转换为DataFrame
      import hc.implicits._
    
      def calTFIDF(topN:Int): DataFrame = {
    
        hc.sql("use database")
    
        // 因为要提取theme的关键词, 所以需要先做聚合,将相同主题文章放到一起
        // select concat_ws(" ".collect_list(content) group by theme) from table_tf_idf 应该也可以
        val dataGroupByTheme = hc.sql(s"select theme,content from table_tf_idf").rdd
        .map(row => (row.getString(0), row.getString(1).replaceAll("\\p{Punct}", " ")))// 去掉英文标点
        .reduceByKey((x, y) => x + y) //聚合
        .toDF("theme", "content") //转回DF
    
        // 用于做分词, 结果可见前文
        val tokenizer = new Tokenizer().setInputCol("content").setOutputCol("words")
        val wordsData = tokenizer.transform(dataGroupByTheme)
    
        // 获取单词->Hasing的映射(单词 -> 哈希值)
        //此处HashingTF属于mllib, 默认numFeatures为1<<20, 但是ml下的hashingTF却是1<<18, 要统一才能确保hash结果一致
        val mllibHashingTF = new MllibHashingTF(1 << 18) 
        val mapWords = wordsData.select("words").rdd.map(row => row.getAs[ArrayBuffer[String]](0))
        .flatMap(x => x).map(w => (mllibHashingTF.indexOf(w), w)).collect.toMap
    
        // 计算出TF值
        val hashingTF = new HashingTF().setInputCol("words").setOutputCol("rawFeatures")
        val featurizedData = hashingTF.transform(wordsData)
    
        // 计算IDF值, 实际计算出来的形式为稀疏矩阵 [标签总数,[标签1,标签2,...],[标签1的值,标签2的值,...]]
        val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features")
        val idfModel = idf.fit(featurizedData)
        val rescaledData = idfModel.transform(featurizedData)
    
        // 将得到的数据按照tf-idf值从大到小排序,提取topN,并且将hashing id 转为单词
        val takeTopN = udf { (v: Vector) => 
          (v.toSparse.indices zip v.toSparse.values)
          .sortBy(-_._2) //负值就是从大到小
          .take(topN)
          .map(x => mapWords.getOrElse(x._1, "null") + ":" + f"${x._2}%.3f".toString) // 冒号分隔单词和值,值取小数后三位
          .mkString(";") } // 词语和值的对以;隔开(别用逗号,会与hive表格式的TERMINATED BY ','冲突)
    
        rescaledData.select(col("theme"), takeTopN(col("features")).as("features"))
    
        //    rescaledData.select("features", "theme").take(3).foreach(println)
      }
    
    
      // 将原始文件写入数据库
      def data2DB() = {
        case class Article(theme:String, content:String)
     // 每个hdfs路径主题下都有很多文章
        val doc1 = sc.wholeTextFiles("/sdl/data/20news-bydate-train/comp.windows.x")
        val doc2 = sc.wholeTextFiles("/sdl/data/20news-bydate-train/comp.graphics")
        val doc3 = sc.wholeTextFiles("/sdl/data/20news-bydate-train/misc.forsale")
        val doc = doc1.union(doc2).union(doc3)
    
      // 创建df, 并且把文章的换行和回车去掉
        val df =  sqlContext.createDataFrame(doc.map(x => Article(x._1.split("/").init.last,x._2.replaceAll("\n|\r",""))))
        df.registerTempTable("df")
    
        // df入库的方式与 saveOutPut 函数相同,省略
      }
    
    
      // 将dataframe格式数据保存到数据库
      def saveOutPut(output:String) = {
        log.debug(s"TF-IDF result writed to the table $output ...")
        calTFIDF().registerTempTable("tfidf_result_table")
    
        hc.sql("use database")
        hc.sql( s"""drop table if exists $output""")
        hc.sql(
          s"""create table IF NOT EXISTS $output (
          theme  String,
          tfidf_result   String
          )
          ROW FORMAT DELIMITED FIELDS TERMINATED BY ','""")
        val sql = s"insert overwrite table $output select theme,features from tfidf_result_table"
        log.debug("load data to table sql: " + sql)
        try {
          hc.sql(sql)
        } catch {
          case e: Exception => log.error("load data to table error")
            throw e
        }
      }
    }

    保存到表里的数据如下, 取top3

    这里写图片描述

    展开全文
  • TF-IDF 实际上是两个词组 Term Frequency 和 Inverse Document Frequency 的总称,两者缩写为 TF 和 IDF,分别代表了词频和逆向文档频率。 词频 TF 计算了一个单词在文档中出现的次数,它认为一个单词的重要性和它...

    1.贝叶斯定理

    贝叶斯定理是关于随机事件A和B的条件概率或边缘概率的定理。
    其中P(A|B)是在B发生的情况下A发生的可能性。
    是在已知相关项目B的资料,而缺乏论证项目A的直接资料时,通过对B项目的有关状态及发生概率分析推导A项目的状态及发生概率。
    在贝叶斯定理中,每个名词都有约定俗成的名称:

    	P(A)是 A 的先验概率,之所以称为“先验”是因为它不考虑任何 B 方面的因素。
    	P(A|B)是已知 B 发生后 A 的条件概率,也由于得自 B 的取值而被称作 A 的后验概率。
    	P(B|A)是已知 A 发生后 B 的条件概率,也由于得自 A 的取值而被称作 B 的后验概率。
    	P(B)是 B 的先验概率,也作标淮化常量(normalizing constant)。
    

    按这些术语,贝叶斯定理可表述为:
    后验概率 = (相似度 * 先验概率)/标淮化常量
    也就是说,后验概率与先验概率和相似度的乘积成正比。
    另外,比例P(B|A)/P(B)也有时被称作标淮相似度(standardised likelihood),Bayes定理可表述为:
    后验概率 = 标淮相似度 * 先验概率
    条件概率就是事件 A 在另外一个事件 B 已经发生条件下的发生概率。条件概率表示为P(A|B),读作“在 B 发生的条件下 A 发生的概率”。
    联合概率表示两个事件共同发生(数学概念上的交集)的概率。A 与 B 的联合概率表示为。
    1.正向概率
    如: 假设袋子里面有N个白球,M个黑球,你伸手进去摸一把,摸出黑球的概率是多大,很容易计算
    2.逆向概率
    如: 如果我们事先并不知道袋子里面黑白球的比例,而是闭着眼睛摸出一个(或好几个)球,观察这些取出来的球的颜色之后,那么我们可以就此对袋子里面的黑白球的比例作出什么样的推测,这个问题,就是所谓的逆向概率的问题。
    3.朴素贝叶斯分类工作原理
    朴素贝叶斯分类是常用的贝叶斯分类方法。我们日常生活中看到一个陌生人,要做的第一件事情就是判断 TA 的性别,判断性别的过程就是一个分类的过程。根据以往的经验,我们通常会从身高、体重、鞋码、头发长短、服饰、声音等角度进行判断。这里的“经验”就是一个训练好的关于性别判断的模型,其训练数据是日常中遇到的各式各样的人,以及这些人实际的性别数据。
    离散数据案例
    我们遇到的数据可以分为两种,一种是离散数据,另一种是连续数据。那什么是离散数据呢?离散就是不连续的意思,有明确的边界,比如整数 1,2,3 就是离散数据,而 1 到 3 之间的任何数,就是连续数据,它可以取在这个区间里的任何数值。
    我以下面的数据为例,这些是根据你之前的经验所获得的数据。然后给你一个新的数据:身高“高”、体重“中”,鞋码“中”,请问这个人是男还是女?
    针对这个问题,我们先确定一共有 3 个属性,假设我们用 A 代表属性,用 A1, A2, A3 分别为身高 = 高、体重 = 中、鞋码 = 中。一共有两个类别,假设用 C 代表类别,那么 C1,C2 分别是:男、女,在未知的情况下我们用 Cj 表示。
    (分类相加,分步相乘,有序排列,无序组合)
    那么我们想求在 A1、A2、A3 属性下,Cj 的概率,用条件概率表示就是 P(Cj|A1A2A3)。根据上面讲的贝叶斯的公式,我们可以得出:
    因为一共有 2 个类别,所以我们只需要求得 P(C1|A1A2A3) 和 P(C2|A1A2A3) 的概率即可,然后比较下哪个分类的可能性大,就是哪个分类结果。
    在这个公式里,因为 P(A1A2A3) 都是固定的,我们想要寻找使得 P(Cj|A1A2A3) 的最大值,就等价于求 P(A1A2A3|Cj)P(Cj) 最大值。
    我们假定 Ai 之间是相互独立的,那么: P(A1A2A3|Cj)=P(A1|Cj)P(A2|Cj)P(A3|Cj)
    然后我们需要从 Ai 和 Cj 中计算出 P(Ai|Cj) 的概率,带入到上面的公式得出 P(A1A2A3|Cj),最后找到使得 P(A1A2A3|Cj) 最大的类别 Cj。
    我分别求下这些条件下的概率:
    P(A1|C1)=1/2, P(A2|C1)=1/2, P(A3|C1)=1/4,P(A1|C2)=0, P(A2|C2)=1/2, P(A3|C2)=1/2,所以 P(A1A2A3|C1)=1/16, P(A1A2A3|C2)=0。
    因为 P(A1A2A3|C1)P(C1)>P(A1A2A3|C2)P(C2),所以应该是 C1 类别,即男性。
    总结:分别计算两种结果的概率,取最大
    连续数据案例
    实际生活中我们得到的是连续的数值,比如下面这组数据:
    那么如果给你一个新的数据,身高 180、体重 120,鞋码 41,请问该人是男是女呢?
    公式还是上面的公式,这里的困难在于,由于身高、体重、鞋码都是连续变量,不能采用离散变量的方法计算概率。而且由于样本太少,所以也无法分成区间计算。怎么办呢?
    这时,可以假设男性和女性的身高、体重、鞋码都是正态分布,通过样本计算出均值和方差,也就是得到正态分布的密度函数。有了密度函数,就可以把值代入,算出某一点的密度函数的值。比如,男性的身高是均值 179.5、标准差为 3.697 的正态分布。所以男性的身高为 180 的概率为 0.1069。怎么计算得出的呢? 你可以使用 EXCEL 的 NORMDIST(x,mean,standard_dev,cumulative) 函数,一共有 4 个参数:
    x:正态分布中,需要计算的数值;
    Mean:正态分布的平均值;
    Standard_dev:正态分布的标准差;
    Cumulative:取值为逻辑值,即 False 或 True。它决定了函数的形式。当为 TRUE 时,函数结果为累积分布;为 False 时,函数结果为概率密度。
    这里我们使用的是 NORMDIST(180,179.5,3.697,0)=0.1069。
    同理我们可以计算得出男性体重为 120 的概率为 0.000382324,男性鞋码为 41 号的概率为 0.120304111。
    所以我们可以计算得出:
    P(A1A2A3|C1)=P(A1|C1)P(A2|C1)P(A3|C1)=0.10690.000382324 0.120304111=4.9169e-6
    同理我们也可以计算出来该人为女的可能性:
    P(A1A2A3|C2)=P(A1|C2)P(A2|C2)P(A3|C2)=0.00000147489 0.015354144 0.120306074=2.7244e-9
    很明显这组数据分类为男的概率大于分类为女的概率。
    4.朴素贝叶斯分类器工作流程
    朴素贝叶斯分类常用于文本分类,尤其是对于英文等语言来说,分类效果很好。它常用于垃圾文本过滤、情感预测、推荐系统等。
    朴素贝叶斯分类器需要三个流程,我来给你一一讲解下这几个流程。
    第一阶段:准备阶段
    在这个阶段我们需要确定特征属性,比如上面案例中的“身高”、“体重”、“鞋码”等,并对每个特征属性进行适当划分,然后由人工对一部分数据进行分类,形成训练样本。
    这一阶段是整个朴素贝叶斯分类中唯一需要人工完成的阶段,其质量对整个过程将有重要影响,分类器的质量很大程度上由特征属性、特征属性划分及训练样本质量决定。
    第二阶段:训练阶段
    这个阶段就是生成分类器,主要工作是计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率。
    输入是特征属性和训练样本,输出是分类器。
    第三阶段:应用阶段
    这个阶段是使用分类器对新数据进行分类。输入是分类器和新数据,输出是新数据的分类结果。
    好了,在这次课中你了解了概率论中的贝叶斯原理,朴素贝叶斯的工作原理和工作流程,也对朴素贝叶斯的强大和限制有了认识。下一节中,我将带你实战,亲自掌握 Python 中关于朴素贝叶斯分类器工具的使用。
    5.实例

    #!/usr/bin/python3
    # -*- coding:utf-8 -*-
    
    from sklearn.feature_extraction.text import TfidfVectorizer
    import math
    import nltk
    
    tfidf_vec = TfidfVectorizer()
    
    documents = [
        'this is the bayes document',
        'this is the second second document',
        'and the third one',
        'is this the document'
    ]
    tfidf_matrix = tfidf_vec.fit_transform(documents)
    
    
    print('不重复的词:', tfidf_vec.get_feature_names())
    
    print('每个单词的 ID:', tfidf_vec.vocabulary_)
    
    print('每个单词的 tfidf 值:\n', tfidf_matrix.toarray())#document和分词id的矩阵
    
    
    # word_list = nltk.word_tokenize(documents[1]) # 分词
    # print (nltk.pos_tag(word_list))
    print (math.log(8,2))
    
    
    
    import  jieba
    
    txt = open("1.txt", "r", encoding='utf-8').read()
    words = jieba.lcut(txt)     # 使用精确模式对文本进行分词
    counts = {}     # 通过键值对的形式存储词语及其出现的次数
    
    for word in words:
        if  len(word) == 1:    # 单个词语不计算在内
            continue
        else:
            counts[word] = counts.get(word, 0) + 1    # 遍历所有词语,每出现一次其对应的值加 1
            
    items = list(counts.items())#将键值对转换成列表
    items.sort(key=lambda x: x[1], reverse=True)    # 根据词语出现的次数进行从大到小排序
    
    for i in range(15):
        word, count = items[i]
        print("{0:<5}{1:>5}".format(word, count))
    
    
    seg_str = "贝叶斯原理是英国数学家托马斯·贝叶斯提出的。贝叶斯是个很神奇的人,他的经历类似梵高。生前没有得到重视,死后,他写的一篇关于归纳推理的论文被朋友翻了出来,并发表了。这一发表不要紧,结果这篇论文的思想直接影响了接下来两个多世纪的统计学,是科学史上著名的论文之一。贝叶斯原理跟我们的生活联系非常紧密。举个例子,如果你看到一个人总是花钱,那么会推断这个人多半是个有钱人。当然这也不是绝对,也就是说,当你不能准确预知一个事物本质的时候,你可以依靠和事物本质相关的事件来进行判断,如果事情发生的频次多,则证明这个属性更有可能存在。   "
    
    print("|".join(jieba.lcut(seg_str)))    # 精简模式,返回一个列表类型的结果
    print("|".join(jieba.lcut(seg_str, cut_all=True)))      # 全模式,使用 'cut_all=True' 指定 
    print("|".join(jieba.lcut_for_search(seg_str)))     # 搜索引擎模式
    
    
    
    
    # from nltk.corpus import PlaintextCorpusReader
    # #corpus_root = 'D://Data//nltk_data//CorpusData'   #//不会产生转义  【语料库路径】
    # corpus_root = r"D:\Data\nltk_data\CorpusData"      #r""防止转义         【语料库路径】 
    # file_pattern=['comment4.txt','comment5.txt']       #【txt文件名】
    # pcrText = PlaintextCorpusReader(corpus_root,file_pattern)   #nltk的本地语料库加载方法
    # pcrText.fileids()                                  #输出目录下所有文件名
    # pcrText.words('comment4.txt')
    

    sklearn 的全称叫 Scikit-learn,它给我们提供了 3 个朴素贝叶斯分类算法,分别是高斯朴素贝叶斯(GaussianNB)、多项式朴素贝叶斯(MultinomialNB)和伯努利朴素贝叶斯(BernoulliNB)。

    这三种算法适合应用在不同的场景下,我们应该根据特征变量的不同选择不同的算法:
    高斯朴素贝叶斯 :特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度。
    多项式朴素贝叶斯 :特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的 TF-IDF 值等。
    伯努利朴素贝叶斯 :特征变量是布尔变量,符合 0/1 分布,在文档分类中特征是单词是否出现。
    伯努利朴素贝叶斯是以文件为粒度,如果该单词在某文件中出现了即为 1,否则为 0。而多项式朴素贝叶斯是以单词为粒度,会计算在某个文件中的具体次数。而高斯朴素贝叶斯适合处理特征变量是连续变量,且符合正态分布(高斯分布)的情况。比如身高、体重这种自然界的现象就比较适合用高斯朴素贝叶斯来处理。而文本分类是使用多项式朴素贝叶斯或者伯努利朴素贝叶斯。

    伯努利分布:只有两种结果的概率分布,bool,比如抛硬币
    二项式分布:简单的抛硬币试验就是伯努利试验,在一次试验中硬币要么正面朝上,要么反面朝上,每次正面朝上的概率都一样p=0.5,且每次抛硬币的事件相互独立,即每次正面朝上的概率不受其他试验的影响。如果独立重复抛n=10次硬币,正面朝上的次数k可能为0,1,2,3,4,5,6,7,8,9,10中的任何一个,那么k显然是一个随机变量,这里就称随机变量k服从二项分布。
    多项式分布:把二项分布公式再推广,就得到了多项分布。比如扔骰子,不同于扔硬币,骰子有6个面对应6个不同的点数,这样单次每个点数朝上的概率都是1/6(对应p1~p6,它们的值不一定都是1/6,只要和为1且互斥即可,比如一个形状不规则的骰子),重复扔n次,如果问有x次都是点数6朝上的概率就是:C(n,x)p6x*(1-p6)(n-x)
    什么是 TF-IDF 值呢?
    我在多项式朴素贝叶斯中提到了“词的 TF-IDF 值”,如何理解这个概念呢?
    TF-IDF 是一个统计方法,用来评估某个词语对于一个文件集或文档库中的其中一份文件的重要程度。
    TF-IDF 实际上是两个词组 Term Frequency 和 Inverse Document Frequency 的总称,两者缩写为 TF 和 IDF,分别代表了词频和逆向文档频率。
    词频 TF 计算了一个单词在文档中出现的次数,它认为一个单词的重要性和它在文档中出现的次数呈正比。
    逆向文档频率 IDF ,是指一个单词在文档中的区分度。它认为一个单词出现在的文档数越少,就越能通过这个单词把该文档和其他文档区分开。IDF 越大就代表该单词的区分度越大。
    所以 TF-IDF 实际上是词频 TF 和逆向文档频率 IDF 的乘积 。这样我们倾向于找到 TF 和 IDF 取值都高的单词作为区分,即这个单词在一个文档中出现的次数多,同时又很少出现在其他文档中。这样的单词适合用于分类。
    TF-IDF 如何计算
    首先我们看下词频 TF 和逆向文档概率 IDF 的公式。
    为什么 IDF 的分母中,单词出现的文档数要加 1 呢?因为有些单词可能不会存在文档中,为了避免分母为 0,统一给单词出现的文档数都加 1。
    TF-IDF=TF
    IDF。
    你可以看到,TF-IDF 值就是 TF 与 IDF 的乘积, 这样可以更准确地对文档进行分类。比如“我”这样的高频单词,虽然 TF 词频高,但是 IDF 值很低,整体的 TF-IDF 也不高。
    我在这里举个例子。假设一个文件夹里一共有 10 篇文档,其中一篇文档有 1000 个单词,“this”这个单词出现 20 次,“bayes”出现了 5 次。“this”在所有文档中均出现过,而“bayes”只在 2 篇文档中出现过。我们来计算一下这两个词语的 TF-IDF 值。
    针对“this”,计算 TF-IDF 值:
    所以 TF-IDF=0.02*(-0.0414)=-8.28e-4。
    针对“bayes”,计算 TF-IDF 值:

    很明显“bayes”的 TF-IDF 值要大于“this”的 TF-IDF 值。这就说明用“bayes”这个单词做区分比单词“this”要好。
    如何求 TF-IDF
    在 sklearn 中我们直接使用 TfidfVectorizer 类,它可以帮我们计算单词 TF-IDF 向量的值。在这个类中,取 sklearn 计算的对数 log 时,底数是 e,不是 10。
    下面我来讲下如何创建 TfidfVectorizer 类。
    TfidfVectorizer 类的创建:
    创建 TfidfVectorizer 的方法是:
    1 TfidfVectorizer(stop_words=stop_words, token_pattern=token_pattern)
    我们在创建的时候,有两个构造参数,可以自定义停用词 stop_words 和规律规则 token_pattern。需要注意的是传递的数据结构,停用词 stop_words 是一个列表 List 类型,而过滤规则 token_pattern 是正则表达式。
    什么是停用词?停用词就是在分类中没有用的词,这些词一般词频 TF 高,但是 IDF 很低,起不到分类的作用。为了节省空间和计算时间,我们把这些词作为停用词 stop words,告诉机器这些词不需要帮我计算。
    当我们创建好 TF-IDF 向量类型时,可以用 fit_transform 帮我们计算,返回给我们文本矩阵,该矩阵表示了每个单词在每个文档中的 TF-IDF 值。
    在我们进行 fit_transform 拟合模型后,我们可以得到更多的 TF-IDF 向量属性,比如,我们可以得到词汇的对应关系(字典类型)和向量的 IDF 值,当然也可以获取设置的停用词 stop_words。
    举个例子,假设我们有 4 个文档:
    文档 1:this is the bayes document;
    文档 2:this is the second second document;
    文档 3:and the third one;
    文档 4:is this the document。
    现在想要计算文档里都有哪些单词,这些单词在不同文档中的 TF-IDF 值是多少呢?
    首先我们创建 TfidfVectorizer 类:
    1 from sklearn.feature_extraction.text import TfidfVectorizer
    2 tfidf_vec = TfidfVectorizer()
    然后我们创建 4 个文档的列表 documents,并让创建好的 tfidf_vec 对 documents 进行拟合,得到 TF-IDF 矩阵:
    1 documents = [
    2 ‘this is the bayes document’,
    3 ‘this is the second second document’,
    4 ‘and the third one’,
    5 ‘is this the document’
    6 ]
    7 tfidf_matrix = tfidf_vec.fit_transform(documents)
    输出文档中所有不重复的词:
    1 print(‘不重复的词:’, tfidf_vec.get_feature_names())
    运行结果
    1 不重复的词: [‘and’, ‘bayes’, ‘document’, ‘is’, ‘one’, ‘second’, ‘the’, ‘third’, ‘this’]
    输出每个单词对应的 id 值:
    1 print(‘每个单词的 ID:’, tfidf_vec.vocabulary_)
    运行结果
    1 每个单词的 ID: {‘this’: 8, ‘is’: 3, ‘the’: 6, ‘bayes’: 1, ‘document’: 2, ‘second’: 5, ‘and’: 0, ‘third’: 7, ‘one’: 4}
    输出每个单词在每个文档中的 TF-IDF 值,向量里的顺序是按照词语的 id 顺序来的:
    1 print(‘每个单词的 tfidf 值:’, tfidf_matrix.toarray())
    运行结果:
    1 每个单词的 tfidf 值: [[0. 0.63314609 0.40412895 0.40412895 0. 0.
    2 0.33040189 0. 0.40412895]
    3 [0. 0. 0.27230147 0.27230147 0. 0.85322574
    4 0.22262429 0. 0.27230147]
    5 [0.55280532 0. 0. 0. 0.55280532 0.
    6 0.28847675 0.55280532 0. ]
    7 [0. 0. 0.52210862 0.52210862 0. 0.
    8 0.42685801 0. 0.52210862]]

    1. 对文档分类
      如果我们要对文档进行分类,有两个重要的阶段:
      1.基于分词的数据准备 ,包括分词、单词权重计算、去掉停用词;
      2.应用朴素贝叶斯分类进行分类 ,首先通过训练集得到朴素贝叶斯分类器,然后将分类器应用于测试集,并与实际结果做对比,最终得到测试集的分类准确率。
      下面,我分别对这些模块进行介绍。

    step 1:对文档进行分词
    在准备阶段里,最重要的就是分词。那么如果给文档进行分词呢?英文文档和中文文档所使用的分词工具不同。
    在英文文档中,最常用的是 NTLK 包。NTLK 包中包含了英文的停用词 stop words、分词和标注方法。
    1 import nltk
    2 word_list = nltk.word_tokenize(text) # 分词
    3 nltk.pos_tag(word_list) # 标注单词的词性
    在中文文档中,最常用的是 jieba 包。jieba 包中包含了中文的停用词 stop words 和分词方法。
    import jieba
    word_list = jieba.cut (text) # 中文分词

    step 2:加载停用词表
    我们需要自己读取停用词表文件,从网上可以找到中文常用的停用词保存在 stop_words.txt,然后利用 Python 的文件读取函数读取文件,保存在 stop_words 数组中。
    1 stop_words = [line.strip().decode(‘utf-8’) for line in io.open(‘stop_words.txt’).readlines()]

    step 3:计算单词的权重
    这里我们用到 sklearn 里的 TfidfVectorizer 类,上面我们介绍过它使用的方法。
    直接创建 TfidfVectorizer 类,然后使用 fit_transform 方法进行拟合,得到 TF-IDF 特征空间 features,你可以理解为选出来的分词就是特征。我们计算这些特征在文档上的特征向量,得到特征空间 features。
    1 tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)
    2 features = tf.fit_transform(train_contents)
    这里 max_df 参数用来描述单词在文档中的最高出现率。假设 max_df=0.5,代表一个单词在 50% 的文档中都出现过了,那么它只携带了非常少的信息,因此就不作为分词统计。
    一般很少设置 min_df,因为 min_df 通常都会很小。

    step 4:生成朴素贝叶斯分类器
    我们将特征训练集的特征空间 train_features,以及训练集对应的分类 train_labels 传递给贝叶斯分类器 clf,它会自动生成一个符合特征空间和对应分类的分类器。
    这里我们采用的是多项式贝叶斯分类器,其中 alpha 为平滑参数。为什么要使用平滑呢?因为如果一个单词在训练样本中没有出现,这个单词的概率就会被计算为 0。但训练集样本只是整体的抽样情况,我们不能因为一个事件没有观察到,就认为整个事件的概率为 0。为了解决这个问题,我们需要做平滑处理。
    当 alpha=1 时,使用的是 Laplace 平滑。Laplace 平滑就是采用加 1 的方式,来统计没有出现过的单词的概率。这样当训练样本很大的时候,加 1 得到的概率变化可以忽略不计,也同时避免了零概率的问题。
    当 0<alpha<1 时,使用的是 Lidstone 平滑。对于 Lidstone 平滑来说,alpha 越小,迭代次数越多,精度越高。我们可以设置 alpha 为 0.001。

    多项式贝叶斯分类器

    1 from sklearn.naive_bayes import MultinomialNB
    2 clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)
    拉普拉斯变换:傅里叶变换是将函数分解到频率不同、幅值恒为1的单位圆上;拉普拉斯变换是将函数分解到频率幅值都在变化的圆上。因为拉普拉斯变换的基有两个变量,因此更灵活,适用范围更广。
    step 5:使用生成的分类器做预测
    首先我们需要得到测试集的特征矩阵。
    方法是用训练集的分词创建一个 TfidfVectorizer 类,使用同样的 stop_words 和 max_df,然后用这个 TfidfVectorizer 类对测试集的内容进行 fit_transform 拟合,得到测试集的特征矩阵 test_features。
    1 test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=train_vocabulary)
    2 test_features=test_tf.fit_transform(test_contents)

    然后我们用训练好的分类器对新数据做预测。
    方法是使用 predict 函数,传入测试集的特征矩阵 test_features,得到分类结果 predicted_labels。predict 函数做的工作就是求解所有后验概率并找出最大的那个。
    1 predicted_labels=clf.predict(test_features)

    模块 6:计算准确率
    计算准确率实际上是对分类模型的评估。我们可以调用 sklearn 中的 metrics 包,在 metrics 中提供了 accuracy_score 函数,方便我们对实际结果和预测的结果做对比,给出模型的准确率。
    使用方法如下:
    1 from sklearn import metrics
    2 print metrics.accuracy_score(test_labels, predicted_labels)

    展开全文
  • TD-IDF

    2020-05-15 14:39:38
    什么是 TF-IDF 算法? 简单来说,向量空间模型就是希望把查询关键字和文档都表达成向量,然后利用向量之间的运算来进一步表达向量间的关系。比如,一个比较常用的运算就是计算查询关键字所对应的向量和文档所对应的...
  • gensim 之 td-idf和lsi模型

    千次阅读 2017-06-27 18:06:51
    gensim官方文档: ...td-idf模型上文已介绍: http://blog.csdn.net/m0_37681914/article/details/73781494gensim的LSI模型训练建立在td-idf之上,用来解决潜在语义,详情可以参考 htt
  • 通过python代码实现TF-IDF算法,并对文本提取关键词,可以自己添加词库以及停用词表。
  • td-idf理解

    2021-02-18 10:14:14
    TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。TF是词频(Term Frequency),IDF是逆文本频率指数(Inverse Document Frequency)。 公式(个人理解版) 以二维...
  • TF-IDF介绍(原来+代码)

    千次阅读 2019-06-26 21:56:38
    概念1、TF-IDF原理 无论中文文本还是英文文本,都要首先对文本进行分词处理,而后需要对文本进行词向量表示。
  • 通过规范审稿人情绪来改善Yelp审阅体验 球队: 安吉拉·德特威勒(Angela Detweiler) 熙熙 林 贝瑟斯特·莫斯塔格尼(Behesteh ...TD-IDF 线性回归 库: 脾气暴躁的 西皮 Scikit_学习 大熊猫 Matplotlib NLTK
  • TF-IDF算法概述及模型构建

    千次阅读 2019-06-01 19:25:16
    1.应用场景 我在构建搜索引擎的时候,需要构建一个排名算法。我最初版本的做法为,根据一篇文章中词汇出现的频率,对各个网页进行排序。...TF-IDF值(搜索词的重要性),随着单词在文件中出现的次数成正比增加,但同...
  • java实现 tf-idf

    2021-02-13 00:18:57
    }/*** @Author:sks * @Description:设置idf * @Date: * @docmentTotalCount:资料库中文档总数*/ private static void setIdf(int docmentTotalCount) throwsSolrServerException,IOException { Map map =...
  • TF-IDF算法详解

    万次阅读 多人点赞 2018-08-06 14:04:48
    最近在做一些NLP的研究,由于也是第一次做这个东西,其实还是发现很多有意思的东西。 相信很多做过NLP的人都应该接触过提取关键词...首先我们来了解一下什么是TF-IDF? 其实这个是两个词的组合,可以拆分为TF和...
  • 在信息检索理论中,TF-IDF 是 Term Frequency - Inverse Document Frequency 的简写。TF-IDF 是一种数值统计,用于反映一个词对于语料中某篇文档的重要性。在信息检索和文本挖掘领域,它经常用于因子加权。TF-IDF 的...
  • tf-idf矩阵 词频-逆向文本频率,是一种用于信息检索和文本挖掘的常用加权技术。 TF(词频) 某一个给定的词语在该文件中出现的频率。 IDF(逆向文本频率) 总文件数目除以包含该词语之文件的数目,再将得到的商取以...
  • 文章目录1、关键词提取2、TF-IDF算法原理3、编程实例 1、关键词提取  关键词是指能反映文本主题或者主要内容的词语。关键词提取就是从文本里面把跟这篇文档意义最相关的一些词抽取出来,是NLP领域的一个重要的子...
  • 解释 TF(Term Frequency,缩写为TF):词频,某一词条(item)出现的频度。为归一化要除以该篇文档的所有item。 TF=TF=TF= IDF(Inverse Document Frequency,缩写为IDF):逆文本频率。公式如下 ...
  • 根据tf-idf的结果 为每部电影筛选出top-n(td-idf较大)个关键词 电影id-关键词-关键词权重 建立倒排索引 通过关键词找到电影 遍历 电影id-关键词-关键词权重 读取每一个关键词,用关键词作为key [(关键词对应...
  • TF(Term Frequency)词频,在文章中出现次数...该权重为IDF(Inverse Document Frequency)逆文档频率,它的大小与一个词的常见程度成反比。在我们得到词频(TF)和逆文档频率(IDF)以后,将两个值相乘,即可得...
  • TF-IDF特征优缺点

    千次阅读 2020-04-14 15:16:49
    标准的TF-IDF公式如下(—后的文字表示说明): 优点:简单、快速 缺点: 仅以“词频”度量词的重要性,后续构成文档的特征值序列,词之间各自独立,无法反映序列信息; 易受数据集偏斜的影响,如某一类别的文档偏...
  • TF-IDF的词嵌入自我理解TF-IDF原理解析及公式TF代码实现:IDF代码实现:最后的向量表示:main函数部分: TF-IDF原理解析及公式 TF-IDF技术是一种基于词的出现频率和词对于文档的不同重要程度而设立的一种模型, 其核心就...
  • 利用TF-IDF进行文本向量特征的处理

    千次阅读 2019-04-18 19:48:04
    TF−IDF(x)=TF(x)∗IDF(x)TF−IDF(x)=TF(x)∗IDF(x)  其中TF(x)TF(x)指词xx在当前文本中的词频。 3. 用scikit-learn进行TF-IDF预处理  在scikit-learn中,有两种方法进行TF-IDF的预处理。  完整代码...
  • 利用gensim计算tf-idf

    千次阅读 2019-10-07 17:17:32
    make_tf_idf_model ( corpus , model_path ) : word_list = [ ] if not os . path . exists ( model_path ) : os . makedirs ( model_path ) for i in range ( len ( corpus ) ) : word_list ...
  • tfidfi=tf∗idf=词i的数量词语总数∗log总文档数包含词i的文档数 tfidf_i = tf*idf = \cfrac{词i的数量}{词语总数}*log\cfrac{总文档数}{包含词i的文档数} tfidfi​=tf∗idf=词语总数词i的数量​∗log包含词i的文档...
  • TF-IDF实现关键词提取

    千次阅读 2018-11-12 10:03:30
    TF-IDF方法简介 TF-IDF,实际上是两个部分:TF和IDF的乘积。下面分别对两个次解释。 TF:词频。简单理解,就是词语在文章中出现的频率。计算方法也很简单: 即文档i中词语j的词频等于词语j在文档i中的出现次数n...
  • 自然语言处理——TF-IDF文本表示

    千次阅读 多人点赞 2020-08-11 23:20:49
    本文介绍了TF-IDF的原理以及Python实现。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 861
精华内容 344
关键字:

td-idf