暑假摸鱼一时爽
一直摸鱼一直爽
一.我该用什么理由来掩饰自己菜.jpg
前几个月和鲸(一个数据科学平台,原名“科赛网”)联合高校和企业开办了大数据挑战赛(目前此比赛已于6.15结束)。
其中预选赛为文本情感分类模型的建立,本质上属于NLP(自然语言处理)的范畴,需要你首先使用官方提供的训练集进行模型训练,其规定每周更新一次测试集供参赛者进行预测并提交自己的成果。
以上为其官方提供的训练集数据,含有ID序号,评论内容以及标签三个部分组成,简单来说就是一个二分类评论是好评还是差评的预测。由之前的机器学习算法选择路径指引,我理所当然地选择了朴树贝叶斯算法进行一般程序的机器学习过程。
首先我像平常一样参考着一个同样使用朴树贝叶斯算法的代码进行了数据导入与清洗,将lable中的值换为0与1。
之后使用nltk工具库(最为常用的文本信息处理的库)进行分词,特征提取。由于评论的语言多种多样各不相同,我将所有可能支持的语言分类器(停用词处理)用遍历的方式处理了很多次原训练数据(但是有些语言实际上是同源,使用不同语言停用词分类可能将原本单词的情感导向消去,所以这不是一个合适的操作)。之后跟着使用了CountVectorizer方法(一种scikit-learn中提供的文本特征提取的库)在机器学习的过程中让电脑自动进行机器学习训练(矩阵计算)。
运用MultinomialNB与make_pipeline方法(两方法均在scikit-learn中调用),最后使用cross_val_score(交叉验证)方法进行模型准确度预估,最后对官方发布的测试集进行预测。于是就有了第一个成绩——0.7451,但是这个成绩没有通过。说好的随便做做不用调参就能过的呢?
当时正是考试周附近,时间也临近6.15预选赛截止的日期,于是“乱投医之路”就开始了。
首先本着数据量越大效果越好的想法,将测试集并入训练集进行多次训练,结果第二个成绩——0.644 活生生的过拟合例子
之后我将部分权重值进行修改,增加重复训练次数,此方法我试了多次,线上评测分数忽高忽低,由于其比赛为了防止“碰出”凑巧适合于线上评分的模型,设置最多只能进行10次提交。我尝试了多次最终将成绩提升到0.7738,提交之后仍是不通过。后来在讨论区发现,准确率至少要到0.84以上才有可能过…好吧,是真的很严格。
二.探索文本分类的高效处理流程(笔记)
首先什么是自然语言呢?
我们常说的自然语言就是指平常我们写的文字,说出的话语等。基本上我们平时看到的所有文字(包括各种各样的符号)都可以统称为自然语言。由于自然语言在我们的日常生活中起到不可替代的作用,所以自然语言的处理就显得尤为重要。目前自然语言处理在机器翻译,文字转语音,语音语义识别等领域运用十分广泛并且已经深入到了我们的生活之中。
2.1 前期准备
2.1.1 需要运用的python库介绍
谈到NLP,就不得不想到NLP领域最知名的python库——NLTK(Natural Language Toolkit)库,其是一个世界级的自然语言处理库(能处理很多国家的语言),因广泛的适用性以及强大多样的的数据操作能力为人熟知。另外还有专门对中文优化的类似作用的库——Jieba(结巴)。
2.1.2 语料库寻找
通常我们如果要参加线上数据科学分析比赛的话,官方会给你一定数量的数据集。如果是作为公司职员,同组的成员会收集好足够的数据。
但在平常练习时,要如何对练习数据进行寻找呢?
这里推荐几个比较知名的网站,如维基百科(各国语言文字都有)中权威且规范的文本,你可以在其网站寻找到各个时间点下载其完整整合文本。另外对于文本情感分类,IMDB(Internet Movie Database,即互联网电影资料库)也能提供其情感分析语料库进行使用,类似的还有豆瓣电影或书籍之类的语料库也可以进行参考。(当然要获取大量信息需要使用网络爬虫相关操作)
2.1.3 文本分词
由于词是最小的能够独立活动的有意义的语言成分,所以文本分词是NLP项目的第一步,旨在将一个完整的句子或段落分隔开以便于进行语义分析,例如是英文,法文,德文这一类,单词与单词之间是以空格作为自然分界符的,原始文本就已经分词完毕,但是遇到需要分析中文日文这种一整句文本的话,要如何进行分析呢?这时候NLP相关的代码库中都会提供其分词的功能。NLTK中操作是nltk.word_tokenize()
,Jieba中为jieba.cut()
,其库会将一连串的文字进行精准分割(对比存在在字典里的最长串词语)并填充分隔符。例如其代码会将“我来到北京清华大学”分割为“我/ 来到/ 北京/ 清华大学”,这样的话对于其语义分析就变得十分简单了。
其中Jieba对于中文分词有特殊的方法,其支持三种不同方式的分词。
-
精确模式
jieba.cut(xxx, cut_all=True)
:将句子最精确地切开,适合文本分析。 -
全模式
jieba.cut(xxx, cut_all=False)
:把句子中所有的可以组成词语的部分都找出来。 -
搜索引擎模式
jieba.cut_for_search()
:在精确模式的基础上,对长词再次切分,处理为适合用于搜索引擎分词的样子。
另外其还支持繁体文字分词而对于英文分析,NLTK也有其独到的词语处理方法。其支持英文单词的词根抽取以及词性还原。
-
词根抽取
lancaster_stemmer.stem()
及snowball_stemmer.stem()
及porter_stemmer.stem()
可以将代码还原为不同词性。 -
词性还原
wordnet_lemmatizer.lemmatize()
可以将各种形式的单词还原为其词根模式,以便于理解处理。
2.1.4 停用词(stopwords)处理
停用词本质上是指我们平常使用频率非常高但对我们文本分析没有作用的词语,比如英文中的“is,are,give,snack”和中文中的“东西,地图,语言”之类的词语,为了让这些词语不对后续文本分类器模型产生不必要的负面影响,我们可以使用nltk/Jieba进行停用词处理(实际上就是将所有文本扫一遍,发现匹配停用词就去除),中文停用词列表我们可以下载哈工大,百度或者四川大学发布的.txt文件,对于英文我们可以使用NLTK库中自带的stopwords模块(需要使用代理下载)。
另外,对于句子中的特殊的标点符号,我们需要对其谨慎对待,大多数时候我们都会将他们全部舍弃以增加文本的权值,但是“!? :)”这种符号往往比大部分文字表达的态度更加明确,所以在去除停用词时应当适当保留部分符号。
此时,我们对其文本初步处理就已经完成了。
2.1.5 特征提取
在进行分类器模型训练之前,我们需要对文本进行特征提取。常用的提取方法有Bag-of-words(词袋方法),本质是将其全部已经分词的每一个词都当做一个特征,但是数据集即使是分词后去除停用词也仍然有上万单词,所以这种方法效果一般不太理想(我原本使用的就是这种方法)。另外还有一种相对来说更有效的方法——N-Gram,原理是是一种考虑了词汇顺序的模型,其会将每个样本转移成了概率矩阵,可以增加信息的权重。
2.1.6 标注
事实上, 有一些看似分类的问题在实际中却难以归于分类。比如对于下面这一张图
这时,我们不能只将这个图归类为香蕉图片或者是橙子图片。如图所示,其图中明显不只有香蕉与橙子,还有柿子草莓等其他水果。对于这一类图我们真正需要的是无论是输入香蕉还草莓,我们都可以找到同一张图。这时我们就需要给图片打上多个标签对其进行多标签分类。而平时我们见到很多文章中涉及python也同时设计数据分析,这种情况对人工标注有时是很吃力的,这时我们也需要进行机器学习。
2.2 机器学习部分
2.2.1 机器学习算法(分类器方法)
2.2.1.1 朴树贝叶斯(NaYve Bayesian)
朴素贝叶斯方法是基千贝叶斯定理与特征条件独立假设的分类方法,对于给定的训练集合,首先基于特征条件独立(所以叫朴素版的贝叶斯)学习输入、输出的联合概率分布;然后基于此模型,对给定的输入x, 利用贝叶斯定理求出后验概率最大的输出y 。朴素贝叶斯方法简单,学习与预测的效率都很高,是常用的方法。具体数学算法如下
2.2.1.2 逻辑回归(logistic regression)
逻辑回归方法是统计机器学习中的经典方法,虽然简单,但是由于其模型复杂度低,不容易过拟合,计算复杂度小,所以在工业界被大规模应用。逻辑回归有很多优点,比如实现简单、分类时计算量小、速度快、存储资源低等;缺点也是明显的,比如容易过拟合、准确度欠佳等。听说有个NLP领域的大神提出过在NLP项目中使用LR方法效率很差,但是不同算法与不同数据集契合程度也不同。具体数学算法如下
(其中α代表学习速率)
2.2.1.3 支持向量机(SVM)
支持向量机方法的最终目的是在特征空间中寻找到一个尽可能将两个数据集合分开的超级平面( hyper-plane) 。因为我们的数据特征空间很有可能是高维度空间(现实世界的数据可能有上百维度,甚至有上千维度),而且我们希望这个超级平面能够尽可能大地将两类数据分开,如下图所示(此为理想的最终结果)。
SVM 算法优点: 可用于线性/非线性分类,也可以用于回归,低泛化误差,推导过程优美,容易解释,计算复杂度较低。
缺点: 对参数和核函数的选择比较敏感,原始的SVM 只擅长处理二分类问题。
2.2.2 无监督学习的文本聚类(笔记)
无监督学习(Unsupervised Learning) 的目的是能够发现数据本身的规律和模式,与监督学习相比,无监督学习不需要对数据进行提前标记。这样可以节约大量的人力、物力,也可以让数据的获取变得非常容易。某种程度上说,机器学习的终极目标就是无监督学习。类似人刚出生一样,什么都是空白,但是可以通过无监督学习, 慢慢积累出知识和有标的数据。从功能上看,无监督学习可以帮助我们发现数据的"簇"(一个不与其他样本相交的子集),此外,对千特征维度特别高的数据样本,我们同样可以通过无监督学习对数据进行降维,保留数据的主要特征,这样对高维空间的数据也可以进行处理。
聚类试图将数据集中的样本划分为若干个通常是不相交的子集,每个子集称为一个"簇" ( cluster ) 。通过这样的划分,每个簇可能对应于一些潜在的类别。这些概念对聚类算法而言事先是未知的,聚类过程仅能自动形成簇结构,簇所对应的含义需要由使用者来把握和命名。聚类常用于寻找数据内在的分布结构,也可作为分类等其他学习任务的前驱过程。例如,在一些商业应用中需要对用户类型进行判别,但事先没有定义好的“用户类型”,可以先对用户数据进行聚类,根据聚类结果将每个簇定义为一个类,然后基于这些类训练分类模型,用于判别新用户的类型(即为预测导向)。
2.2.3 有监督的文本分类学习
监督学习描述的任务是,当给定输入X, 如何通过在标注了输入和输出的数据上训练模型而预测输出y。
比如垃圾邮件与正常邮件的二分类,就是一个经典的有监督学习的例子。所谓的有监督是指计算机是在你的监督(将邮件进行手动标记)下进行学习的。当新来一份邮件时,我们可以手动将我们不想收到的邮件标记为垃圾邮件,这时计算机会对你标记的垃圾邮件进行分析,试图找出到底是什么内容引导你对其进行垃圾邮件的标记,同时当你没有对邮件进行垃圾邮件标记时对内部试图找出是什么导致你没有对其标记为垃圾邮件。随着标记的数据越来越多,计算机对其垃圾文件的分类会更加人性化,预测更加准确。
推广到一般情况就是你手动对其原数据进行二分类标记,引导计算机进行学习,从而对预测模型进行训练优化以达到提高准确率的目的。
2.2.4 机器学习多选项尝试
由于处理各种不同种类的数据,运用不同的特征提取方法,集合不同的机器学习算法,会有不一样的结果,所以建议在进行机器学习时同时进行三种机器学习与两种特征提取,计算其各个情况的准确率,召回率,精度(准确度与召回率一般成反比,如果不符合那就是出了问题)。最终采用其综合成绩最高的机器学习算法与特征提取方式作为预测模型。
对于更加深层次的NLP方法,我们还可以使用谷歌知名的深度学习框架TensorFlow进行卷积神经网络的方法进行处理。
2.2.5 卷积神经网络的应用
卷积神经网络通常运用于图像处理以及图像识别上,同时它也可以帮助我们进行自然语言处理。如以下图所示。一般首先使用卷积操作处理词向量序列(利用过滤器矩阵),生成多通道特征图,对特征图采用时间维度上的最大池化操作(一般情况下为2*2最大池化)得到与此卷积核对应的整句话的特征(特征提取),最后将所有卷积核得到的特征拼接起来即为文本的定长向量表示。对于文本分类问题,将其连接至Softmax 层即构建出完整的模型。在实际应用中,我们会使用多个卷积核来处理数据,窗口大小相同的卷积核堆叠起来形成一个矩阵,这样可以更高效完成运算。