目录

文本分类简介

数据集介绍

数据预处理

提取特征

训练分类器

模型评估


  • 文本分类简介

文本分类是指在给定分类体系,根据文本内容自动确定文本类别的过程。最基础的分类是归到两个类别中,称为二分类问题,例如电影评论分类,只需要分为“好评”或“差评”。分到多个类别中的称为多分类问题,例如,把名字分类为法语名字、英语名字、西班牙语名字等。

一般来说文本分类大致分为如下几个步骤:

  1. 定义阶段:定义数据以及分类体系,具体分为哪些类别,需要哪些数据。
  2. 数据预处理:对文档做分词、去停用词等准备工作。
  3. 数据提取特征:对文档矩阵进行降维,提取训练集中最有用的特征。
  4. 模型训练阶段:选择具体的分类模型以及算法,训练出文本分类器。
  5. 评测阶段:在测试集上测试并评价分类器的性能。
  6. 应用阶段:应用性能最高的分类模型对待分类文档进行分类。
  • 数据集介绍

Large Movie Review Dataset数据集(aclimdb)由斯坦福大学人工智能实验室于2011年推出,包含25000条训练数据和25000条测试数据,另外包含约50000条没有标签的辅助数据。训练集和测试集又分别包含12500条正例(正向评价pos)和12500负例(负向评价neg)。

aclimdb的目录结构:

训练集正例的目录:

这个里面包含了12500篇英文评论,打开第一个评论看一下里面的文本内容:

Bromwell High is a cartoon comedy. It ran at the same time as some other programs about school life, such as "Teachers". My 35 years in the teaching profession lead me to believe that Bromwell High's satire is much closer to reality than is "Teachers". The scramble to survive financially, the insightful students who can see right through their pathetic teachers' pomp, the pettiness of the whole situation, all remind me of the schools I knew and their students. When I saw the episode in which a student repeatedly tried to burn down the school, I immediately recalled ......... at .......... High. A classic line: INSPECTOR: I'm here to sack one of your teachers. STUDENT: Welcome to Bromwell High. I expect that many adults of my age think that Bromwell High is far fetched. What a pity that it isn't!

  • 数据预处理

首先载入数据,得到训练集数据、训练集标签、测试集数据、测试集标签,其中训练集标签和测试集标签可由正例或负例数据载入时生成全0或全1数组得到,正例标签为1,负例标签为0.

import glob
import numpy as npdef get_data(path_neg, path_pos):neg_data = []pos_data = []files_neg = glob.glob(path_neg)files_pos = glob.glob(path_pos)for neg in files_neg:with open(neg, 'r', encoding='utf-8') as neg_f:neg_data.append(neg_f.readline())for pos in files_pos:with open(pos, 'r', encoding='utf-8') as pos_f:pos_data.append(pos_f.readline())neg_label = np.zeros(len(neg_data)).tolist()pos_label = np.ones(len(pos_data)).tolist()corpus = neg_data + pos_datalabels = neg_label + pos_labelreturn corpus, labels

然后对数据进行规范化和预处理,包括利用正则表达式去掉特殊字符,利用nltk包的RegexpTokenizer和tokenize分割单词并去掉标点符号,利用nltk包的stopwords去掉停用词,最后得到规范化的语料库。

import re
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwordsdef normalize(corpus):normalized_corpus = []for text in corpus:# 转为小写字母text = text.lower().strip()# 去掉符号text = re.sub(r"<br />", r" ", text)text = re.sub(' +', ' ', text)text = re.sub(r'(\W)(?=\1)', '', text)text = re.sub(r"([.!?])", r" \1", text)text = re.sub(r"[^a-zA-Z.!?]+", r" ", text)# 分词并去掉标点符号tokenizer = RegexpTokenizer(r'\w+')tokens = tokenizer.tokenize(text)# 去掉停用词stopword = stopwords.words('english')filtered_tokens = [token for token in tokens if token not in stopword]# 重新组成字符串filtered_text = ' '.join(filtered_tokens)normalized_corpus.append(filtered_text)return normalized_corpus
  • 提取特征

