机器学习笔记-文本分类(四)代码实现

在学习文本分类的时候发现主要有以下几个步骤,借助代码说明(代码大多参考:机器学习算法原理与编程实战,不过发现给的语料有些编码问题,并且本人用的是Python3.6+windows,所有进行了部分修改)。

主要步骤

  • 将训练集中的所有文本用jieba分词保存到另外一个文件
  • 统计分词后文本的TF-IDF,转化为词频向量
  • 去掉停用词
  • 应用sklearn分类

文档分词

这个是一层层进入文件,然后将结果又一层层保存到文件,原文档如下结构


Paste_Image.png

需要分词的文档是这种三级结构,分词后也是的到对应的三级结构。

统计文本的TF-IDF,这用到sklearn中的函数,直接见代码注释,我发现在pycharm中调试代码,就能很好理解这些sklearn中的函数了,一目了然

Paste_Image.png

Paste_Image.png

测试集

文中的测试集是每个种类抽取十来个文本,当然标签页带上,上图的“环境200”,“计算机200” 就是类别标签(数字指里面的文档数,我直接带上了)。如图,测试集(我手动添加的测试集),然后搞了掉小动作,故意将一篇文档放错到别的类别文件夹中。

Paste_Image.png

代码实现

代码能全部执行,环境是Python3,需要安装sklearn(前面介绍了安装),还需要更改文件路径

import jieba
import os
import pickle   #持久化
from numpy import *
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer #TF-IDF向量转换类
from sklearn.feature_extraction.text import TfidfVectorizer #TF_IDF向量生成类
from sklearn.datasets.base import Bunch
from sklearn.naive_bayes import MultinomialNB #多项式贝叶斯算法

def readFile(path):
    with open(path,'r',errors='ignore') as file: #文档中编码有些问题,所有用errors过滤错误
        content = file.read()
        return content

def saveFile(path,result):
    with open(path,'w',errors='ignore') as file:
        file.write(result)

def segText(inputPath,resultPath):
    fatherLists = os.listdir(inputPath) #主目录
    for eachDir in fatherLists: #遍历主目录中各个文件夹
        eachPath = inputPath + eachDir + "/" #保存主目录中每个文件夹目录,便于遍历二级文件
        each_resultPath = resultPath + eachDir + "/"#分词结果文件存入的目录
        if not os.path.exists(each_resultPath):
            os.makedirs(each_resultPath)
        childLists = os.listdir(eachPath) #获取每个文件夹中的各个文件
        for eachFile in  childLists: #遍历每个文件夹中的子文件
            eachPathFile = eachPath + eachFile #获得每个文件路径
            print(eachFile)
            content = readFile(eachPathFile)#调用上面函数读取内容
            #content = str(content)
            result = (str(content)).replace("\r\n","").strip()#删除多余空行与空格
            #result = content.replace("\r\n","").strip()

            cutResult = jieba.cut(result)#默认方式分词,分词结果用空格隔开
            saveFile(each_resultPath+eachFile," ".join(cutResult))#调用上面函数保存文件
            
def bunchSave(inputFile,outputFile):
    catelist = os.listdir(inputFile)
    bunch = Bunch(target_name=[],label=[],filenames=[],contents=[])
    bunch.target_name.extend(catelist)#将类别保存到Bunch对象中
    for eachDir in catelist:
        eachPath = inputFile + eachDir + "/"
        fileList = os.listdir(eachPath)
        for eachFile in fileList:#二级目录中的每个子文件
            fullName = eachPath + eachFile #二级目录子文件全路径
            bunch.label.append(eachDir)#当前分类标签
            bunch.filenames.append(fullName) #保存当前文件的路径
            bunch.contents.append(readFile(fullName).strip()) #保存文件词向量
    with open(outputFile,'wb') as file_obj: #持久化必须用二进制访问模式打开
        pickle.dump(bunch,file_obj)

def readBunch(path):
    with open(path,'rb') as file:
        bunch = pickle.load(file)
    return bunch

def writeBunch(path,bunchFile):
    with open(path,'wb') as file:
        pickle.dump(bunchFile,file)

def getStopWord(inputFile):
    stopWordList = readFile(inputFile).splitlines()
    return stopWordList

def getTFIDFMat(inputPath,stopWordList,outputPath):#求得TF-IDF向量
    bunch = readBunch(inputPath)
    tfidfspace = Bunch(target_name = bunch.target_name,label=bunch.label,filenames= bunch.filenames,tdm=[],vocabulary={})
    #初始化向量空间
    vectorizer = TfidfVectorizer(stop_words=stopWordList,sublinear_tf=True,max_df=0.5)
    transformer = TfidfTransformer() #该类会统计每个词语的TF-IDF权值
    #文本转化为词频矩阵,单独保存字典文件
    tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
    tfidfspace.vocabulary = vectorizer.vocabulary_
    writeBunch(outputPath,tfidfspace)

def getTestSpace(testSetPath,trainSpacePath,stopWordList,testSpacePath):
    bunch = readBunch(testSetPath)
    #构建测试集TF-IDF向量空间
    testSpace = Bunch(target_name = bunch.target_name,label=bunch.label,filenames=bunch.filenames,tdm=[],vocabulary={})
    #导入训练集的词袋
    trainbunch = readBunch(trainSpacePath)
    #使用TfidfVectorizer初始化向量空间模型  使用训练集词袋向量
    vectorizer = TfidfVectorizer(stop_words=stopWordList,sublinear_tf=True,max_df=0.5,vocabulary=trainbunch.vocabulary)
    transformer = TfidfTransformer()
    testSpace.tdm = vectorizer.fit_transform(bunch.contents)
    testSpace.vocabulary = trainbunch.vocabulary
    #持久化
    writeBunch(testSpacePath,testSpace)

def bayesAlgorithm(trainPath,testPath):
    trainSet = readBunch(trainPath)
    testSet = readBunch(testPath)
    clf = MultinomialNB(alpha=0.001).fit(trainSet.tdm,trainSet.label)
    print(shape(trainSet.tdm))
    print(shape(testSet.tdm))
    predicted = clf.predict(testSet.tdm)
    total = len(predicted)
    rate=0
    for flabel,fileName,expct_cate in zip(testSet.label,testSet.filenames,predicted):
        if flabel != expct_cate:
            rate +=1
            print(fileName,":实际类别:",flabel,"-->预测类别:",expct_cate)
    print("erroe rate:",float(rate)*100/float(total),"%")


#分词,第一个是分词输入,第二个参数是结果保存的路径
segText("E:/Train_Data/文本分类语料库/","E:/Train_Data/segResult/")
bunchSave("E:/Train_Data/segResult/","E:/Train_Data/train_set.dat")#输入分词,输出分词向量
stopWordList = getStopWord("E:/Train_Data/各种停用词表/哈工大停用词表.txt")#获取停用词
getTFIDFMat("E:/Train_Data/train_set.dat",stopWordList,"E:/Train_Data/tfidfspace.dat")#输入词向量,输出特征空间

#训练集
segText("E:/Train_Data/test_data/","E:/Train_Data/test_segResult/")#分词
bunchSave("E:/Train_Data/test_segResult/","E:/Train_Data/test_set.dat")
getTestSpace("E:/Train_Data/test_set.dat","E:/Train_Data/tfidfspace.dat",stopWordList,"E:/Train_Data/testspace.dat")
bayesAlgorithm("E:/Train_Data/tfidfspace.dat","E:/Train_Data/testspace.dat")
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容