多层感知机概述

人的大脑是由无数的神经元组成的复杂网络。神经元是具有长突起的细胞,它由细胞体和轴突、树突组成。

每个神经元可以有一或多个树突,可以接受刺激并将兴奋传入细胞体。每个神经元只有一个轴突,可以把兴奋从胞体传送到另一个神经元或其他组织,如肌肉或腺体。

使用多层感知机进行文档分类-图3

神经网络算法就是模拟了人体神经元的工作原理,多个输入参数,分别具有各自的权重,经过激励函数的处理后,得到输出。输出可以再对接下一级的神经网络的输入,从而组成更加复杂的神经网络。

如果对预测错误的神经元施加惩罚,从输出层开始层层向上查找预测错误的神经元,微调这些神经元对应的权重,达到修复错误的目的,这样的算法就叫做反向传播算法。Scikit-learn中的神经网络实现都是使用反向传播算法。本文重点介绍算法在安全领域的应用,神经网络的公式推导请参考其他机器学习专业书籍。本书介绍的是神经网络中最简单的一种形式,即多层感知机。

数据集

数据集依然使用搜狗实验室提供的”搜狐新闻数据”,该数据来自搜狐新闻2012年6月—7月期间国内,国际,体育,社会,娱乐等18个频道的新闻数据,提供URL和正文信息。 对应的网址为:

我们选择其中数量最大的三个频道的数据进行分析,数据清洗过程请参考我之前的文章《使用fasttext进行文档分类》

特征提取

特征提取的方式采用词袋结合TFIDF的方式。

  1. vectorizer = CountVectorizer()
  2. transformer = TfidfTransformer()
  3. x = transformer.fit_transform(vectorizer.fit_transform(x))
  1. #切割词袋
  2. vectorizer = CountVectorizer(ngram_range=(2,2))
  3. # 该类会统计每个词语的tf-idf权值
  4. x = transformer.fit_transform(vectorizer.fit_transform(x))

由于这次需要区分的标签一共有三种,不能直接使用过去二分类问题的方式进行处理了。针对多分类问题,需要使用one-hot编码处理标签。所谓的one-hot编码,又称为一位有效编码,主要是采用位状态寄存器来对个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。比如我们有三类标签,就可以编码为:

在keras中可以非常方便的进行转换。

  1. #转换成one hot编码
  2. y=to_categorical(t, num_classes=3)

训练与效果验证

在scikit-learn中构造多层感知机的分类器非常方便,通常只需要设计神经网络的结构即可。本例中设计的隐藏层有两层,结点数分为为5和3,通常最后一层的结点数与标签类型数相同。

  1. #mlp
  2. alpha=1e-5,
  3. hidden_layer_sizes=(5, 3),

其中比较重要的几个参数的含义为:

效果验证使用5折交叉验证,考核的指标是f1和accuracy。使用cross_val_score函数可以非常方便的实现交叉验证的功能,其中cv参数指定交叉验证的方式,比如5代表5折交叉验证。

  1. scores = cross_val_score(clf, x, y, cv = 5,scoring='f1_micro')
  2. print("f1: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
  3. scores = cross_val_score(clf, x, y, cv = 5,scoring='accuracy')
  4. print("accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
  1. f1: 0.98 (+/- 0.04)
  2. accuracy: 0.97 (+/- 0.05)

当使用n-gram&TFIDF模型的效果,有兴趣的读者可以自行验证。