Rocchio算法

向量空间模型的思想是把文档简化为特征项的权重为分量的向量表示,其中选取词作为特征项,权重用词频表示。

其主要用的是TF-IDF算法来计算:TF(词频)是一个词语出现的次数除以该文件的总词语数。IDF(文件频率)的方法是测定有多少文件出现过某个词,然后除以文件集里的文件数。注意这里IDF用的是逆向文件频率,即假如“汽车”一词在100份文件中出现过,总文件数是10000份,这时的逆向文件频率为log10(10000/100)=2log10(10000/100)=2,而得到的TF是0.05,此时的TF-IDF分数为0.05x2=0.1。

也即是,如果某个词在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为这个词有很好的类别区分能力,适合用来分类;IDF表示含有该词汇的文档,比例越低IDF越大,则说明该词汇具有良好的类别区分能力。

1. Rocchio算法

Rocchio算法是一种非常直观的文本分类算法。其核心思路是给每一个文档的类别都做一个的标准向量(也称为原型向量),然后用待分类的文档的向量和这个标准向量对比一下余弦相似度,相似度越高越可能属于该分类,反之亦然。

例如:在新闻网站中希望构造一个自动的文章分类系统,然后先收集10000个样本,然后由人给每篇文章划分类别,然后把每个类别里的每篇文章逐个拿出来做分词和向量化,这样每个类别里的每篇文章都有一个非常长的向量模型。再把得到的每个类别的所有文章进行维度的平均(词频的平均),得到的这个原型向量称为“质心”。当有一篇新的文章要分类时也同样进行分词和向量化,下面就是余弦相似度的计算了。cos(θ)cos(θ)越接近1说明越相似,越接近0就说明越不相似,这里不存在小于0的情况。

这里要注意的是文本挖掘里的使用的向量和其他的向量使用有所不同,这里的维度数会因文本的不同而不同,而且这里维度的值不是枚举类型,是0—1的区间内的数。

2. 学习20newsgroups案例

20新闻组数据集是一个接近被2000个新闻组文档的集合,它是由Ken Lang收集的,也许是为了他的论文:”Newsweeder:学习过滤新闻”,尽管他没有明确的提到这个数据集.20新闻组集合在机器学习技术中的文本应用实验中已经成为一个流行的数据集.

数据的采集有两种方法,这里简单介绍下:

2.1 scikit-learn:加载本地的原始数据

可以先下载好数据集,然后使用sklearn.datasets.load_files函数加载解压缩文件夹内的子文件夹。

sklearn.datasets.load_files(container_path, description=None, categories=None,load_content=True, shuffle=True, encoding=None, decode_error='strict', random_state=0)
 
 
  • 1

部分参数说明:container_path,load_content=True,encoding=None

  • container_path:“container_folder”的路径。
  • load_content=True:是否真的把文件中的内容加载到内存中,选择true就是了。
  • encoding=None:string or None (default is None),是否解码文件中的内容(主要针对图片、视频或其他二进制文件,而非文本内容);如果不是None,那么在load_content=True的情况下,就会解码文件中的内容。注意,当前文本文件的编码方式一般为“utf-8”。如果不指明编码方式(encoding=None),那么文件内容将会按照bytes处理,而不是unicode处理,这样模块“sklearn.feature_extraction.tex”中的很多函数就不能用了。

返回值:data : Bunch

值得注意的:

data:原始数据
filenames:每个文件的名字
target:类别标签(从0开始的整数索引)
target_names:类别标签(数字)的具体含义(由子文件夹的名字决定)

简单示例:
这里以加载20个新闻组数据集为例,提前把数据集下载好,放于和运行文件的同一个目录下。

这里写图片描述

代码:

from sklearn import datasets

