美文网首页
机器学习部分

机器学习部分

作者: MatrixFK | 来源:发表于2017-06-14 23:29 被阅读53次

1,工具选择

分词器选择:pyltp

语言技术平台(Language Technology Platform,LTP)是哈工大社会计算与信息检索研究中心历时十年开发的一整套中文语言处理系统。LTP制定了基于XML的语言处理结果表示,并在此基础上提供了一整套自底向上的丰富而且高效的中文语言处理模块(包括词法、句法、语义等6项中文处理核心技术),以及基于动态链接库(Dynamic Link Library, DLL)的应用程序接口、可视化工具,并且能够以网络服务(Web Service)的形式进行使用。

在邮件的数据处理的前期功能中,我们选择的一个工具pyltp作为我们的分词库。这是我们小组成员一致讨论得出的结果,那么为什么要选择它作为我们的垃圾邮件处理的分词器呢,在这里,我们通过列举他的优点来说明我们为什么要选择这一款分词器做作为我们的分词器。

(1)因为它的文档丰富详实,对于一款在github上开源的中文分词器,由于他的文档非常丰富。对于python版本的ltp文档内容非常清楚,每一个接口都有相关的示例方法和调用返回值,这对开发者而言是非常友好的。

(2)分词效率高,同时进行分词和词性标注速度为300KB/s,每秒可处理约15万字。只进行分词速度可达到1.3MB/s。这种速度对于我们小型的电脑处理大量的垃圾邮件的分类是非常有利的。

(3)可以定义训练模型。这对于我们在这里的垃圾邮件分类是非常重要的一个特性,因为实际上作为一款分词软件,它有自己的训练的模式,但是它的样本通常是基于大量的普遍的文章。而我们这里只是这样的大量的普遍的文章的一个子集,为了提高分词的准确率,我们有必要自己建立训练集进行训练。所以这对于我们而言是一个非常重要的特性。

特征属性选择算法选择:

文本分类领域中常用的文本特征属性选择算法有:TF-IDF,信息增益,卡方检验等,而在这一点上,我们选择的是利用卡方检验来计算它的文本特征属性。这里我们通过对比这几种算法来说明我们为什么要选择卡方检验。

  • TF-IDF与特征属性选择
    TF即词频(Term Frequency),表示词条在某个文档d中出现的频率。
    IDF即逆向文件频率(Inverse Document Frequency),如果包含词条t的文档越少,那么IDF值
    越大,则说明词条t具有很好的类别区分能力。
    而TF-IDF 的不足是:

(1)没有考虑特征词在类间的分布
如果一个特征词在各个类之间分布都比较均匀,那么这样的词对分类没有任何贡献;而如果一个特征词集中分布在某个类中,在其它类中都出现但是出现的频率很小很小,那么这个词能很好地代表这个类的特征属性,但是TF-IDF不能很好地区别这两种情况。

(2)没有考虑特征词在类内部文档中的分布
在类内部文档中,如果特征词均匀分布在其中,那么这个特征词能够很好地代表这个类的特征,如果只在几篇文档中出现,那么不能够代表这个类的特征。

  • 信息增益:

在信息增益中,重要的衡量标准就是看这个特征能够为分类系统带来多少信息,带来的信息越多,那么该特征就越重要。通过信息增益选择的特征属性只能考察一个特征对整个系统的贡献,而不能具体到某个类别上,这就使得它只能做全局特征选择,即所有的类使用相同的特征集合

  • 卡方检验

卡方检验是数理统计中一种常用的检验两个变量是否独立的方法。在卡方检验中使用特征与类别间的关联性来进行量化,关联性越强,特征属性得分就越高,该特征越应该被保留。卡方检验最基本的思想是观察实际值和理论值的偏差来确定理论的正确性。通常先假设两个变量确实是独立的,然后观察实际值与理论值的偏差程度,如果偏差足够小,那么就认为这两个变量确实是独立的,否则偏差很大,那么就认为这两个变量是相关的。

所以在这里我们选择卡方检验作为我们的文本特征属性选择算法,后来经过实践证明,卡方检验确实能比其他的几个算法所得到的准确性要高一些。

机器学习开源库选择:

这里我们选择使用了TensorFlow作为我们的机器学习开源库。我们构建了一个模型,TensorFlow帮助我们自动求导,可视化梯度下降的结果。TensorFlow是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点在图中表示数学操作,图中的线则表示在节点间相互联系的多维数据数组,即张量。它灵活的架构让你可以在多种平台上展开计算,例如台式计算机中的一个或多个CPU(或GPU),服务器,移动设备等等。TensorFlow 最初由Google大脑小组的研究员和工程师们开发出来,用于机器学习和深度神经网络方面的研究,但这个系统的通用性使其也可广泛用于其他计算领域。在这里我们使用了TensorFlow正是由于他的这些优秀的特性以及开源的中文文档。这对于我们的开发是十分有帮助的。

