文本是不定长度的,文本表示成计算的能够运算的数字或向量的方法称为词嵌入(Word Embedding)。词嵌入是将不定长的文本转换成定长的空间中。为了解决将原始文本转成固定长度的特征向量问题,scikit-learn提供了以下方法:

  • 令牌化(tokenizing):对每个可能的词令牌分成字符串并赋予整数形的id,通过空格和标点符号作为令牌分隔符。

  • 统计(counting)每个词令牌在文档中的出现次数。

  • 标准化(normalizing)是减少重要的词令牌的出现次数的权重。

使用传统的机器学习方法进行文本分类,思路有Count Vectors + 分类算法(LR/SVM/XGBoost等等),TF-IDF+分类算法(LR/SVM/XGBoost等等)

1 Count Vectors + 分类算法

1.1 Count Vectors

类countVectorizer在但单类中实现了tokenization(词语切分)和occurence counting(出现频数统计):

函数为:

参数详解:

input:string {‘filename’, ‘file’, ‘content’}, default=’content’

定义输入数据的格式,如果是filename,读取的文件名列表,以获取要分析的原始内容;如果是‘file’,序列项必须有一个' read '方法(类文件的对象),该方法被调用来获取内存中的字节;如果是‘content’,输入应该是字符串或字节类型的序列项。

encoding:string,default='utf-8'

进行分析时,使用该类型进行解码。

lowercase:bool,default=True

在进行tokenizing之前,将字符转成小写

ngram_range:tuple (min_n, max_n), default=(1, 1)

要提取的不同单词n-gram或字符n-gram的n值范围的上下边界。

analyzer:string, {‘word’, ‘char’, ‘char_wb’} or callable, default=’word’

分析是由单词n-gram还是字符n-gram组成,‘char_wb’是一个混合状态。

max_df:float in range [0.0, 1.0] or int, default=1.0

当构建词汇表时,忽略文档频率严格高于给定阈值的术语(特定于语料库的停止词)。如果为float,该参数表示文档的比例,整数绝对计数。如果词汇不是none,则忽略此参数。

min_df:float in range [0.0, 1.0] or int, default=1

构建词汇表时,忽略文档频率严格低于给定阈值的术语。这个值在文献中也被称为截止值。如果为float,该参数表示文档的比例,整数绝对计数。如果词汇不是none,则忽略此参数。

例子:

from sklearn.feature_extraction.text import CountVectorizercorpus = ['This is the first document.','This document is the second document.','And this is the third one.','Is this the first document?']vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())print(X.toarray())vectorizer2 = CountVectorizer(analyzer='word', ngram_range=(2, 2))
X2 = vectorizer2.fit_transform(corpus)
print(vectorizer2.get_feature_names())print(X2.toarray())

1.2 分类算法

这里选用了线性模型里边的岭回归做分类,还可以选用SVM,LR,XGBoost等分类算法模型,后边用网格搜索(GridSearchCV)进行参数遍历的会用到。

综合分析:

import pandas as pd
import xgboost as xgb
import lightgbm as lgb
import catboost as cat
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.svm import  SVC
from sklearn.metrics import f1_score
from sklearn.pipeline import Pipelinetrain_df = pd.read_csv('data/data45216/train_set.csv',sep='\t',nrows=15000)
print(train_df.shape)vectorizer = CountVectorizer(max_features=3000)
train_test = vectorizer.fit_transform(train_df['text'])clf = RidgeClassifier()
clf.fit(train_test[:10000],train_df['label'].values[:10000])
val_pred = clf.predict(train_test[10000:])
print(f1_score(train_df['label'].values[10000:],val_pred,average='macro'))

输出结果为:0.65441877581244

2 TF-IDF+分类算法

2.1 TF-IDF

TF-IDF是词频-逆文档频率,含义是如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为这个词或短语具有很好的类别区分能力,适合用来分类。TF-IDF的假设是,高频率词应该具有高权重,除非它也是高文档频率。逆文档怕频率是使用词条的文档频率来抵消该词的词频对权重的影响,而得到一个较低的权重。

