【Python与机器学习】:利用Keras进行多类分类

摘要:
您需要将类别变量(分类函数)的输出标签转换为数字变量。1) (输出层采用sigmoid函数)或(-1,1)(输出层使用tanh函数)。也就是说,onehotencoding方法用于将输出标签的向量转换为相应标签所在列中的1。1注意,此处不应将标签直接转换为数字变量。

多类分类问题本质上可以分解为多个二分类问题,而解决二分类问题的方法有很多。这里我们利用Keras机器学习框架中的ANN(artificial neural network)来解决多分类问题。这里我们采用的例子是著名的UCI Machine Learning Repository中的鸢尾花数据集(iris flower dataset)。

1. 编码输出便签
多类分类问题与二类分类问题类似,需要将类别变量(categorical function)的输出标签转化为数值变量。这个问题在二分类的时候直接转换为(0,1)(输出层采用sigmoid函数)或(-1,1)(输出层采用tanh函数)。类似的,在多分类问题中我们将转化为虚拟变量(dummy variable):即用one hot encoding方法将输出标签的向量(vector)转化为只在出现对应标签的那一列为1,其余为0的布尔矩阵。以我们所用的鸢尾花数据为例:

sample,    label
1,        Iris-setosa
2,        Iris-versicolor
3,        Iris-virginica

用one hot encoding转化后如下:

sample, Iris-setosa, Iris-versicolor, Iris-virginica
1,        1,            0,                0
2,        0,            1,                0
3,        0,            0,                1

注意这里不要将label直接转化成数值变量,如1,2,3,这样的话与其说是预测问题更像是回归预测的问题,后者的难度比前者大。(当类别比较多的时候输出值的跨度就会比较大,此时输出层的激活函数就只能用linear)

这一步转化工作我们可以利用keras中的np_utils.to_categorical函数来进行。

2. 构建神经网络模型
Keras是基于Theano或Tensorflow底层开发的简单模块化的神经网络框架,因此用Keras搭建网络结构会比Tensorflow更加简单。这里我们将使用Keras提供的KerasClassifier类,这个类可以在scikit-learn包中作为Estimator使用,故利用这个类我们就可以方便的调用sklearn包中的一些函数进行数据预处理和结果评估(此为sklearn包中模型(model)的基本类型)。
对于网络结构,我们采用3层全向连接的,输入层有4个节点,隐含层有10个节点,输出层有3个节点的网络。其中,隐含层的激活函数为relu(rectifier),输出层的激活函数为softmax。损失函数则相应的选择categorical_crossentropy(此函数来着theano或tensorflow,具体可以参见这里)(二分类的话一般选择activation=‘sigmoid’, loss=‘binary_crossentropy’)。
PS:对于多类分类网络结构而言,增加中间隐含层能够提升训练精度,但是所需的计算时间和空间会增大,因此需要测试选择一个合适的数目,这里我们设为10;此外,每一层的舍弃率(dropout)也需要相应调整(太高容易欠拟合,太低容易过拟合),这里我们设为0.2。

3. 评估模型
这里我们利用评估机器学习模型的经典方法: k折交叉检验(k-fold cross validation)。这里我们采用10折(k=10)。

4. 代码实现

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils
from sklearn.model_selection import train_test_split, KFold, cross_val_score
from sklearn.preprocessing import LabelEncoder

# load dataset
dataframe = pd.read_csv("iris.csv", header=None)
dataset = dataframe.values
X = dataset[:, 0:4].astype(float)
Y = dataset[:, 4]

# encode class values as integers
encoder = LabelEncoder()
encoded_Y = encoder.fit_transform(Y)
# convert integers to dummy variables (one hot encoding)
dummy_y = np_utils.to_categorical(encoded_Y)