2,数据处理部分:

负责数据处理部分的文件主要是

generatelabels.py , wordCHIcounter.py ,wordsbucket.py 这三个文件,其中三个文件独立的并且顺序的实行,并且三个文件的执行顺序有依赖关系。

下面我来介绍一下三个文件分别做的工作,综合起来就是我们在训练模型之前的一步——数据处理的工作了。

generatelabels.py

import pickle
def generate(filename):
    labels={}
    for line in open(filename):
        word=line.split()
        if len(word)!=2:
            raise Exception(line+'spliterr')
        if word[0].lower()=='spam':
            labels[word[1][7:]]=1
        elif word[0].lower()=='ham':
            labels[word[1][7:]]=0
        else:
            raise Exception(line+'labelerr')
    pickle.dump(labels,open('labels','wb'),protocol=2)

def getlabels():
    return pickle.load(open('labels','rb'))
def main():
    filename='./dataset/full/index'
    generate(filename)
    

if __name__ == '__main__':
    main()
    print getlabels()

这个文件主要做的工作是将 /dataset/full/index 这个文本文件转换成可被python识别的二进制文件,输出为文件labels。在这里,index是用于记录dataset/data下的每一个文本到底那一个是垃圾邮件,哪一个是正常邮件的一个索引文件。如果标记为 "spam" ,则说明它为垃圾邮件,如果不是,则它是正常文件。

wordCHIcounter.py:

由于代码长度,我们不在此列出完整代码,只列出关键部分代码,在这个文件中,我们主要利用两个Counter来对词的“表现程度”进行统计和计算:

    # 积极的词汇
    positiveappear=Counter()
    # 消极的词汇
    negetiveappear=Counter()

然后我们对文件进行便利,将每一个文件进行分词,然后统计每一个词的消极积极"表现程度",如果这个文件是垃圾邮件,那么 消极度 + 1 ,如果是正常的文件,那么积极度 + 1,下面是关键的代码:

for line in f:
    if line=="\n":
        contextbeginflag=True
    if contextbeginflag==False:
        continue
    #print(line)
    words = segmentor.segment(line)
    # 分词
    for word in words:
        wordset.add(word)
        totalwordsset.add(word)
for word in wordset:
    if label==1:
        positiveappear[word]+=1        
    else:
        negetiveappear[word]+=1
if label==1:
    positivenum+=1
else:
    negetivenum+=1
pass

最后,我们利用这些值来计算每一个词的卡方检验值,并将他保存成python可以利用的文件格式,关键代码如下:

    for word in totalwordsset:
        N=positivenum+negetivenum
        A=positiveappear[word]/N
        B=negetiveappear[word]/N
        C=(positivenum)/N-A
        D=(negetivenum)/N-B
        smoth=0.00001
        wordCHI[word]=N*((A*D-B*C)**2)/(A+C+smoth)/(A+B+smoth)/(B+D+smoth)/(B+C+smoth)
        pass
    pickle.dump(wordCHI,open('wordCHI','wb'))

wordsbucket.py
我们需要构建模型,然后利用tensor flow帮助我们自动求导,可视化梯度下降的结果,所以在得到了每一个词的卡方检验值之后,我们还需要做的就是利用这些卡方检验值,将每一篇文章向量化。
在这里,我们需要构建一个wordbucketdict函数来筛选,把卡方检验值大于1的那些单词给选出来,输出成为一个数组。
接着,我们对于在文章中构建一个至多10000维的向量,如果一个单词出现在这篇文章中且在刚才我们得到的数组中,那么我们就在向量的维度上给它进行+1操作。这样,就生成了这片文章的向量值,并保存在bucket里面,然后我们将这些变量,按照原来的目录文件进行保存,保存到wordCHIbucket中,等到下一步数据处理的时候,我们就直接读取里面的数据就可以获取到该篇文章的向量值了。

for line in f: 
    if line=="\n":
        contextbeginflag=True
    if contextbeginflag==False:
        continue
    #print(line)
    words = segmentor.segment(line)
    for word in words:
        if word in worddict:
            bucket[worddict[word]]+=1

相关文章

网友评论

      本文标题:机器学习部分

      本文链接:https://www.haomeiwen.com/subject/kcefqxtx.html