词频(Term Frequency,TF)是指某一个给定的词语在该文件中出现的频率。这个数字是对词数(Term Count)的归一化,以防止它偏向长的文件,对于在某个特定文件中的词语来说,它的重要性可表示为:

其中,分子是该词在文件中的出现次数,而分母是在文件中所有字词出现的次数之和。

逆向文件频率(Inverse Document Frequency,IDF)是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数除以包含该词语之文件的数目,再将得到的商取对数得到:

其中,:语料库中的文件总数;j:包含词语的文件数目,如果该词语不在语料库则导致分母为0,因此,常用作为分母,然后在计算TF和IDF的乘积。

函数为:

参数详解:

input:string {‘filename’, ‘file’, ‘content’}, default=’content’

定义输入数据的格式,如果是filename,读取的文件名列表,以获取要分析的原始内容;如果是‘file’,序列项必须有一个' read '方法(类文件的对象),该方法被调用来获取内存中的字节;如果是‘content’,输入应该是字符串或字节类型的序列项。

encoding:string,default='utf-8'

进行分析时,使用该类型进行解码。

lowercase:bool,default=True

在进行tokenizing之前,将字符转成小写

ngram_range:tuple (min_n, max_n), default=(1, 1)

要提取的不同单词n-gram或字符n-gram的n值范围的上下边界。

analyzer:string, {‘word’, ‘char’, ‘char_wb’} or callable, default=’word’

分析是由单词n-gram还是字符n-gram组成,‘char_wb’是一个混合状态。

max_df:float in range [0.0, 1.0] or int, default=1.0

当构建词汇表时,忽略文档频率严格高于给定阈值的术语(特定于语料库的停止词)。如果为float,该参数表示文档的比例,整数绝对计数。如果词汇不是none,则忽略此参数。

min_df:float in range [0.0, 1.0] or int, default=1

构建词汇表时,忽略文档频率严格低于给定阈值的术语。这个值在文献中也被称为截止值。如果为float,该参数表示文档的比例,整数绝对计数。如果词汇不是none,则忽略此参数。

norm:{‘l1’, ‘l2’}, default=’l2’

正则化,‘l2’是平方值,‘l1’是绝对值

use_idf:bool, default=True

启用反向文档频率重新加权

smooth_idf:bool, default=True

通过在文档频率上增加一个来平滑idf权重,就好像一个额外的文档恰好包含集合中的每个术语一次。防止零除法

sublinear_tf:bool, default=False

应用 sublinear tf scaling, i.e. 取代 tf 在with 1 + log(tf).

例子:

from sklearn.feature_extraction.text import TfidfVectorizercorpus = ['This is the first document.','This document is the second document.','And this is the third one.','Is this the first document?']vectorizer = TfidfVectorizer()
x = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names)

2.2 分类算法

这里选用了线性模型里边的岭回归做分类,还可以选用SVM,LR,XGBoost等分类算法模型,后边用网格搜索(GridSearchCV)进行参数遍历的会用到。

综合分析:

tfidf = TfidfVectorizer(ngram_range=(1,3),max_features=3000)
train_test = tfidf.fit_transform(train_df['text'])clf = RidgeClassifier()
clf.fit(train_test[:10000],train_df['label'].values[:10000])
val_pred = clf.predict(train_test[10000:])
print(f1_score(train_df['label'].values[10000:],val_pred,average='macro'))

输出结果为:0.8719098297954606

本章作业:

调整参数可以考虑用网格搜索进行超参数遍历,分别对文本处理方式和分类算法进行遍历。超参数是不直接在估计器内学习的参数,它们作为估计器类中构造函数的参数进行传递,搜索超参数空间以便能获得最好的“交叉验证”,搜索包括:

  • 估计器(回归器或分类器)
  • 参数空间
  • 搜寻或采样候选的方法
  • 交叉验证方案
  • 计分函数