在使用分类器之前,需要对文本提取特征,包括以下几种经典方法:

(1)BOW:最原始的特征集,一个单词就是一个特征,往往一个数据集就会有上万个特征,去停用词可以帮助筛选掉一些对分类没帮助的词。

(2)统计特征:包括TF,IDF,以及合并起来的TF-IDF。

(3)N-Gram:考虑词汇顺序,即N阶马尔可夫链。

本文使用两种方式提取特征,一种是词袋模型,另一种是TF-IDF特征。

使用sklearn包的CountVectorizer和TfidfVectorizer可以分别提取出词袋模型和TF-IDF的特征。

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizerdef bow_extractor(corpus, ngram_range=(1, 1)):vectorizer = CountVectorizer(min_df=1, ngram_range=ngram_range)features = vectorizer.fit_transform(corpus)return vectorizer, featuresdef tfidf_extractor(corpus, ngram_range=(1, 1)):vectorizer = TfidfVectorizer(min_df=1, norm='l2', smooth_idf=True, use_idf=True, ngram_range=ngram_range)features = vectorizer.fit_transform(corpus)return vectorizer, features
  • 训练分类器

常见的分类器有逻辑斯蒂回归(LR),支持向量机(SVM),K近邻(KNN),决策树(DT),神经网络(NN)等,可以根据场景选择合适的文本分类器。上述大型电影评论数据集的特征数量很多,可以选择LR或线性SVM。

导入sklearn包的SGDClassifier并指定参数loss='hinge'使用软边际的线性SVM分类器,导入LogisticRegression使用逻辑斯蒂回归分类器。

# 导入分类器
svm = SGDClassifier(loss='hinge', max_iter=100)
lr = LogisticRegression(solver='liblinear')

使用训练集特征和训练集标签训练分类器,并在测试集上预测结果。

def train_predict_evaluate_model(classifier,train_features, train_labels,test_features, test_labels):# 训练模型classifier.fit(train_features, train_labels)# 在测试集上预测结果predictions = classifier.predict(test_features)return predictions
  • 模型评估

导入sklearn包中的metrics模块并利用测试集的真实标签和预测标签来评估模型的性能,评价指标包括分类的准确率、精度、召回率和F1值。

设TP为真正例,FP为假正例,FN为假反例,TN为真反例:

精度(Accuracy)=(TP+TN)/(TP+FP+FN+TN)

准确率(P,Precision)=TP/(TP+FP),在所有被判断为正确的文档中,有多大比例是正确的。

召回率(R,Recall)=TP/(TP+TN),在所有正确的文档中,有多大比例被我们判为正确。

F1值(F-measure)=2PR/(P+R),既考虑准确率,又考虑召回率。

准确率和召回率是互相影响的,理想情况下是两者都高,即F1值高。

from sklearn import metrics
import numpy as npdef get_metrics(true_labels, predicted_labels):print('精度:', np.round(metrics.accuracy_score(true_labels,predicted_labels),2))print('准确率:', np.round(metrics.precision_score(true_labels,predicted_labels,average='weighted'),2))print('召回率:', np.round(metrics.recall_score(true_labels,predicted_labels,average='weighted'),2))print('F1值:', np.round(metrics.f1_score(true_labels,predicted_labels,average='weighted'),2))

主函数如下:

