任何分类问题都需要从数据中挖掘有用的特征,文本分类也不例外。下面介绍几种从文本中提取特征的方法。也是处理文本的一种最基本的方法。在机器学习算法的训练过程中,文本表示法假设给定$N$个样本,每个样本有$M$个特征,从而形成$N×M$个样本矩阵,进而完成算法训练和预测。同样,在计算机视觉中,一张图片的像素点可以看成是特征,每张图片可以看成是一张高×宽×3的特征图,可以将一个三维矩阵输入计算机进行计算。但在自然语言领域,上述方法并不可行:文本是可变长度的。将文本表示为计算机可以运算的数字或向量的方法,一般称为词嵌入(WordEmbedding)方法。词嵌入将可变长度的文本转换为固定长度的空间,这是文本分类的第一步。one-hot标签one-hot通常用于编码不同的类别。一个编码的每一位对应一个类别,其中只有一个为1,其余为0。按照同样的思路,我们也可以使用one-hot编码来表示每个词。比如下面两句话句子1:我爱北京天安门句子2:我喜欢上海首先,统计两个句子中所有单词的类别,并对每个类别进行编号{'I':1,'Love':2,'北':3,'净':4,'天':5,'安':6,'门':7,'喜':8,'欢':9,'上':10,'sea':11}一共有11个词,所以每个词可以转化为11维的稀疏向量:I:[1,0,0,0,0,0,0,0,0,0,0]爱:[0,1,0,0,0,0,0,0,0,0,0]...海:[0,0,0,0,0,0,0,0,0,0,1]这个想法看似合理,但是有两个明显的问题。对于一个稍微复杂的语料数据,它已经包含了海量的词,而一个词会有多种形式,如果每个词都用一个one-hotencodingvector表示,会造成维度爆炸。one-hotvectors不能对词之间的关系建模(one-hotvectors是相互正交的),但是这个信息是文本中的重要特征。BagofWordsbagofwords(BoW)也称为词袋模型,是一种从文本中提取特征进行建模的方法。bagofwords模型是描述文档中单词出现的文本表示,主要包括已有单词的字典。现有单词表示的度量。之所以称为词袋,是因为BoW只关心已知词是否出现在文档中,而不关心它在文档中出现的顺序和结构信息。它使用文档中每个单词的计数作为特征。构建BoW模型包括以下步骤来收集数据,例如这是最好的时代,这是最坏的时代,这是智慧的时代,这是愚蠢的时代。设计字典可以将文档库(收集的数据)中你认为重要的词添加到字典中。字典的形式如下:“it”“was”“the”“best”“of”“times”“worst”“age”“wisdom”“foolishness”构建文档向量的目的是将每个文档(可以理解为包含可变长度单词的句子)转换为长度为字典中单词数的固定长度向量。那么如何将文档转化为单个向量呢,最简单的方法就是用一个布尔值来表示字典中的每个词是否出现在文档中,出现则为1,否则为0。例如,上面文档得到的向量是"it"=1"was"=1"the"=1"best"=1"of"=1"times"=1"worst"=0"age"=0"wisdom"=0"foolishness"=0对应的vector为:[1,1,1,1,1,1,0,0,0,0]在sklearn中,我们可以利用自带的工具快速实现BoWfunctionfromsklearn.feature_extraction.textimportCountVectorizercorpus=['这是第一个文档。','这个文档是第二个文档。','这是第三个。','这是第一个文档吗?',]#以每个词在词典中出现的次数作为特征-1个现有单词,但N=2(N-1=1),也就是说,一个词出现的概率只由它的前一个词决定。那么如何根据出现过的N-1个词来预测一个词的出现呢?首先,我们需要一个语料库(corpus),其中包含大量的Sentences。假设语料库现在包含以下句子:1.Hesaidthankyou.2.Hesaidbyeashewalkedthroughthedoor.3.HewenttoSanDiego.4.SanDiegohadniceweather.5.Itisrainingin旧金山.假设我们将N设为2,即只根据其前一个词来预测该词出现的概率。一般来说,概率的计算方法如下$\frac{count(wpwn)}{count(wp)}$,wp代表前一个词,wn代表当前词,count是一个计数函数。比如我们想得到你在thank之后出现的概率P(you|thank),相当于“thankyou”出现的次数/“thank”出现的次数=1/1=1我们可以说,每当有一句谢谢,你会出现在它的后面。TF-IDFTF-IDF(termfrequency-inversedocumentfrequency),它是一种统计测量方法,用于评估一个词与文档库中文档的相关性。它常用于信息检索和文本挖掘。对于文档中的一个单词,其TF-IDF可以乘以两个不同的指标得到term-frequency(TF):$TF(t)=\frac{count(t)}{total\quadterms}=\frac{单词t在当前文档中出现的次数}{当前文档中的单词总数}$逆向文档频率(IDF):$IDF(t)=In(\frac{count(document)}{count(document\quadwhich\quadcontain\quadterm\quadt)})=In(\frac{totaldocumentNumber}{Numberofdocumentscontainingtheword})$例如,一个文档包含100个词,并且cat这个词出现了3次,那么TF(cat)=3/100=0.03,假设我们有1e7篇文档,其中cat出现在1e3次,那么IDF(cat)=log(1e7/1e3)=4,所以TF_IDF权重是:0.03*4=0.12。现在回到比赛数据,尝试使用TF-IDF构建特征Forclassificationimportpandasasppdffromsklearn.feature_extraction.textimportCountVectorizer,TfidfVectorizerfromsklearn.metricsimportf1_scorefromsklearn.model_selectionimporttrain_test_splitfromsklearn.linear_modelimportRidgeClassifierroot_dir='/content/drive/MyDrive/competitions/NLPNews'#内存有限,这里只读取10000行train_df=pd.read_csv(root_dir+'/train.csv',sep='\t',nrows=10000)#max_features表示字典的大小,包括max_features个词频最高的词tfidf=TfidfVectorizer(ngram_range=(1,3),max_features=3000)train_test=tfidf.fit_transform(train_df['text'])#构建分类器clf=RidgeClassifier()#拆分数据集x_train,x_test,y_train,y_test=train_test_split(train_test,train_df['label'],test_size=0.1,random_state=0)#训练模型clf.fit(x_train,y_train)#执行预测y_pred=clf.predict(x_test)#输出宏观平均f1-scoreprint(f1_score(y_test,y_pred,average='macro'))0.8802400152512864总结通过这次学习,文本的表示方法和一个对tex的特征构造的基本理解t数据集。参考[1]Datawhale零基础入门NLP竞赛-Task3基于机器学习的文本分类)[2]浅谈词袋模型[3]N-gram简介:WhatAreTheyandWhyDo我们需要他们吗?[4]tf-idf是什么意思?