scikit-learn包中提供了两种采样搜索候选的通用方法,GridSearchCV考虑了所有参数组合,RandomizedSearchCV可以从具有指定分布的参数空间中抽取给定数量的候选,这里选用GridSearchCV举例:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.svm import  SVC
from sklearn.metrics import f1_score
from sklearn.pipeline import Pipeline#遍历TF-IDF的参数
pipeline = Pipeline([('tfidf', TfidfVectorizer()),('clf', SGDClassifier()),
])parameters = {#'tfidf__max_df': (0.5, 0.75, 1.0),'tfidf__max_features': (None, 5000, 10000, 50000),'tfidf__ngram_range': ((1, 1), (1, 2),(1,3)),  # unigrams or bigrams'tfidf__norm': ('l1', 'l2'),'clf__max_iter': (20,),'clf__alpha': (0.00001, 0.000001),'clf__penalty': ('l2', 'elasticnet'),# 'clf__max_iter': (10, 50, 80),
}grid_search = GridSearchCV(pipeline, parameters,  verbose=1)
print("Performing grid search...")
print("pipeline:", [name for name, _ in pipeline.steps])
print("parameters:")
pprint(parameters)
grid_search.fit(train_df['text'].tolist()[:10000],train_df['label'].values[:10000])print("Best score: %0.3f" % grid_search.best_score_)
print("Best parameters set:")
best_parameters = grid_search.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):print("\t%s: %r" % (param_name, best_parameters[param_name]))

遍历分类器:

import pandas as pd
import xgboost as xgb
import lightgbm as lgb
import catboost as cat
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import RidgeClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.svm import  SVC
from sklearn.metrics import f1_score
from sklearn.pipeline import Pipelinetfidf = TfidfVectorizer(ngram_range=(1,3),max_features=3000)
train_test = tfidf.fit_transform(train_df['text'])#定义多个分类函数
classifiers = [('xgb',xgb.XGBClassifier(),{'max_depth': [5, 10, 15, 20, 25],'learning_rate': [0.01, 0.02, 0.05, 0.1, 0.15],'n_estimators': [50, 100, 200, 300, 500],
}),('lgb',lgb.LGBMClassifier(),{'max_depth': [5, 10, 15, 20, 25],'learning_rate': [0.01, 0.02, 0.05, 0.1, 0.15],'n_estimators': [50, 100, 200, 300, 500],
}),('cat',cat.CatBoostClassifier(),{'max_depth': [5, 10, 15, 20, 25],'learning_rate': [0.01, 0.02, 0.05, 0.1, 0.15],'n_estimators': [50, 100, 200, 300, 500],
}),('svc',SVC(),{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4],'C': [1, 10, 100, 1000]})]for name,clf,params in classifiers:grid_search = GridSearchCV(clf,params,n_jobs=1,verbose=1)grid_search.fit(train_test[:10000],train_df['label'].values[:10000])

思考:我用TF-IDF+分类器的验证结果为0.87,提交结果为0.1773,用了Fasttext的验证结果为0.82,提交结果为0.833,产生的原因是什么?

