熟悉一个新的平台或者一个新的工具最好的方式就是从头到尾踏实的完成一个机器学习项目

这里以PimaIndiansdiabetes.csv 数据集为例。

Download Data Set

PimaIndiansdiabetes.csv 数据集介绍

  • 1、该数据集最初来自国家糖尿病/消化/肾脏疾病研究所。数据集的目标是基于数据集中包含的某些诊断测量来诊断性的预测 患者是否患有糖尿病。
  • 2、从较大的数据库中选择这些实例有几个约束条件。尤其是,这里的所有患者都是Pima印第安至少21岁的女性。
  • 3、数据集由多个医学预测变量和一个目标变量组成Outcome。预测变量包括患者的怀孕次数、BMI、胰岛素水平、年龄等。
  • 4、数据集的内容是皮马人的医疗记录,以及过去5年内是否有糖尿病。所有的数据都是数字,问题是(是否有糖尿病是1或0),是二分类问题。数据有8个属性,1个类别:
    • 【1】Pregnancies:怀孕次数
    • 【2】Glucose:葡萄糖
    • 【3】BloodPressure:血压 (mm Hg)
    • 【4】SkinThickness:皮层厚度 (mm)
    • 【5】Insulin:胰岛素 2小时血清胰岛素(mu U / ml )
    • 【6】BMI:体重指数 (体重/身高)^2 )
    • 【7】DiabetesPedigreeFunction:糖尿病谱系功能
    • 【8】Age:年龄 (岁)
    • 【9】Outcome:类标变量 (0或1)

数据可视化了解数据集的结构

现在是时候看一下我们的数据集了。当前步骤中我们从不同的角度观察数据。

加载数据集

首先import pandas模块调用read_csv方法加载数据集。

1
2
3
4
from pandas import read_csv
# 加载数据集
filename = 'pima-indians-diabetes.csv'
dataset = read_csv(filename, header=None)

显示数据实例个数、属性个数

使用pandas中的shape方法查看数据集的维度特征,显示数据实例个数(行)、属性个数(列)。

1
2
3
# 显示数据实例个数、属性个数
dataset.shape
#(768, 9)

看到有768个实例,9个属性。

前10个样本情况

使用head 方法观察数据前10行。实际地仔细观察数据向来都是好办法。

1
2
# 前10个样本情况
dataset.head(10)
012345678
061487235033.60.627501
11856629026.60.351310
28183640023.30.672321
318966239428.10.167210
40137403516843.12.288331
55116740025.60.201300
637850328831.00.248261
71011500035.30.134290
82197704554330.50.158531
9812596000.00.232541

显示每个属性的统计概要

看一下每个属性的统计概要。

这里包括总数,均值,std,最小值,最大值以及一些百分比。

1
2
# 显示每个属性的统计概要(包括总数,均值,最小值,最大值以及一些百分比)
dataset.describe()
012345678
count768.000000768.000000768.000000768.000000768.000000768.000000768.000000768.000000768.000000
mean3.845052120.89453169.10546920.53645879.79947931.9925780.47187633.2408850.348958
std3.36957831.97261819.35580715.952218115.2440027.8841600.33132911.7602320.476951
min0.0000000.0000000.0000000.0000000.0000000.0000000.07800021.0000000.000000
25%1.00000099.00000062.0000000.0000000.00000027.3000000.24375024.0000000.000000
50%3.000000117.00000072.00000023.00000030.50000032.0000000.37250029.0000000.000000
75%6.000000140.25000080.00000032.000000127.25000036.6000000.62625041.0000001.000000
max17.000000199.000000122.00000099.000000846.00000067.1000002.42000081.0000001.000000

箱线盒图

导入matplotlib,绘制每一个输入变量的箱线图。这能让我们更清晰的了解输入属性的分布情况。

1
2
3
4
from matplotlib import pyplot
# 线盒图
dataset.plot(kind='box')
pyplot.show()

img

柱状图

1
2
3
# 柱状图
dataset.hist()
pyplot.show()

img

看起来输入变量中有3个可能符合高斯分布。这个现象值得注意,我们可以使用基于这个假设的算法。

多变量散点图

看一下变量之间的相互关系,所有属性两两一组互相对比的散点图。这种图有助于我们定位输入变量间的结构性关系。

1
2
3
4
# 多变量散点图
from pandas.plotting import scatter_matrix
scatter_matrix(dataset)
pyplot.show()

注意下图中某些属性两两比对时延对角线出现的分组现象。这其实表明高度的相关性和可预测关系。

img

交叉验证