# 读取训练集
newsgroups_train = datasets.load_files("20news-bydate-train")
pprint(list(newsgroups_train.target_names))
print (len(newsgroups_train.target_names))
 
 

    运行结果:

    >>> 
    ==== RESTART: C:\Users\LiLong\Desktop\test_now\naive_bayes_multinomial.py ====
    ['alt.atheism',
     'comp.graphics',
     'comp.os.ms-windows.misc',
     'comp.sys.ibm.pc.hardware',
     'comp.sys.mac.hardware',
     'comp.windows.x',
     'misc.forsale',
     'rec.autos',
     'rec.motorcycles',
     'rec.sport.baseball',
     'rec.sport.hockey',
     'sci.crypt',
     'sci.electronics',
     'sci.med',
     'sci.space',
     'soc.religion.christian',
     'talk.politics.guns',
     'talk.politics.mideast',
     'talk.politics.misc',
     'talk.religion.misc']
    
    
    
    
    
    2.2 在线下载数据集

    我们也可以使用scikit-learn自带的toy example数据集进行测试,介绍一下如何加载自带的数据集。

    可以使用sklearn.datasetsfetch_20newsgroups进行在线的自动下载。

    函数原型:

    fetch_20newsgroups(data_home=None,subset='train',categories=None,shuffle=True,random_state=42,remove=(),download_if_missing=True)
    
      
      
      • data_home:指的是数据集的地址,如果默认的话,所有的数据都会在’~/scikit_learn_data’文件夹下.
      • subset:就是train,test,all三种可选,分别对应训练集、测试集和所有样本。
      • categories:是指类别,如果指定类别,就会只提取出目标类,如果是默认,则是提取所有类别出来。
      • shuffle:是否打乱样本顺序,如果是相互独立的话。
      • random_state:打乱顺序的随机种子
      • remove:是一个元组,用来去除一些停用词的,例如标题引用之类的。
      • download_if_missing: 如果数据缺失,是否去下载。

      注意:在线的下载会花费一段时间,如果你担心程序死掉了,可以打开在线下载文件的保存目录:C:\Users\lilong\scikit_learn_data\20news_home,这个文件夹下就是在线下载的保存目录,观察这个文件夹你会发现文件在一个一个增加,最后下载完成后压缩包文件和解压的文件都会被自动删除,最后只剩下20news-bydate_py3.pkz文件了,这里暂且看作是程序运行后内存可以读取的文件。

      这里写图片描述

      2.3 完整代码

      #coding=utf-8
      from sklearn.datasets import fetch_20newsgroups
      from sklearn.feature_extraction.text import CountVectorizer
      from sklearn.feature_extraction.text import TfidfTransformer
      from sklearn.naive_bayes import MultinomialNB
      from pprint import pprint
      
      
      # 读取训练集
      
      newsgroups_train = fetch_20newsgroups(subset='train')
      pprint(list(newsgroups_train.target_names))
      '''
      newsgroups_train = datasets.load_files("20news-bydate-train")
      # 得到20个主题
      pprint(list(newsgroups_train.target_names))
      print (len(newsgroups_train.target_names))
      
      # 这里选取4个主题
      categories = ['rec.sport.baseball', 'alt.atheism', 'talk.politics.guns', 'sci.space']
      
      # 下载这4个主题
      twenty_train = fetch_20newsgroups(subset='train', categories=categories)
      print ('here..............')
      
      
      # 文件内容在twenty_train这个变量里,现在对内容进行分词和向量化操作
      count_vect = CountVectorizer()
      X_train_counts = count_vect.fit_transform(twenty_train.data)
      
      
      # 接着对向量化之后的结果做TF-IDF转换
      tfidf_transformer = TfidfTransformer()
      X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)
      
      
      # Rocchio的示例代码
      from sklearn.neighbors.nearest_centroid import NearestCentroid
      # 现在把TF-IDF转换后的结果和每条结果对应的主题编号twenty_train.target放入分类器进行训练
      clf = NearestCentroid().fit(X_train_tfidf, twenty_train.target)
      
      # 创建测试集合,这里有2条数据,每条数据一行内容,进行向量化和tf-idf转换
      docs_new = ['God is love', 'OpenGL on the GPU is fast']
      X_new_counts = count_vect.transform(docs_new)
      X_new_tfidf = tfidf_transformer.transform(X_new_counts)
      
      # 预测
      predicted = clf.predict(X_new_tfidf)
      
      # 打印结果
      for doc, category in zip(docs_new, predicted):
          print('%r => %s' % (doc, twenty_train.target_names[category]))

      运行结果:

      >>> 
      ==== RESTART: C:\Users\LiLong\Desktop\test_now\naive_bayes_multinomial.py ====
      ['alt.atheism',
       'comp.graphics',
       'comp.os.ms-windows.misc',
       'comp.sys.ibm.pc.hardware',
       'comp.sys.mac.hardware',
       'comp.windows.x',
       'misc.forsale',
       'rec.autos',
       'rec.motorcycles',
       'rec.sport.baseball',
       'rec.sport.hockey',
       'sci.crypt',
       'sci.electronics',
       'sci.med',
       'sci.space',
       'soc.religion.christian',
       'talk.politics.guns',
       'talk.politics.mideast',
       'talk.politics.misc',
       'talk.religion.misc']
      here..............
      'God is love' => alt.atheism
      'OpenGL on the GPU is fast' => sci.space
       
       

        注意这里的Rocchio算法的缺陷是很明显的,它做了两个假设,使得它的分类能力大大折扣。
        假设一:一个类别的文本仅仅聚集在一个质心的周围,实际情况往往不是。
        假设二:训练样本是绝对正确的,因为它没有任何的定量衡量样本是否含有噪声的机制,错误的分类会影响质心的位置。

        3. 笔记

        zip([iterable, …])函数使用:其中iterabl 代表一个或多个迭代器,zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
        如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

        >>>a = [1,2,3]
        >>> b = [4,5,6]
        >>> c = [4,5,6,7,8]
        >>> zipped = zip(a,b)     # 打包为元组的列表
        [(1, 4), (2, 5), (3, 6)]
        >>> zip(a,c)              # 元素个数与最短的列表一致
        [(1, 4), (2, 5), (3, 6)]
        >>> zip(*zipped)          # 与 zip 相反,可理解为解压,返回二维矩阵式
        [(1, 2, 3), (4, 5, 6)]
        • 0
          点赞
        • 1
          收藏
          觉得还不错? 一键收藏
        • 0
          评论

        “相关推荐”对你有帮助么?

        • 非常没帮助
        • 没帮助
        • 一般
        • 有帮助
        • 非常有帮助
        提交
        评论
        添加红包

        请填写红包祝福语或标题

        红包个数最小为10个

        红包金额最低5元

        当前余额3.43前往充值 >
        需支付:10.00
        成就一亿技术人!
        领取后你会自动成为博主和红包主的粉丝 规则
        hope_wisdom
        发出的红包
        实付
        使用余额支付
        点击重新获取
        扫码支付
        钱包余额 0

        抵扣说明:

        1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
        2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

        余额充值