山大创新实训 2[知识问答]对问题利用向量空间模型和朴素贝叶斯进行文本分类

预处理

问题分类没有现成的数据集,团队成员集体构造可能出现的问题并进行人工标注类别

在这里插入图片描述
train_corpus保存了训练集语料库,其下每一个文档都代表了一个问题分类,问题分类里txt文件保存数据集。
例如:作者的作品 问题数据集
在这里插入图片描述

中文分词

 for mydir in catelist:
        '''
       
        '''
        class_path = corpus_path + mydir + "/"  # 拼出分类子目录的路径如:train_corpus/xx/
        seg_dir = seg_path + mydir + "/"  # 拼出分词后存贮的对应目录路径如:train_corpus_seg/xx/

        if not os.path.exists(seg_dir):  # 是否存在分词目录,如果没有则创建该目录
            os.makedirs(seg_dir)

        file_list = os.listdir(class_path)  # 获取未分词语料库中某一类别中的所有文本

        for file_path in file_list:  # 遍历类别目录下的所有文件
            fullname = class_path + file_path  # 拼出文件名全路径如:train_corpus/xx/xx.txt
            content = readfile(fullname)  # 读取文件内容
            '''此时,content里面存贮的是原文本的所有字符,例如多余的空格、空行、回车等等,
            接下来,需要把这些无关痛痒的字符统统去掉,变成只有标点符号做间隔的紧凑的文本内容
            '''
            content = content.replace('\r\n'.encode('utf-8'), ''.encode('utf-8')).strip()  # 删除换行
            content = content.replace(' '.encode('utf-8'), ''.encode('utf-8')).strip()  # 删除空行、多余的空格
            content_seg = jieba.cut(content)  # 为文件内容分词
            savefile(seg_dir + file_path, ' '.join(content_seg).encode('utf-8'))  # 将处理后的文件保存到分词后语料目录

将文本文件转为Bunch类形
我们在Bunch对象里面创建了有4个成员:
target_name:是一个list,存放的是整个数据集的类别集合。
label:是一个list,存放的是所有文本的标签。
filenames:是一个list,存放的是所有文本文件的名字。
contents:是一个list,分词后文本文件(一个文本文件只有一行)

 catelist = os.listdir(seg_path)  # 获取seg_path下的所有子目录,也就是分类信息
    # 创建一个Bunch实例
    bunch = Bunch(target_name=[], label=[], filenames=[], contents=[])
    bunch.target_name.extend(catelist)
    '''
    extend(addlist)是python list中的函数,意思是用新的list(addlist)去扩充
    原来的list
    '''
    # 获取每个目录下所有的文件
    for mydir in catelist:
        class_path = seg_path + mydir + "/"  # 拼出分类子目录的路径
        file_list = os.listdir(class_path)  # 获取class_path下的所有文件
        for file_path in file_list:  # 遍历类别目录下文件
            fullname = class_path + file_path  # 拼出文件名全路径
            bunch.label.append(mydir)
            bunch.filenames.append(fullname)
            bunch.contents.append(readfile(fullname))  # 读取文件内容
            '''append(element)是python list中的函数,意思是向原来的list中添加element,注意与extend()函数的区别'''
    # 将bunch存储到wordbag_path路径中
    with open(wordbag_path, "wb") as file_obj:
        pickle.dump(bunch, file_obj)
    print("构建文本对象结束!!!")

向量空间模型

把所有词统一到同一个词向量空间中

希望得到两个东西:

1.词典(单词和单词对应的序号)
2.权重矩阵tdm,其中,权重矩阵是一个二维矩阵,tdm[i][j]表示,第j个词(即词典中的序号)在第i个类别中的IF-IDF值(下文有讲解)。
tdm的每一列都是一个单词在各个类别中的全职。每一列当作词向量。

TF-IDF

将训练集所有文本文件(词向量)统一到同一个TF-IDF词向量空间中。这个词向量空间最终存放在train_word_bag/tfdifspace.dat中

stpwrdlst = readfile(stopword_path).splitlines()
    bunch = readbunchobj(bunch_path)
    tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[],
                       vocabulary={})

 
    if train_tfidf_path is not None:
        trainbunch = readbunchobj(train_tfidf_path)
        tfidfspace.vocabulary = trainbunch.vocabulary
        vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5,
                                     vocabulary=trainbunch.vocabulary)
        tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)

    else:
        vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5)
        tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
        tfidfspace.vocabulary = vectorizer.vocabulary_

    writebunchobj(space_path, tfidfspace)
    print("if-idf词向量空间实例创建成功!!!")

朴素贝叶斯进行文本分类

设计分类器,用训练集训练,用测试集测试。

# 导入训练集
trainpath = "train_word_bag/tfdifspace.dat"
train_set = readbunchobj(trainpath)

# 导入测试集
testpath = "test_word_bag/testspace.dat"
test_set = readbunchobj(testpath)

# 训练分类器:输入词袋向量和分类标签,alpha:0.001 alpha越小,迭代次数越多,精度越高
clf = MultinomialNB(alpha=0.001).fit(train_set.tdm, train_set.label)

# 预测分类结果
predicted = clf.predict(test_set.tdm)

for flabel, file_name, expct_cate in zip(test_set.label, test_set.filenames, predicted):
    if flabel != expct_cate:
        print(file_name, ": 实际类别:", flabel, " -->预测类别:", expct_cate)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值