from data_normalize import get_data, normalize
from feature_extractor import bow_extractor, tfidf_extractor
from train_predict_evaluate import train_predict_evaluate_model
from sklearn.linear_model import SGDClassifier
from sklearn.linear_model import LogisticRegressionif __name__ == "__main__":train_corpus, train_labels = get_data('./train/neg/*.txt', './train/pos/*.txt')test_corpus, test_labels = get_data('./test/neg/*.txt', './test/pos/*.txt')norm_train_corpus = normalize(train_corpus)norm_test_corpus = normalize(test_corpus)# 词袋模型特征bow_vectorizer, bow_train_features = bow_extractor(norm_train_corpus)bow_test_features = bow_vectorizer.transform(norm_test_corpus)# tfidf 特征tfidf_vectorizer, tfidf_train_features = tfidf_extractor(norm_train_corpus)tfidf_test_features = tfidf_vectorizer.transform(norm_test_corpus)# 导入分类器svm = SGDClassifier(loss='hinge', max_iter=100)lr = LogisticRegression(solver='liblinear')# 基于词袋模型特征的逻辑斯蒂回归模型print("基于词袋模型特征的逻辑斯蒂回归模型")lr_bow_predictions = train_predict_evaluate_model(classifier=lr,train_features=bow_train_features,train_labels=train_labels,test_features=bow_test_features,test_labels=test_labels)# 基于词袋模型的支持向量机模型print("基于词袋模型的支持向量机模型")svm_bow_predictions = train_predict_evaluate_model(classifier=svm,train_features=bow_train_features,train_labels=train_labels,test_features=bow_test_features,test_labels=test_labels)# 基于tfidf的逻辑斯蒂回归模型print("基于tfidf的逻辑斯蒂回归模型")lr_tfidf_predictions = train_predict_evaluate_model(classifier=lr,train_features=tfidf_train_features,train_labels=train_labels,test_features=tfidf_test_features,test_labels=test_labels)# 基于tfidf的支持向量机模型print("基于tfidf的支持向量机模型")svm_tfidf_predictions = train_predict_evaluate_model(classifier=svm,train_features=tfidf_train_features,train_labels=train_labels,test_features=tfidf_test_features,test_labels=test_labels)

训练结果如下:

基于词袋模型特征的逻辑斯蒂回归模型
精度: 0.86
准确率: 0.86
召回率: 0.86
F1值: 0.86
基于词袋模型的支持向量机模型
精度: 0.85
准确率: 0.85
召回率: 0.85
F1值: 0.85
基于tfidf的逻辑斯蒂回归模型
精度: 0.88
准确率: 0.88
召回率: 0.88
F1值: 0.88
基于tfidf的支持向量机模型
精度: 0.88
准确率: 0.88
召回率: 0.88
F1值: 0.88

从训练结果中可以看出,TF-IDF稍微好于词袋模型,而使用逻辑斯蒂回归或支持向量机分类器的效果差别不大。

