分享

文本自动分类

 昵称597197 2014-03-24

使用机器学习方法 做文档的自动分类

套路:

1.根据每个文件 生成该文件的一个特征

2.根据特征 选择 分类器 进行文本分类

3.(可选)根据 2 步结果,调整参数/特征等


示例:

数据:搜狗文本分类语料库 精简版

分类器:朴素贝叶斯

编程语言:Python+nltk自然语言处理库+jieba分词库

[python] view plaincopy
  1. __author__ = 'LiFeiteng'  
  2. # -*- coding: utf-8 -*-  
  3. import os  
  4. import  jieba  
  5. import nltk  
  6.   
  7.   
  8. ## 由搜狗语料库 生成数据  
  9. folder_path = 'C:\LIFEITENG\SogouC.reduced\\Reduced'  
  10. #folder_path = 'C:\LIFEITENG\SogouC.mini\Sample'  
  11. folder_list = os.listdir(folder_path)  
  12. class_list = [] ##由于乱码等问题 仅以数字[0,1,...]来代表文件分类  
  13. nClass = 0  
  14. N = 100 #每类文件 最多取 100 个样本 70%train 30%test  
  15. train_set = []  
  16. test_set = []  
  17. all_words = {}  
  18. import time  
  19. process_times = [] ## 统计处理每个文件的时间  
  20. for i in range(len(folder_list)):  
  21.     new_folder_path = folder_path + '\\' + folder_list[i]  
  22.     files = os.listdir(new_folder_path)  
  23.     class_list.append(nClass)  
  24.     nClass += 1  
  25.     j = 0  
  26.     nFile = min([len(files), N])  
  27.     for file in files:  
  28.         if j > N:  
  29.             break  
  30.         starttime = time.clock()  
  31.   
  32.         fobj = open(new_folder_path+'\\'+file, 'r')  
  33.         raw = fobj.read()  
  34.         word_cut = jieba.cut(raw, cut_all=False)  
  35.         word_list = list(word_cut)  
  36.         for word in word_list:  
  37.             if word in all_words.keys():  
  38.                 all_words[word] += 1  
  39.             else:  
  40.                 all_words[word] = 0  
  41.         if j > 0.3 * nFile:  
  42.             train_set.append((word_list, class_list[i]))  
  43.         else:  
  44.             test_set.append((word_list, class_list[i]))  
  45.         j += 1  
  46.         endtime = time.clock()  
  47.         process_times.append(endtime-starttime)  
  48.   
  49.         print "Folder ",i,"-file-",j, "all_words length = ", len(all_words.keys()),\  
  50.             "process time:",(endtime-starttime)  
  51.   
  52.   
  53. print len(all_words)  
  54.   
  55. ## 根据word的词频排序  
  56. all_words_list = sorted(all_words.items(), key=lambda e:e[1], reverse=True)  
  57. word_features = []  
  58. ## 由于乱码的问题,没有正确使用 stopwords;简单去掉 前100个高频项  
  59. ## word_features 是选用的 word-词典  
  60. for t in range(10011001):  
  61.     word_features.append(all_words_list[t][0])  
  62.   
  63. def document_features(document):  
  64.     document_words = set(document)  
  65.     features = {}  
  66.     for word in word_features: ## 根据词典生成 每个document的feature True or False  
  67.         features['contains(%s)' % word] = (word in document_words)  
  68.     return features  
  69.   
  70. ## 根据每个document 分词生成的 word_list 生成 feature  
  71. train_data = [(document_features(d), c) for (d,c) in train_set]  
  72. test_data = [(document_features(d), c) for (d,c) in test_set]  
  73. print "train number:",len(train_data),"\n test number:",len(test_data)  
  74.   
  75. ## 朴素贝叶斯分类器  
  76. classifier = nltk.NaiveBayesClassifier.train(train_data)  
  77. print "test accuracy:",nltk.classify.accuracy(classifier, test_data)  
  78.   
  79. ## 处理每个文件所用的时间 可见到后面 处理单个文件的时间显著增长  
  80. ## 原因 已查明  
  81. import pylab  
  82. pylab.plot(range(len(process_times)), process_times, 'b.')  
  83. pylab.show()  
test上的正确率: 9个类别 74%


处理每个文件所用时间:



===============================

朴素贝叶斯:From 《数据挖掘概念与技术》



1.中文乱码问题,由于这个问题,在stopwords上简单去掉 前100个高频项 数据清洗不足

2.字典的选择上——简单以统计 所有文件词频,选用101-1100 1000个词作字典

   我觉得 字典完全可以从 数据上 学习(要比上面方法高明些),就像在图像处理中 稀疏模型 学习字典(KSVD)一样

   自然语言处理/文本处理 中也应该存在这样的方法

3.文件的特征 是[0,0,1,0,0,1,...]并不是统计每个文件的词频,

   这跟选择的分类器相关,如果选择svm等 就要对文件 生成词频特征

4.到后面(见上图),单个文件处理时间显著增长,原因待查明——已查明 if word in all_words.keys(): 改为all_words.has_key(word)


以 机器学习 的小无相功 打了一套 自然语言处理/文本挖掘 的招数

难免有些生硬  望专家指点

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多