# define model structure
def baseline_model():
    model = Sequential()
    model.add(Dense(output_dim=10, input_dim=4, activation='relu'))
    model.add(Dropout(0.2))
    model.add(Dense(output_dim=3, input_dim=10, activation='softmax'))
    # Compile model
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model
estimator = KerasClassifier(build_fn=baseline_model, nb_epoch=40, batch_size=256)
# splitting data into training set and test set. If random_state is set to an integer, the split datasets are fixed.
X_train, X_test, Y_train, Y_test = train_test_split(X, dummy_y, test_size=0.3, random_state=0)
estimator.fit(X_train, Y_train)

# make predictions
pred = estimator.predict(X_test)

# inverse numeric variables to initial categorical labels
init_lables = encoder.inverse_transform(pred)

# k-fold cross-validate
seed = 42
np.random.seed(seed)
kfold = KFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(estimator, X, dummy_y, cv=kfold)

5. 参考

  1. http://machinelearningmastery.com/multi-class-classification-tutorial-keras-deep-learning-library/
  2. http://datascience.stackexchange.com/questions/10048/what-is-the-best-keras-model-for-multi-label-classification
  3. http://stackoverflow.com/questions/28064634/random-state-pseudo-random-numberin-scikit-learn
  4. http://scikit-learn.org/stable/modules/classes.html

免责声明:文章转载自《【Python与机器学习】:利用Keras进行多类分类》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用ADB无线连接Android真机进行调试Parquet与ORC:高性能列式存储格式(收藏)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Segmentation fault (core dumped) 错误的一种解决场景

错误类型 Segmentation fault (core dumped) 产生原因 Segmentation fault 段错误。 Core Dump 核心转储(是操作系统在进程收到某些信号而终止运行时,将此时进程地址空间的内容以及有关进程状态的其他信息写出的一个磁盘文件。这种信息往往用于调试),其实“吐核”这个词形容的很恰当,就是核心内存吐出来。 出...

开发时javascript 文件调试 chrome 浏览器本地缓存处理

chrome 浏览器 javascript 文件缓存处理 调试一体项目时,js文件需要经常刷新,通过强制刷新全页面重新加载是非常恶心的,我们测试填写的很多数据都需要重新填一遍,当然我们可以写个函数快速填充数据,但是还是不够通用。 尽管我们在新的标签页面请求js,发现js文件已经刷新了。但是当前页面使用的js还是没变...... 解决方案 在开发者模式下停用...

领域驱动设计(DDD:Domain-Driven Design)

软件开发要干什么: 反映真实世界要自动化的业务流程 解决现实问题 领域Domain Domain特指软件关注的领域 在不能充分了解业务领域的情况下是不可能做出一个好的软件 领域建模         领域模型驱动设计 分层架构 实体 值对象 服务 模块 聚合 工厂 资源库 分层架构:   将领域模型相关的代码集中到一个层中,把它从用户界面、应...

lua二进制操作函数

  由于 Lua 脚本语言本身不支持对数字的二进制操作(例如 与,或,非 等操作),MUSHclient 为此提供了一套专门用于二进制操作的函数,它们都定义在一个“bit”表中,使用时只要requre “bit”即可。 bit.ashr - 带符号的按位右移   此函数需要两个整数作为参数。第一个参数可以带有符号,是被以为的数,第二个参数是一个无符号整数,...

delphi中的常用数学函数

delphi中的常用数学函数 定义:function Power(X,Y): (Same type as parameter); 说明:X可以是整型,也可以是实型;返回值实型例子:vari:integer;begini := Power(3,4); { 81}end. 求绝对值函数abs(x)定义:function Abs(X): (Same type...

Qt 事件机制

【1】事件 事件是可以被控件识别的操作。如按下确定按钮、选择某个单选按钮或复选框。 每种控件有自己可识别的事件,如窗体的加载、单击、双击等事件,编辑框(文本框)的文本改变事件等等。 事件就是用户对窗口上各种组件的操作。 【2】Qt事件 由窗口系统或Qt自身产生的,用以响应所发生各类事情的操作。具体点,Qt事件是一个QEvent对象,用于描述程序内部或外部发...