交叉验证的基本思想是把在某种意义下将原始数据进行分组,一部分做为训练集,另一部分做为验证集,首先用训练集对分类器进行训练,再利用验证集来测试训练得到的模型,以此来做为评价分类器的性能指标。

用交叉验证的目的是为了得到可靠稳定的模型。

对数据进行3、5、7交叉验证,比较结果。

十折交叉验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# MLP for Pima Indians Dataset with 10-fold cross validation via sklearn
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
import numpy


# Function to create model, required for KerasClassifier
def create_model():
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model


# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load pima indians dataset
dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:, 0:8]
Y = dataset[:, 8]
# create model
model = KerasClassifier(build_fn=create_model,
epochs=150,
batch_size=10)
# evaluate using 10-fold cross validation
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())

3 交叉验证

1
2
3
4
# 3 交叉验证
kfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())

5 交叉验证

1
2
3
kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())

7 交叉验证

1
2
3
4
# 7 交叉验证
kfold = StratifiedKFold(n_splits=7, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())

结果

交叉验证Result
30.75
50.7252864837646484
70.7383295553071159
100.7382946014404297

改变神经网络结构

加深,加宽,看看什么结构对模型性能有较大影响。

加深

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 改变神经网络结构,(加深,加宽),看看什么结构对模型性能有较大影响。
# 加深
def create_model_1():
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(12, input_dim=12,activation='relu'))
model.add(Dense(12, input_dim=12,activation='relu'))
model.add(Dense(12,input_dim=12, activation='relu'))
model.add(Dense(12,input_dim=12, activation='relu'))
model.add(Dense(8, input_dim=12,activation='relu'))
model.add(Dense(8, input_dim=8,activation='relu'))
model.add(Dense(8, input_dim=8,activation='relu'))
model.add(Dense(8, input_dim=8,activation='relu'))
model.add(Dense(8, input_dim=8,activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model
model = KerasClassifier(build_fn=create_model_1,
epochs=150,
batch_size=10)
kfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())

加宽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 改变神经网络结构,(加深,加宽),看看什么结构对模型性能有较大影响。
# 加宽
def create_model_2():
# create model
model = Sequential()
model.add(Dense(24, input_dim=8, activation='relu'))
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model
model = KerasClassifier(build_fn=create_model_2,
epochs=150,
batch_size=10)
kfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())

加深加宽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 改变神经网络结构,(加深,加宽),看看什么结构对模型性能有较大影响。
# 加宽 加深
def create_model_2():
# create model
model = Sequential()
model.add(Dense(24, input_dim=8, activation='relu'))
model.add(Dense(24, input_dim=24, activation='relu'))
model.add(Dense(24, input_dim=24, activation='relu'))
model.add(Dense(24, input_dim=24, activation='relu'))
model.add(Dense(24, input_dim=24, activation='relu'))
model.add(Dense(12, input_dim=24, activation='relu'))
model.add(Dense(12, input_dim=12, activation='relu'))
model.add(Dense(12, input_dim=12, activation='relu'))
model.add(Dense(12, input_dim=12, activation='relu'))
model.add(Dense(12, input_dim=12, activation='relu'))
model.add(Dense(12, input_dim=12, activation='relu'))
model.add(Dense(8, input_dim=12, activation='relu'))
model.add(Dense(8, input_dim=12, activation='relu'))
model.add(Dense(8, input_dim=12, activation='relu'))
model.add(Dense(8, input_dim=12, activation='relu'))
model.add(Dense(8, input_dim=12, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model


model = KerasClassifier(build_fn=create_model_2, epochs=150, batch_size=10)
kfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())

结果

操作Resault
加深0.7096354166666666
加宽0.7057291666666666
加深加宽0.7174479166666666
  • 更深的模型,意味着更好的非线性表达能力,可以学习更加复杂的变换,从而可以拟合更加复杂的特征输入。

  • 网络更深,每一层要做的事情也更加简单了。

    上面就是网络加深带来的两个主要好处,更强大的表达能力和逐层的特征学习

    而宽度就起到了另外一个作用,那就是让每一层学习到更加丰富的特征,比如不同方向,不同频率的纹理特征。

可视化训练过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 可视化训练过程(损失函数关系图,精确度关系图)
import matplotlib.pyplot as plt
# Fit the model
model = KerasClassifier(build_fn=create_model,
epochs=150,
batch_size=10)
history = model.fit(X,
Y,
validation_split=0.33,
epochs=150,
batch_size=10,
verbose=0)
# list all data in history
print(history.history.keys())

# summarize history for accuracy
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# summarize history for loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

img

img

源码

评论