python 多分类模型优化_【Python与机器学习】:利用Keras进行多类分类

多类分类问题本质上可以分解为多个二分类问题,而解决二分类问题的方法有很多。这里我们利用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. 参考

你可能感兴趣的:(python,多分类模型优化)