利用词袋模型和TF-IDF实现Large Movie Review Dataset文本分类相关推荐

  1. 情感分析的描述、基于词袋模型和word2vec模型的情感分析实现

    情感分析的描述.基于词袋模型和word2vec模型的情感分析实现 以购物评论为例: # 读入原始数据集 import pandas as pddfpos = pd.read_excel('../dat ...

  2. 词袋模型和TF-IDF

    作者|PURVA HUILGOL 编译|VK 来源|Analytics Vidhya 机器理解文本的挑战 "语言是一种极好的交流媒介" 你和我很快就会明白那句话.但机器根本无法处理 ...

  3. tf-idf词向量和bow_使用词袋Bow和TF IDF进行多标签分类

    tf-idf词向量和bow 1.加载数据 (1. Load the data) For this study, we are using Kaggle data for Toxic Comment C ...

  4. PPNet模型和tf.stop_gradient的用法

    参考链接: 1. 快手参数个性化 CTR 模型 - PPNet 2. 快手精排模型实践 3. LHUC算法论文 如上图所示,PPNet 的左侧是目前常见的 DNN 网络结构,由稀疏特征(sparse ...

  5. 用词袋(bag of word)实现场景识别

    前段时间在standford university的计算机视觉:算法与应用这门课上做了一个小作业--利用词袋实现场景识别(Scene recognition with bag of words),下面 ...

  6. 基于Kaggle数据的词袋模型文本分类教程

     基于Kaggle数据的词袋模型文本分类教程 发表于23小时前| 454次阅读| 来源FastML| 0 条评论| 作者Zygmunt Z 词袋模型文本分类word2vecn-gram机器学习 w ...

  7. python根据词向量计算相似度_如何使用gensim的word2vec模型和python计算句子相似度...

    如何使用gensim的word2vec模型和python计算句子相似度 根据Gensim Word2Vec,我可以使用gensim包中的word2vec模型来计算2个单词之间的相似度. 例如 trai ...

  8. sklearn TfidfVectorizer、CountVectorizer词袋、 TfidfTransformer词频模型区别及词表、idf获取、cosine计算、bm25相关性

    #搜索query与docs,词表.idf获取.cosine计算 import pandas as pd import numpy as np from sklearn.feature_extracti ...

  9. lr模型和dnn模型_建立ML或DNN模型的技巧

    lr模型和dnn模型 机器学习 (Machine Learning) Everyone can fit data into any model machine learning or deep lea ...

  10. 自然语言处理之中文文本分析(jieba分词、词袋doc2bow、TFIDF文本挖掘)

    中文分词常用的分词工具有jieba等,本文以jieba分词为例,讲解中文文本分析. 一.jieba分词 来源github:https://github.com/fxsjy/jieba 1.主要模式 支 ...

最新文章

  1. 【CVPR2020】目标检测方向论文更新
  2. GCC中的分支预测(likely和unlikey)
  3. TF之DNN:对DNN神经网络进行Tensorboard可视化(得到events.out.tfevents本地服务器输出到网页可视化)
  4. 首尾非零正则_常用的17种正则表达式
  5. 2.3.6 操作系统之进程同步与互斥经典问题(生产者-消费者问题、多生产者-多消费者问题、吸烟者问题、读者-写者问题、哲学家进餐问题)
  6. (*长期更新)软考网络工程师学习笔记——Section 6 网络层上篇
  7. python同步两张数据表_Python 如何实现数据库表结构同步
  8. 两列布局、三列适应布局、两列等高适应布局。
  9. animation 先执行一次 在持续执行_这一次,彻底弄懂 JavaScript 执行机制
  10. 企业级应用与互联网应用的区别?
  11. 6迁移-企业级 Hyper-v 群集部署实验方案
  12. python计算峰度和偏度、相关系数
  13. KeyError: 'labels [189] not contained in axis' Python DataFrame 合并后使用loc进行索引的时候出错问题分析以及解决方案
  14. Android 微信分享不显示分享出去的图标问题
  15. ios 高德获取定位_更新日志-iOS 定位SDK | 高德地图API
  16. docker创建mysql容器
  17. 【机器学习的高等数学基础】导数的几何意义和物理意义、函数的可导性与连续性之间的关系、平面曲线的切线和法线、基本导数与微分表、微分中值定理,泰勒公式、弧微分、曲率、曲率半径、洛必达法则、渐近线的求法等
  18. 概念模型、逻辑模型和物理模型的区别
  19. c语言-是不是太胖了
  20. 卸载 MySql (基于Centos 7)

热门文章

  1. Objective--C Practice and source code
  2. mariadb配置允许远程访问方式
  3. 一个用户在同一时间只能登录一次
  4. 第二章 马尔科夫决策过程和贝尔曼等式-强化学习理论学习与代码实现(强化学习导论第二版)
  5. 《机器学习Python实践》第4章——Python和SciPy速成
  6. ArcMAP 设置图层透明度
  7. 地图相关知识和地图打印色彩差异解决办法
  8. windows下PHP拓展包的选择
  9. java中web错误返回码,Java-Web3j Transfer.sendFunds()返回错误“天然气...
  10. 实习成长之路:DelayQueue多线程下的延迟队列的使用