Datawhale-零基础入门NLP-新闻文本分类Task03相关推荐

  1. Task01——零基础入门NLP - 新闻文本分类之赛题理解

    本篇目标 首先本篇文章会对赛题进行介绍以及个人对赛题的理解,带大家接触NLP的预处理.模型构建和模型训练等知识点. 赛题介绍 赛题名称:零基础入门NLP - 新闻文本分类 赛题任务:赛题以自然语言处理 ...

  2. 零基础入门NLP - 新闻文本分类

    本文是对阿里云新人竞赛中的"零基础入门NLP - 新闻文本分类"解体过程进行的记录,目前仅使用了textCNN模型进行预测,后续还会考虑使用LSTM进行对比. 赛题数据 赛题以新闻 ...

  3. 零基础入门NLP - 新闻文本分类,正式赛第一名方案分享

    零基础入门NLP - 新闻文本分类,正式赛第一名方案分享:https://mp.weixin.qq.com/s/7WpZUqdlItBToLYuRLm44g

  4. 【初学者入门】零基础入门NLP - 新闻文本分类

    序言 从今天开始入门学习NLP,虽然有点晚,但是我觉得任何时候都值得开始,尤其是面对你去感兴趣的事情.今天的任务是 [零基础入门NLP - 新闻文本分类],这是天池大赛中的入门级算法比赛,入口链接请自 ...

  5. 天池零基础入门NLP - 新闻文本分类Top1方案的bert4torch复现

    天池有些长期比赛可以练习玩玩(还可以继续提交),于是试了下简单的新闻文本分类任务,Top1的解决方案思路是"预训练+fgm+交叉验证模型融合",代码是基于bert4keras的,本 ...

  6. 【学习笔记】零基础入门NLP - 新闻文本分类实战

    赛题理解   首先要理解赛题的背景及描述--赛题以新闻数据为赛题数据,数据集报名后可见并可下载.赛题数据为新闻文本,并按照字符级别进行匿名处理.整合划分出14个候选分类类别:财经.彩票.房产.股票.家 ...

  7. 阿里云天池 零基础入门NLP - 新闻文本分类 2种做法,F1=0.87

    problem 1.赛题理解 数据集: 在NLP_data_list_0715.csv中,有三个链接. 分别可以下载训练集,测试集A,测试样例. f1_score介绍: F1分数(F1-score)是 ...

  8. 【天池学习赛】零基础入门NLP - 新闻文本分类

    一.赛题描述 赛题数据为新闻文本,并按照字符级别进行匿名处理.整合划分出14个候选分类类别:财经.彩票.房产.股票.家居.教育.科技.社会.时尚.时政.体育.星座.游戏.娱乐的文本数据. 赛题任务:赛 ...

  9. Task02——零基础入门NLP - 新闻文本分类之数据读取与分析

    本期目标 学习使用Pandas读取赛题数据 分析赛题数据的分布规律 数据读取 import pandas as pd train_df=pd.read_csv('./train_set.csv/tra ...

  10. java统计文本中英文单词个数split_零基础入门NLP - 新闻文本分类Task2(天池入门赛)...

    本章主要内容是主要是通过pandas模块来进行数据分析.(注:文章只是对天池入门赛课件的学习) 一.学习目标 1.学习使用pandas读取赛题规律 2.分布赛题数据的分布规律 二.数据读取 使用pan ...

最新文章

  1. asp.net多图片上传案例_会计小明的故事-成本核算案例篇
  2. UVA 12063 Zeros and Ones
  3. Spread for Windows Forms快速入门(1)---开始使用Spread
  4. CentOS6.3中挂载NTFS移动硬盘的经历
  5. 使用kibana可视化报表实时监控你的应用程序
  6. 双向特征融合的数据自适应SAR图像舰船目标检测模型
  7. 有什么手机python编辑器_好用的Python编辑器有哪些?
  8. category和extension的区别
  9. 高性能mysql 第5章 创建高可用的索引
  10. Java垃圾回收jconsole分析
  11. SDN+DPI文献阅读
  12. SQL语句group by 与order by 执行顺序引发的一场“内斗”
  13. 用友U8 ERP系统材料出库单打印格式设置-内容显示设置
  14. 日本公司为东京大学开设区块链课程捐款80万美元
  15. POJ 1201 Intervals(差分约束)
  16. 密度测量:1.密度测量的基础知识
  17. 人脸识别和人脸检测的区别
  18. L0 Norm 、L1 Norm 和 L2 Norm 的简单理解
  19. 空气动力学——第二章 基本原理和基本方程
  20. CSS(b站学习记录)

热门文章

  1. 关于数据库查询优化的思考
  2. dp之二维背包poj1837(天平问题 推荐)
  3. 重载与重写(overload and override)
  4. 数据结构与算法--6.二分查找
  5. Flask 第三方组件之 WTForms
  6. 【排序算法】python 十大经典排序算法(全网最详)
  7. 整理一些完全免费开放的API接口
  8. qt android glsl,基于Qt的OpenGL学习(1)—— Hello Triangle
  9. 如何有效解决C与C++的相互调用问题
  10. html间数据传送,Express框架与html之间如何进行数据传递(示例代码)