Written Part
1. 给定包含属性{Height, Hair, Eye}和两个类别{C1, C2}的数据集。构建基于信息增益(info gain)的决策树。
Height | Hair | Eye | Class | |
1 | Tall | Blond | Brown | C1 |
2 | Tall | Dark | Blue | C1 |
3 | Tall | Dark | Brown | C1 |
4 | Short | Dark | Blue | C1 |
5 | Short | Blond | Brown | C1 |
6 | Tall | Red | Blue | C2 |
7 | Tall | Blond | Blue | C2 |
8 | Short | Blond | Blue | C2 |
9 | Medium | Dark | Blue | C2 |
表 1 数据集
决策树算法框架如下所示:
输入:
训练集
D
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
.
.
.
,
(
x
m
,
y
m
)
}
;
属性值
A
=
{
a
1
,
a
2
,
.
.
.
,
a
d
}
过程:
函数
T
r
e
e
G
e
n
e
r
a
t
e
(
D
,
A
)
输出:
以
n
o
d
e
为根结点的一棵决策树
\begin{array}{ll} \textbf{输入:}&\space训练集\space D = \{(\pmb{x}_1,y_1),(\pmb{x}_2,y_2),...,(\pmb{x}_m,y_m)\};\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\\ &\space属性值 \space A=\{a_1,a_2,...,a_d\} \\ \textbf{过程:}&\space函数\space TreeGenerate(D, A) \\ \textbf{输出:}&\space 以 \space node \space 为根结点的一棵决策树 \end{array}
输入:过程:输出: 训练集 D={(x1,y1),(x2,y2),...,(xm,ym)}; 属性值 A={a1,a2,...,ad} 函数 TreeGenerate(D,A) 以 node 为根结点的一棵决策树
1 : 生成结点 n o d e ; 2 : if D 中样本全属于同一类别 C then 3 : 将 n o d e 标记为 C 类叶结点 ; return 4 : end if 5 : if A ≠ ∅ OR D 中样本在 A 上取值相同 then 6 : 将 n o d e 标记为叶结点,其类别标记为 D 中样本数最多的类 ; return 7 : end if 8 : 从 A 中选择最优划分属性 a ∗ ; 9 : for a ∗ 的每一个值 a ∗ v do 10 : 为 n o d e 生成一个分支 ; 令 D v 表示 D 中在 a ∗ 上取值为 a ∗ v 的样本子集 ; 11 : if D v 为空 then 12 : 将分支结点标记为叶结点 , 其类别标记为 D 中样本数最多的类 ; return 13 : else 14 : 以 T r e e G e n e r a t e ( D v , A \ { a ∗ } ) 为分支结点 15 : end if 16 : end for \begin{array}{rl} 1:&生成结点\space node;\\ % 2:&\textbf{if} \space\space D\space 中样本全属于同一类别 \space C\space\space \textbf{then} \\ % 3:& \space\space \space\space 将\space node \space 标记为 \space C \space 类叶结点;\textbf{return}\\ % 4:& \textbf{end}\space \textbf{if}\\ % 5:&\textbf{if}\space\space A\ne \varnothing\space\space \textbf{OR} \space\space D\space 中样本在\space A\space 上取值相同\space \textbf{then} \\ % 6:&\space\space \space\space 将\space node\space 标记为叶结点,其类别标记为 \space D\space 中样本数最多的类;\textbf{return}\\ % 7:&\textbf{end}\space \textbf{if} \\ % 8:&从 \space A \space 中选择最优划分属性 \space a_*;\\ % 9:&\textbf{for} \space\space a_*\space 的每一个值\space a_*^v\space \textbf{do}\\ % 10:&\space\space\space\space 为\space node\space 生成一个分支;\space 令\space D_v\space 表示\space D\space中在\space a_*\space上取值为\space a_*^v\space 的样本子集;\\ % 11:&\space\space\space\space\textbf{if}\space D_v \space为空\space \textbf{then}\\ % 12:&\space\space\space\space\space\space\space\space将分支结点标记为叶结点,\space其类别标记为 \space D\space中样本数最多的类;\textbf{return}\\ % 13:&\space\space\space\space \textbf{else}\\ % 14:&\space\space\space\space\space\space\space\space 以 \space TreeGenerate(D_v,A\space\verb|\|\space \{a_*\})\space为分支结点\\ % 15:&\space\space\space\space \textbf{end}\space \textbf{if}\\ % 16:&\textbf{end}\space\textbf{for} \end{array} 1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:生成结点 node;if D 中样本全属于同一类别 C then 将 node 标记为 C 类叶结点;returnend ifif A=∅ OR D 中样本在 A 上取值相同 then 将 node 标记为叶结点,其类别标记为 D 中样本数最多的类;returnend if从 A 中选择最优划分属性 a∗;for a∗ 的每一个值 a∗v do 为 node 生成一个分支; 令 Dv 表示 D 中在 a∗ 上取值为 a∗v 的样本子集; if Dv 为空 then 将分支结点标记为叶结点, 其类别标记为 D 中样本数最多的类;return else 以 TreeGenerate(Dv,A \ {a∗}) 为分支结点 end ifend for
对于基于信息增益的决策树算法而言,上面框架中划分属性的方法为选择信息增益最大的属性进行划分。形式化地,假设离散属性
a
a
a 有
V
V
V 个可能的取值
{
a
1
,
a
2
,
.
.
.
,
a
V
}
\{a^1,a^2,...,a^V\}
{a1,a2,...,aV},若使用
a
a
a 来对样本集
D
D
D 进行划分,则会产生
V
V
V 个分支结点,其中第
v
v
v 个分支结点包含了
D
D
D 中所有在属性
a
a
a 上取值为
a
v
a^v
av 的样本,记为
D
v
D^v
Dv 。可以根据式
(
3
)
(3)
(3) 计算出
D
v
D^v
Dv 的信息熵,再考虑到不同分支结点所包含的样本数不同,给分支结点赋予权重
∣
D
v
∣
/
∣
D
∣
|D^v|/|D|
∣Dv∣/∣D∣,即样本数越多的分支结点的影响越大,于是可以计算出用属性
a
a
a 对样本集
D
D
D 进行划分所获得的“信息增益”(information gain)
G
a
i
n
(
D
,
a
)
=
E
n
t
(
D
)
−
∑
v
=
1
V
D
v
∣
D
∣
E
n
t
(
D
v
)
\begin{align} Gain(D, a)=Ent(D)-\sum_{v=1}^V\space \frac{D^v}{|D|}Ent(D^v)\tag{1} \end{align}
Gain(D,a)=Ent(D)−v=1∑V ∣D∣DvEnt(Dv)(1)
从公式上来看,信息增益表示父结点的信息熵与子结点信息熵加权和之差。一般而言,信息增益越大,则意味着使用属性
a
a
a 来进行划分所获得的“纯度提升”越大。
对于本题而言,规定
H
e
i
g
h
t
=
{
T
a
l
l
,
M
e
d
i
u
m
,
S
h
o
r
t
}
\rm Height = \{Tall, Medium, Short\}
Height={Tall,Medium,Short},
H
a
i
r
=
{
B
l
o
n
d
,
D
a
r
k
,
R
e
d
}
\rm Hair = \{Blond, Dark, Red\}
Hair={Blond,Dark,Red},
{
B
l
u
e
,
B
r
o
w
n
}
\rm \{Blue, Brown\}
{Blue,Brown},整个数据集记为
D
D
D。则
E
n
t
(
D
)
=
−
(
4
9
log
4
9
+
5
9
log
5
9
)
Ent(D) = -(\frac{4}{9}\log \frac{4}{9} + \frac{5}{9}\log\frac{5}{9})
Ent(D)=−(94log94+95log95),首先考虑属性
H
e
i
g
h
t
\rm Height
Height,
E
n
t
(
D
1
)
=
−
(
4
5
log
4
5
+
1
5
log
1
5
)
E
n
t
(
D
2
)
=
−
(
1
log
1
)
E
n
t
(
D
3
)
=
−
(
2
3
log
2
3
+
1
3
log
1
3
)
\begin{align} Ent(D^1)&=-(\frac{4}{5}\log \frac{4}{5} + \frac{1}{5}\log \frac{1}{5})\notag \\ Ent(D^2)&=-(1\log 1) \notag\\ Ent(D^3)&=-(\frac{2}{3}\log \frac{2}{3} + \frac{1}{3}\log \frac{1}{3})\notag \end{align}
Ent(D1)Ent(D2)Ent(D3)=−(54log54+51log51)=−(1log1)=−(32log32+31log31)
所以基于
H
e
i
g
h
t
\rm Height
Height 划分的信息增益为
G
a
i
n
(
D
,
H
e
i
g
h
t
)
=
E
n
t
(
D
)
−
(
5
9
E
n
t
(
D
1
)
+
1
9
E
n
t
(
D
2
)
+
3
9
E
n
t
(
D
3
)
)
≈
0.1456
Gain(D, {\rm Height}) = Ent(D) - (\frac{5}{9} Ent(D^1) +\frac{1}{9} Ent(D^2) + \frac{3}{9}Ent(D^3) ) ≈ 0.1456
Gain(D,Height)=Ent(D)−(95Ent(D1)+91Ent(D2)+93Ent(D3))≈0.1456(保留四位小数)。类似地可以计算出
G
a
i
n
(
D
,
H
a
i
r
)
≈
0.1861
Gain(D, {\rm Hair}) ≈ 0.1861
Gain(D,Hair)≈0.1861,
G
a
i
n
(
D
,
E
y
e
)
≈
0.3789
Gain(D, {\rm Eye})≈ 0.3789
Gain(D,Eye)≈0.3789。因此,选择属性 Eye 进行划分,结果如图
1
1
1 所示。
图 1 按属性 Eye 划分
对 Blue 分支进一步进行划分, G a i n ( D 1 , H e i g h t ) ≈ 0.1258 Gain(D^1, {\rm Height}) ≈0.1258 Gain(D1,Height)≈0.1258, G a i n ( D 1 , H a i r ) ≈ 0.459 Gain(D^1, {\rm Hair})≈0.459 Gain(D1,Hair)≈0.459,因此,Blue 分支选择属性 Hiar 进行划分。对 Brown 分支进一步划分,由于 Brown 分支中样本标签均为 C1,所以划分结束,该节点被标记为 C1 类。结果如图 2 2 2 所示。
图 2 按属性 Hair 划分
由于 Blond 分支和 Red 分支中的样本类别均 C2,所以结束划分,标记为 C2 类。对 Dark 分支进行划分, G a i n ( D 12 , H e i g h t ) ≈ 0.9183 Gain(D^{12}, {\rm Height})≈0.9183 Gain(D12,Height)≈0.9183,Tall 分支、Medium 分支和 Short 分支中的样本均已纯粹,所以最终构建的决策树如图 3 3 3 所示。
图 3 按属性 Height 划分
使用到的代码如下:
from math import log
"""
函数说明:创建测试数据集
"""
def createDataSet():
dataSet = [[0, 0, 1, 'C1'], # 数据集
[0, 1, 0, 'C1'],
[0, 1, 1, 'C1'],
[2, 1, 0, 'C1'],
[2, 0, 1, 'C1'],
[0, 2, 0, 'C2'],
[0, 0, 0, 'C2'],
[2, 0, 0, 'C2'],
[1, 1, 0, 'C2']]
labels = ['Height', 'Hiar', 'Eye'] # 分类属性
return dataSet, labels # 返回数据集和分类属性
"""
函数说明:计算给定数据集的经验熵(香农熵)
Parameters:
dataSet - 数据集
Returns:
shannonEnt - 经验熵(香农熵)
"""
def calcShannonEnt(dataSet):
numEntires = len(dataSet) # 返回数据集的行数
labelCounts = {} # 保存每个标签(Label)出现次数的字典
for featVec in dataSet: # 对每组特征向量进行统计
currentLabel = featVec[-1] # 提取标签(Label)信息
if currentLabel not in labelCounts.keys(): # 如果标签(Label)没有放入统计次数的字典,添加进去
labelCounts[currentLabel] = 0
labelCounts[currentLabel] += 1 # Label计数
shannonEnt = 0.0 # 经验熵(香农熵)
for key in labelCounts: # 计算香农熵
prob = float(labelCounts[key]) / numEntires # 选择该标签(Label)的概率
shannonEnt -= prob * log(prob, 2) # 利用公式计算
return shannonEnt # 返回经验熵(香农熵)
"""
函数说明:按照给定特征划分数据集
Parameters:
dataSet - 待划分的数据集
axis - 划分数据集的特征
value - 需要返回的特征的值
"""
def splitDataSet(dataSet, axis, value):
retDataSet = [] # 创建返回的数据集列表
for featVec in dataSet: # 遍历数据集
if featVec[axis] == value:
reducedFeatVec = featVec[:axis] # 去掉axis特征
reducedFeatVec.extend(featVec[axis + 1:]) # 将符合条件的添加到返回的数据集
retDataSet.append(reducedFeatVec)
return retDataSet # 返回划分后的数据集
"""
函数说明:选择最优特征
Parameters:
dataSet - 数据集
Returns:
bestFeature - 信息增益最大的(最优)特征的索引值
"""
def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0]) - 1 # 特征数量
baseEntropy = calcShannonEnt(dataSet) # 计算数据集的香农熵
bestInfoGain = 0.0 # 信息增益
bestFeature = -1 # 最优特征的索引值
for i in range(numFeatures): # 遍历所有特征
# 获取dataSet的第i个所有特征
featList = [example[i] for example in dataSet]
uniqueVals = set(featList) # 创建set集合{},元素不可重复
newEntropy = 0.0 # 经验条件熵
for value in uniqueVals: # 计算信息增益
subDataSet = splitDataSet(dataSet, i, value) # subDataSet划分后的子集
prob = len(subDataSet) / float(len(dataSet)) # 计算子集的概率
newEntropy += prob * calcShannonEnt(subDataSet) # 根据公式计算经验条件熵
infoGain = baseEntropy - newEntropy # 信息增益
print("第%d个特征的增益为%.4f" % (i, infoGain)) # 打印每个特征的信息增益
if (infoGain > bestInfoGain): # 计算信息增益
bestInfoGain = infoGain # 更新信息增益,找到最大的信息增益
bestFeature = i # 记录信息增益最大的特征的索引值
return bestFeature # 返回信息增益最大的特征的索引值
if __name__ == '__main__':
dataSet, features = createDataSet()
entropy = calcShannonEnt(dataSet)
bestfeature = chooseBestFeatureToSplit(dataSet)
print("数据集的熵为:%f" % (entropy))
print("最优特征索引值:" + str(bestfeature))
2. 为表 1 1 1 数据集设计包含一个隐藏层的多层前馈神经网络,标明输入层和输出层中的节点。使用这个神经网络,在给定训练实例 “(Medium, Dark, Brown, C2)” 的情况下,计算反向传播算法一次迭代后的权重值。注意注明初始权重值和偏置,以及使用的学习率。
包含一个隐藏层的前馈神经网络如图 4 4 4 所示。隐藏层和输出层的每个神经元均对应一个偏置,图中没有画出。
图 4 单隐层前馈神经网络
形式化的反向传播链式求导过程如下。规定符号:
- 第 k k k 层的权重记为 W ( k ) = ( w i j ( k ) ) W^{(k)}=(w_{ij}^{(k)}) W(k)=(wij(k)),其中 w i j ( k ) w_{ij}^{(k)} wij(k) 表示第 k − 1 k-1 k−1 层的第 j j j 个节点连接第 k k k 层的第 i i i 个节点的权重。
- 第 k k k 层的偏置项记为 b ( k ) = ( b i ( k ) ) b^{(k)} = (b^{(k)}_i) b(k)=(bi(k)),其中 b i ( k ) b_i^{(k)} bi(k) 表示第 k − 1 k-1 k−1 层与第 k k k 层的第 i i i 个节点连接的偏置。
- 第 k k k 层的净输出(未经过激活)记为 z ( k ) = W ( k ) T a ( k − 1 ) + b ( k ) z^{(k)} = {W^{(k)}}^Ta^{(k-1)} + b^{(k)} z(k)=W(k)Ta(k−1)+b(k) 。
- 第 k k k 层的输出记为 a ( k ) = f ( z ( k ) ) a^{(k)} = f(z^{(k)}) a(k)=f(z(k)),其中 f f f 为激活函数。因此,对于具有 m m m 层的网络,第 m m m 层的输出 a ( m ) a^{(m)} a(m) 表示网络的输出。
- 特别地,假设第 0 0 0 层为输入层,则有第 0 0 0 层的输出为网络的输入,记为 z ( 0 ) = a ( 0 ) = X z^{(0)} = a^{(0)} = X z(0)=a(0)=X,其中 X X X 为网络输入。
- 输入 X X X 对应的真实标签为 Y Y Y。
对于输入层而言,输入样本为 z ( 0 ) = a ( 0 ) = X z^{(0)} = a^{(0)}=X z(0)=a(0)=X,即 ( z 1 ( 0 ) , z 2 ( 0 ) , z 3 ( 0 ) ) = ( a 1 ( 0 ) , a 2 ( 0 ) , a 3 ( 0 ) ) = ( x 1 , x 2 , x 3 ) (z^{(0)}_1, z^{(0)}_2,z^{(0)}_3) = (a_1^{(0)}, a_2^{(0)}, a_3^{(0)}) = (x_1, x_2, x_3) (z1(0),z2(0),z3(0))=(a1(0),a2(0),a3(0))=(x1,x2,x3)。
对于隐藏层而言,存在
z
1
(
1
)
=
w
11
(
0
)
a
1
(
0
)
+
w
12
(
0
)
a
2
(
0
)
+
w
13
(
0
)
a
3
(
0
)
+
b
1
(
0
)
z
2
(
1
)
=
w
21
(
0
)
a
1
(
0
)
+
w
22
(
0
)
a
2
(
0
)
+
w
23
(
0
)
a
3
(
0
)
+
b
2
(
0
)
z
3
(
1
)
=
w
31
(
0
)
a
1
(
0
)
+
w
32
(
0
)
a
2
(
0
)
+
w
33
(
0
)
a
3
(
0
)
+
b
3
(
0
)
z
4
(
1
)
=
w
41
(
0
)
a
1
(
0
)
+
w
42
(
0
)
a
2
(
0
)
+
w
43
(
0
)
a
3
(
0
)
+
b
4
(
0
)
a
1
(
1
)
=
f
(
z
1
(
1
)
)
a
2
(
1
)
=
f
(
z
2
(
1
)
)
a
3
(
1
)
=
f
(
z
3
(
1
)
)
a
4
(
1
)
=
f
(
z
4
(
1
)
)
z_1^{(1)} = w_{11}^{(0)}a_1^{(0)} + w_{12}^{(0)}a_2^{(0)} + w_{13}^{(0)}a_3^{(0)} + b_1^{(0)} \\ z_2^{(1)} = w_{21}^{(0)}a_1^{(0)} + w_{22}^{(0)}a_2^{(0)} + w_{23}^{(0)}a_3^{(0)} + b_2^{(0)} \\ z_3^{(1)} = w_{31}^{(0)}a_1^{(0)} + w_{32}^{(0)}a_2^{(0)} + w_{33}^{(0)}a_3^{(0)} + b_3^{(0)} \\ z_4^{(1)} = w_{41}^{(0)}a_1^{(0)} + w_{42}^{(0)}a_2^{(0)} + w_{43}^{(0)}a_3^{(0)} + b_4^{(0)} \\ a_1^{(1)} = f(z_1^{(1)}) \\ a_2^{(1)} = f(z_2^{(1)}) \\ a_3^{(1)} = f(z_3^{(1)}) \\ a_4^{(1)} = f(z_4^{(1)}) \\
z1(1)=w11(0)a1(0)+w12(0)a2(0)+w13(0)a3(0)+b1(0)z2(1)=w21(0)a1(0)+w22(0)a2(0)+w23(0)a3(0)+b2(0)z3(1)=w31(0)a1(0)+w32(0)a2(0)+w33(0)a3(0)+b3(0)z4(1)=w41(0)a1(0)+w42(0)a2(0)+w43(0)a3(0)+b4(0)a1(1)=f(z1(1))a2(1)=f(z2(1))a3(1)=f(z3(1))a4(1)=f(z4(1))
对于输出层而言,存在
z
1
(
2
)
=
w
11
(
1
)
a
1
(
1
)
+
w
12
(
1
)
a
2
(
1
)
+
w
13
(
1
)
a
3
(
1
)
+
w
14
(
1
)
a
4
(
1
)
+
b
1
(
1
)
z
2
(
2
)
=
w
21
(
1
)
a
1
(
1
)
+
w
22
(
1
)
a
2
(
1
)
+
w
23
(
1
)
a
3
(
1
)
+
w
14
(
1
)
a
4
(
1
)
+
b
2
(
1
)
a
1
(
2
)
=
f
(
z
1
(
2
)
)
a
2
(
2
)
=
f
(
z
2
(
2
)
)
z_1^{(2)} = w_{11}^{(1)}a_1^{(1)} + w_{12}^{(1)}a_2^{(1)} + w_{13}^{(1)}a_3^{(1)} + w_{14}^{(1)}a_4^{(1)} + b_1^{(1)} \\ z_2^{(2)} = w_{21}^{(1)}a_1^{(1)} + w_{22}^{(1)}a_2^{(1)} + w_{23}^{(1)}a_3^{(1)} + w_{14}^{(1)}a_4^{(1)} + b_2^{(1)} \\ a_1^{(2)} = f(z_1^{(2)}) \\ a_2^{(2)} = f(z_2^{(2)}) \\
z1(2)=w11(1)a1(1)+w12(1)a2(1)+w13(1)a3(1)+w14(1)a4(1)+b1(1)z2(2)=w21(1)a1(1)+w22(1)a2(1)+w23(1)a3(1)+w14(1)a4(1)+b2(1)a1(2)=f(z1(2))a2(2)=f(z2(2))
其中激活函数
f
f
f 采用 Sigmoid。
假设采用均方误差(MSE)作为损失函数,所以有 L ( W , b ) = 1 2 [ ( y 1 − a 1 ( 2 ) ) 2 + ( y 2 − a 2 ( 2 ) ) 2 ] \mathcal L(W, b) = \frac{1}{2}[(y_1-a^{(2)}_1)^2 + (y_2 - a_2^{(2)})^2] L(W,b)=21[(y1−a1(2))2+(y2−a2(2))2]。反向传播首先要计算损失函数 L \mathcal L L 关于模型参数的导数(梯度),以计算 ∂ L / ∂ w 11 ( 1 ) \partial \mathcal L/\partial w^{(1)}_{11} ∂L/∂w11(1) 为例,同层其它参数(包括 w i j ( 1 ) w^{(1)}_{ij} wij(1) 和 b i ( 1 ) b^{(1)}_i bi(1))类似。推导过程如下:
∂ L ∂ w 11 ( 1 ) = ∂ 1 2 [ ( y 1 − a 1 ( 2 ) ) 2 + ( y 2 − a 2 ( 2 ) ) 2 ] ∂ w 11 ( 2 ) = 1 2 ∂ [ ( y 1 − a 1 ( 2 ) ) 2 ] ∂ w 11 ( 1 ) + 1 2 ∂ [ ( y 2 − a 2 ( 2 ) ) 2 ] ∂ w 11 ( 1 ) = 1 2 ∂ [ ( y 1 − a 1 ( 2 ) ) 2 ] ∂ w 11 ( 1 ) = 1 2 ∂ [ ( y 1 − a 1 ( 2 ) ) 2 ] ∂ z 1 ( 2 ) ∂ z 1 ( 2 ) ∂ w 11 ( 1 ) = − ( y 1 − f ( z 1 ( 2 ) ) ) ∂ f ( z 1 ( 2 ) ) ∂ z 1 ( 2 ) ∂ z 1 ( 2 ) ∂ w 11 ( 1 ) = − ( y 1 − f ( z 1 ( 2 ) ) ) f ′ ( z 1 ( 2 ) ) ∂ z 1 ( 2 ) ∂ w 11 ( 1 ) = − ( y 1 − f ( z 1 ( 2 ) ) ) f ′ ( z 1 ( 2 ) ) ∂ ( w 11 ( 1 ) a 1 ( 1 ) + w 12 ( 1 ) a 2 ( 1 ) + w 13 ( 1 ) a 3 ( 1 ) + w 14 ( 1 ) a 4 ( 1 ) + b 1 ( 1 ) ) ∂ w 11 ( 1 ) = − ( y 1 − f ( z 1 ( 2 ) ) ) f ′ ( z 1 ( 2 ) ) a 1 ( 1 ) \begin{align} \frac{\partial \mathcal L}{\partial w_{11}^{(1)}} &= \frac{\partial \frac{1}{2}[(y_1-a^{(2)}_1)^2 + (y_2 - a_2^{(2)})^2]}{\partial w_{11}^{(2)}} \notag\\ &= \frac{1}{2} \frac{\partial [(y_1-a^{(2)}_1)^2]}{\partial w_{11}^{(1)}} + \frac{1}{2} \frac{\partial [(y_2-a^{(2)}_2)^2]}{\partial w_{11}^{(1)}} \notag\\ &= \frac{1}{2} \frac{\partial [(y_1-a^{(2)}_1)^2]}{\partial w_{11}^{(1)}} \notag\\ &= \frac{1}{2} \frac{\partial [(y_1-a^{(2)}_1)^2]}{\partial z_1^{(2)}}\frac{\partial z_1^{(2)}}{\partial w_{11}^{(1)}} \notag\\ &= -(y_1-f(z_1^{(2)}))\frac{\partial f(z_1^{(2)})}{\partial z_1^{(2)}}\frac{\partial z_1^{(2)}}{\partial w_{11}^{(1)}} \notag\\ &= -(y_1 - f(z_1^{(2)}))f'(z_1^{(2)})\frac{\partial z_1^{(2)}}{\partial w_{11}^{(1)}} \notag\\ &= -(y_1 - f(z_1^{(2)}))f'(z_1^{(2)})\frac{\partial (w_{11}^{(1)}a_1^{(1)} + w_{12}^{(1)}a_2^{(1)} + w_{13}^{(1)}a_3^{(1)} + w_{14}^{(1)}a_4^{(1)} + b_1^{(1)})}{\partial w_{11}^{(1)}} \notag\\ &= -(y_1 - f(z_1^{(2)}))f'(z_1^{(2)})a_1^{(1)} \notag \end{align} ∂w11(1)∂L=∂w11(2)∂21[(y1−a1(2))2+(y2−a2(2))2]=21∂w11(1)∂[(y1−a1(2))2]+21∂w11(1)∂[(y2−a2(2))2]=21∂w11(1)∂[(y1−a1(2))2]=21∂z1(2)∂[(y1−a1(2))2]∂w11(1)∂z1(2)=−(y1−f(z1(2)))∂z1(2)∂f(z1(2))∂w11(1)∂z1(2)=−(y1−f(z1(2)))f′(z1(2))∂w11(1)∂z1(2)=−(y1−f(z1(2)))f′(z1(2))∂w11(1)∂(w11(1)a1(1)+w12(1)a2(1)+w13(1)a3(1)+w14(1)a4(1)+b1(1))=−(y1−f(z1(2)))f′(z1(2))a1(1)
为了展示方便,记 δ 1 ( 2 ) = − ( y 1 − f ( z 1 ( 2 ) ) ) f ′ ( z 1 ( 2 ) ) \delta_1^{(2)} = -(y_1 - f(z_1^{(2)}))f'(z_1^{(2)}) δ1(2)=−(y1−f(z1(2)))f′(z1(2)),因此
∂
L
∂
w
11
(
1
)
=
δ
1
(
2
)
a
1
(
1
)
\frac{\partial \mathcal L}{\partial w_{11}^{(1)}} = \delta_1^{(2)}a_1^{(1)}
∂w11(1)∂L=δ1(2)a1(1)
再向前推一层,以计算
∂
L
/
∂
w
11
(
0
)
\partial \mathcal L/\partial w^{(0)}_{11}
∂L/∂w11(0) 为例,同层其它参数(包括
w
(
0
)
w^{(0)}
w(0) 和
b
(
0
)
b^{(0)}
b(0))类似。推导过程如下:
∂
L
∂
w
11
(
0
)
=
∂
1
2
[
(
y
1
−
a
1
(
2
)
)
2
+
(
y
2
−
a
2
(
2
)
)
2
]
∂
w
11
(
0
)
=
1
2
∂
[
(
y
1
−
a
1
(
2
)
)
2
]
∂
w
11
(
0
)
+
1
2
∂
[
(
y
2
−
a
2
(
2
)
)
2
]
∂
w
11
(
0
)
=
1
2
∂
[
(
y
1
−
f
(
z
1
(
2
)
)
)
2
]
∂
w
11
(
0
)
+
1
2
∂
[
(
y
2
−
f
(
z
2
(
2
)
)
)
2
]
∂
w
11
(
0
)
=
1
2
∂
[
(
y
1
−
f
(
z
1
(
2
)
)
)
2
]
∂
z
1
(
2
)
∂
z
1
(
2
)
∂
w
11
(
0
)
+
1
2
∂
[
(
y
2
−
f
(
z
2
(
2
)
)
)
2
]
∂
z
2
(
2
)
∂
z
2
(
2
)
∂
w
11
(
0
)
=
δ
1
(
2
)
∂
z
1
(
2
)
∂
w
11
(
0
)
+
δ
2
(
2
)
∂
z
2
(
2
)
∂
w
11
(
0
)
\begin{align} \frac{\partial \mathcal L}{\partial w_{11}^{(0)}} &= \frac{\partial \frac{1}{2}[(y_1-a^{(2)}_1)^2 + (y_2 - a_2^{(2)})^2]}{\partial w_{11}^{(0)}} \notag\\ &= \frac{1}{2} \frac{\partial [(y_1-a^{(2)}_1)^2]}{\partial w_{11}^{(0)}} + \frac{1}{2} \frac{\partial [(y_2-a^{(2)}_2)^2]}{\partial w_{11}^{(0)}} \notag\\ &= \frac{1}{2} \frac{\partial [(y_1-f(z^{(2)}_1))^2]}{\partial w_{11}^{(0)}} + \frac{1}{2} \frac{\partial [(y_2-f(z^{(2)}_2))^2]}{\partial w_{11}^{(0)}} \notag\\ &= \frac{1}{2} \frac{\partial [(y_1-f(z^{(2)}_1))^2]}{\partial z_1^{(2)}}\frac{\partial z_1^{(2)}}{\partial w_{11}^{(0)}} + \frac{1}{2} \frac{\partial [(y_2-f(z^{(2)}_2))^2]}{\partial z_2^{(2)}}\frac{\partial z_2^{(2)}}{\partial w_{11}^{(0)}} \notag\\ &= \delta_1^{(2)}\frac{\partial z_1^{(2)}}{\partial w_{11}^{(0)}} + \delta_2^{(2)}\frac{\partial z_2^{(2)}}{\partial w_{11}^{(0)}} \notag\\ \end{align}
∂w11(0)∂L=∂w11(0)∂21[(y1−a1(2))2+(y2−a2(2))2]=21∂w11(0)∂[(y1−a1(2))2]+21∂w11(0)∂[(y2−a2(2))2]=21∂w11(0)∂[(y1−f(z1(2)))2]+21∂w11(0)∂[(y2−f(z2(2)))2]=21∂z1(2)∂[(y1−f(z1(2)))2]∂w11(0)∂z1(2)+21∂z2(2)∂[(y2−f(z2(2)))2]∂w11(0)∂z2(2)=δ1(2)∂w11(0)∂z1(2)+δ2(2)∂w11(0)∂z2(2)
计算 ∂ z 1 ( 2 ) ∂ w 11 ( 0 ) \frac{\partial z_1^{(2)}}{\partial w_{11}^{(0)}} ∂w11(0)∂z1(2) 有:
∂
z
1
(
2
)
∂
w
11
(
0
)
=
∂
(
w
11
(
1
)
a
1
(
1
)
+
w
12
(
1
)
a
2
(
1
)
+
w
13
(
1
)
a
3
(
1
)
+
w
14
(
1
)
a
4
(
1
)
+
b
1
(
1
)
)
∂
w
11
(
0
)
=
∂
(
w
11
(
1
)
a
1
(
1
)
)
∂
w
11
(
0
)
+
∂
(
w
12
(
1
)
a
2
(
1
)
)
∂
w
11
(
0
)
+
∂
(
w
13
(
1
)
a
3
(
1
)
)
∂
w
11
(
0
)
+
∂
(
w
14
(
1
)
a
4
(
1
)
)
∂
w
11
(
0
)
+
∂
(
b
1
(
1
)
)
∂
w
11
(
0
)
=
∂
(
w
11
(
1
)
a
1
(
1
)
)
∂
w
11
(
0
)
=
∂
(
w
11
(
1
)
f
(
z
1
(
1
)
)
)
∂
w
11
(
0
)
=
∂
(
w
11
(
1
)
f
(
z
1
(
1
)
)
)
z
1
(
1
)
∂
z
1
(
1
)
∂
w
11
(
0
)
=
w
11
(
1
)
f
′
(
z
1
(
1
)
)
∂
(
w
11
(
0
)
a
1
(
0
)
+
w
12
(
0
)
a
2
(
0
)
+
w
13
(
0
)
a
3
(
0
)
+
b
1
(
0
)
)
∂
w
11
(
0
)
=
w
11
(
1
)
f
′
(
z
1
(
1
)
)
a
1
(
0
)
\begin{align} \frac{\partial z_1^{(2)}}{\partial w_{11}^{(0)}} &= \frac{\partial (w_{11}^{(1)}a_1^{(1)} + w_{12}^{(1)}a_2^{(1)} + w_{13}^{(1)}a_3^{(1)} + w_{14}^{(1)}a_4^{(1)} + b_1^{(1)})}{\partial w_{11}^{(0)}} \notag\\ &= \frac{\partial (w_{11}^{(1)}a_1^{(1)})}{\partial w_{11}^{(0)}} + \frac{\partial (w_{12}^{(1)}a_2^{(1)})}{\partial w_{11}^{(0)}} + \frac{\partial (w_{13}^{(1)}a_3^{(1)})}{\partial w_{11}^{(0)}} + \frac{\partial (w_{14}^{(1)}a_4^{(1)})}{\partial w_{11}^{(0)}} + \frac{\partial (b_1^{(1)})}{\partial w_{11}^{(0)}} \notag\\ &= \frac{\partial (w_{11}^{(1)}a_1^{(1)})}{\partial w_{11}^{(0)}} \notag\\ &= \frac{\partial (w_{11}^{(1)}f(z_1^{(1)}))}{\partial w_{11}^{(0)}} \notag\\ &= \frac{\partial (w_{11}^{(1)}f(z_1^{(1)}))}{z_1^{(1)}}\frac{\partial z_1^{(1)}}{\partial w_{11}^{(0)}} \notag\\ &= w_{11}^{(1)} f'(z_1^{(1)}) \frac{\partial (w_{11}^{(0)}a_1^{(0)} + w_{12}^{(0)}a_2^{(0)} + w_{13}^{(0)}a_3^{(0)} + b_1^{(0)})}{\partial w_{11}^{(0)}} \notag\\ &= w_{11}^{(1)} f'(z_1^{(1)})a_{1}^{(0)}\notag \end{align}
∂w11(0)∂z1(2)=∂w11(0)∂(w11(1)a1(1)+w12(1)a2(1)+w13(1)a3(1)+w14(1)a4(1)+b1(1))=∂w11(0)∂(w11(1)a1(1))+∂w11(0)∂(w12(1)a2(1))+∂w11(0)∂(w13(1)a3(1))+∂w11(0)∂(w14(1)a4(1))+∂w11(0)∂(b1(1))=∂w11(0)∂(w11(1)a1(1))=∂w11(0)∂(w11(1)f(z1(1)))=z1(1)∂(w11(1)f(z1(1)))∂w11(0)∂z1(1)=w11(1)f′(z1(1))∂w11(0)∂(w11(0)a1(0)+w12(0)a2(0)+w13(0)a3(0)+b1(0))=w11(1)f′(z1(1))a1(0)
同理可以计算得到
∂
z
2
(
2
)
∂
w
11
(
0
)
=
w
21
(
1
)
f
′
(
z
1
(
1
)
)
a
1
(
0
)
\frac{\partial z_2^{(2)}}{\partial w_{11}^{(0)}} =w_{21}^{(1)} f'(z_1^{(1)})a_{1}^{(0)}
∂w11(0)∂z2(2)=w21(1)f′(z1(1))a1(0)
因此
∂
L
∂
w
11
(
0
)
=
δ
1
(
2
)
∂
z
1
(
2
)
∂
w
11
(
0
)
+
δ
2
(
2
)
∂
z
1
(
2
)
∂
w
11
(
0
)
=
δ
1
(
2
)
w
11
(
1
)
f
′
(
z
1
(
1
)
)
a
1
(
0
)
+
δ
2
(
2
)
w
21
(
1
)
f
′
(
z
1
(
1
)
)
a
1
(
0
)
=
a
1
(
0
)
f
′
(
z
1
(
1
)
)
(
δ
1
(
2
)
w
11
(
1
)
+
δ
2
(
2
)
w
21
(
1
)
)
\begin{align} \frac{\partial \mathcal L}{\partial w_{11}^{(0)}} &= \delta_1^{(2)}\frac{\partial z_1^{(2)}}{\partial w_{11}^{(0)}} + \delta_2^{(2)}\frac{\partial z_1^{(2)}}{\partial w_{11}^{(0)}} \notag\\ & = \delta_1^{(2)}w_{11}^{(1)} f'(z_1^{(1)})a_1^{(0)} + \delta_2^{(2)}w_{21}^{(1)} f'(z_1^{(1)})a_1^{(0)} \notag\\ &= a_1^{(0)}f'(z_1^{(1)})(\delta_1^{(2)} w_{11}^{(1)} + \delta_2^{(2)}w_{21}^{(1)}) \notag \end{align}
∂w11(0)∂L=δ1(2)∂w11(0)∂z1(2)+δ2(2)∂w11(0)∂z1(2)=δ1(2)w11(1)f′(z1(1))a1(0)+δ2(2)w21(1)f′(z1(1))a1(0)=a1(0)f′(z1(1))(δ1(2)w11(1)+δ2(2)w21(1))
至此,损失函数
L
\mathcal L
L 关于全部模型参数
W
W
W 和
b
b
b 的导数(梯度)均可以采用类似的方法计算得到。
得到了梯度,反向传播的第一阶段完成。在第二阶段,需要用梯度来更新模型参数:
w
t
+
1
=
w
t
−
η
∂
L
∂
w
t
w^{t+1} = w^{t} - \eta \frac{\partial \mathcal L}{\partial w^{t}}
wt+1=wt−η∂wt∂L
其中
w
t
w^t
wt 表示模型参数
w
w
w 在
t
t
t 时刻的取值,
η
\eta
η 表示学习率。通过不断迭代上述两个阶段,直至满足条件(比如收敛或一定迭代次数)。
使用到的代码如下:
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
seed = 99
torch.manual_seed(seed) # 为CPU设置随机种子
class FFN(nn.Module):
def __init__(self):
super(FFN, self).__init__()
self.hideen = nn.Linear(in_features=3, out_features=4, bias=True)
self.sigmoid = nn.Sigmoid()
self.output = nn.Linear(in_features=4, out_features=2, bias=True)
self.init_weight()
def forward(self, x):
hid = self.sigmoid(self.hideen(x))
out = self.output(hid)
return out
def init_weight(self):
# nn.init.zeros_(self.hideen.weight)
# nn.init.zeros_(self.hideen.bias)
# nn.init.zeros_(self.output.weight)
# nn.init.zeros_(self.output.bias)
initrange = 0.1
nn.init.uniform_(self.hideen.weight, -initrange, initrange)
nn.init.uniform_(self.hideen.bias, -initrange, initrange)
nn.init.uniform_(self.output.weight, -initrange, initrange)
nn.init.uniform_(self.output.bias, -initrange, initrange)
data = torch.tensor([[1, 1, 1]], dtype=torch.float)
label = torch.tensor([1], dtype=torch.long)
learning_rate = 0.01
net = FFN()
optimizer = optim.SGD(params=net.parameters(), lr=learning_rate)
print(net.hideen.weight)
print(net.hideen.bias)
print(net.output.weight)
print(net.output.bias)
# optimizer.zero_grad()
loss = F.cross_entropy(net(data), label)
loss.backward()
optimizer.step()
print(net.hideen.weight)
print(net.hideen.bias)
print(net.output.weight)
print(net.output.bias)
设置随机种子,固定初始化权重,隐藏层权重为 [[ 0.0003, -0.0573, 0.0622],[ 0.0557, -0.0528, -0.0420],[-0.0334, 0.0818, -0.0500],[ 0.0245, 0.0930, 0.0060]]
,偏置为 [-0.0586, 0.0375, -0.0616, 0.0627]
,输出层权重为 [[ 0.0825, 0.0879, 0.0642, -0.0193],[ 0.0865, -0.0596, 0.0958, -0.0133]]
,偏置为 [0.0448, 0.0795]
。
迭代一次后的隐藏层权重为 [[ 0.0003, -0.0573, 0.0622],[ 0.0556, -0.0528, -0.0421],[-0.0334, 0.0818, -0.0500],[ 0.0245, 0.0930, 0.0060]]
,偏置为 [-0.0586, 0.0374, -0.0616, 0.0627]
,输出层权重为 [[ 0.0819, 0.0873, 0.0635, -0.0200],[ 0.0871, -0.0590, 0.0963, -0.0127]]
,偏置为 [0.0434, 0.0806]
。
3. 使用朴素贝叶斯分类器,基于表 1 1 1 数据集对未知样本 Z = (Height = Short, Hair = blond, Eye = brown) 进行分类。
朴素贝叶斯分类器(naive Bayes classifier)采用了“属性条件独立性假设”(attribute conditional independence assumption):对已知类别,假设所有属性相互独立。换言之,假设每个属性独立地对分类结果发生影响。
基于属性条件独立性假设,有:
P
(
c
∣
x
)
=
P
(
c
)
P
(
x
∣
c
)
P
(
x
)
=
P
(
c
)
P
(
x
)
∏
i
=
1
d
P
(
x
i
∣
c
)
(2)
P(c\space |\space \pmb x) = \frac{P(c)P(\pmb x\space|\space c)}{P(\pmb x)}=\frac{P(c)}{P(\pmb x)}\prod_{i=1}^dP(x_i\space|\space c)\tag{2}
P(c ∣ x)=P(x)P(c)P(x ∣ c)=P(x)P(c)i=1∏dP(xi ∣ c)(2)
其中
d
d
d 为属性数目,
x
i
x_i
xi 为
x
\pmb x
x 在第
i
i
i 个属性上的取值。
由于对所有类别来说
P
(
x
)
P(\pmb x)
P(x) 相同,因此贝叶斯判定准则表示为:
h
n
b
(
x
)
=
a
r
g
m
a
x
c
∈
Y
P
(
c
)
∏
i
=
1
d
P
(
x
i
∣
c
)
(3)
h_{nb}(\pmb x)=\mathop{arg \space max} \limits_{c∈\mathcal{Y}}\space P(c) \prod_{i=1}^dP(x_i\space|\space c)\tag{3}
hnb(x)=c∈Yarg max P(c)i=1∏dP(xi ∣ c)(3)
这就是朴素贝叶斯分类器的表达式。
显然,朴素贝叶斯分类器的训练过程就是基于训练集 D D D 来估计类先验概率 P ( c ) P(c) P(c),并为每个属性估计条件概率 P ( x i ∣ c ) P(x_i \space|\space c) P(xi ∣ c) 。
令
D
c
D_c
Dc 表示训练集
D
D
D 中第
c
c
c 类样本组成的集合,若有充足的独立同分布样本,则可容易地估计出类先验概率
P
(
c
)
=
∣
D
c
∣
∣
D
∣
(4)
P(c)=\frac{|D_c|}{|D|}\tag{4}
P(c)=∣D∣∣Dc∣(4)
对离散属性而言,令
D
c
,
x
i
D_{c,x_i}
Dc,xi 表示
D
c
D_c
Dc 中在第
i
i
i 个属性上取值为
x
i
x_i
xi 的样本组成的集合,则条件概率
P
(
x
i
∣
c
)
P(x_i\space |\space c)
P(xi ∣ c) 可估计为
P
(
x
i
∣
c
)
=
∣
D
c
,
x
i
∣
∣
D
c
∣
(5)
P(x_i\space | \space c) = \frac{|D_{c,x_i}|}{|D_c|}\tag{5}
P(xi ∣ c)=∣Dc∣∣Dc,xi∣(5)
对连续属性可考虑概率密度函数,假定
p
(
x
i
∣
c
)
∼
N
(
μ
c
,
i
,
σ
c
,
i
2
)
p(x_i\space |\space c)\sim \mathcal{N}(\mu_{c,i},\sigma_{c,i}^2)
p(xi ∣ c)∼N(μc,i,σc,i2),其中
μ
c
,
i
\mu_{c,i}
μc,i 和
σ
c
,
i
2
\sigma_{c,i}^2
σc,i2 分别是第
c
c
c 类样本在第
i
i
i 个属性上取值的均值和方差,则有
p
(
x
i
∣
c
)
=
1
2
π
σ
c
,
i
e
x
p
(
−
(
x
i
−
μ
c
,
i
2
)
2
σ
c
,
i
2
)
(6)
p(x_i\space|\space c)=\frac{1}{\sqrt{2\pi}\sigma_{c,i}}exp\left(-\frac{(x_i-\mu_{c,i}^2)}{2\sigma_{c,i}^2}\right)\tag{6}
p(xi ∣ c)=2πσc,i1exp(−2σc,i2(xi−μc,i2))(6)
对于样本 Z = (Height = Short, Hair = blond, Eye = brown) 而言,先计算先验概率
P
(
C
1
)
P(\rm C1)
P(C1) 和
P
(
C
2
)
P(\rm C2)
P(C2),
P
(
C
1
)
=
5
9
P({\rm C1}) = \frac{5}{9}
P(C1)=95,
P
(
C
2
)
=
4
9
P({\rm C2}) = \frac{4}{9}
P(C2)=94。针对属性 Height,
P
(
H
e
i
g
h
t
=
S
h
o
r
t
∣
C
1
)
=
2
5
P({\rm Height = Short} \mid {\rm C1}) = \frac{2}{5}
P(Height=Short∣C1)=52,
P
(
H
e
i
g
h
t
=
S
h
o
r
t
∣
C
2
)
=
1
4
P({\rm Height = Short} \mid {\rm C2}) = \frac{1}{4}
P(Height=Short∣C2)=41;针对属性 Hair,
P
(
H
a
i
r
=
b
l
o
n
d
∣
C
1
)
=
2
5
P({\rm Hair = blond}\mid {\rm C1}) = \frac{2}{5}
P(Hair=blond∣C1)=52,
P
(
H
a
i
r
=
b
l
o
n
d
∣
C
2
)
=
1
2
P({\rm Hair = blond}\mid {\rm C2}) = \frac{1}{2}
P(Hair=blond∣C2)=21;针对属性 Eye,
P
(
E
y
e
=
b
r
o
w
n
∣
C
1
)
=
3
5
P({\rm Eye = brown}\mid {\rm C1}) = \frac{3}{5}
P(Eye=brown∣C1)=53,
P
(
E
y
e
=
b
r
o
w
n
∣
C
2
)
=
0
P({\rm Eye= brown}\mid {\rm C2}) = 0
P(Eye=brown∣C2)=0。
因此,
P ( C 1 ∣ Z ) = P ( C 1 ) P ( H e i g h t = S h o r t ∣ C 1 ) P ( H a i r = b l o n d ∣ C 1 ) P ( E y e = B r o w n ∣ C 1 ) = 0.0533 P({\rm C1}\mid {\rm Z}) = P({\rm C1})P({\rm Height = Short} \mid {\rm C1})P({\rm Hair = blond} \mid {\rm C1})P({\rm Eye = Brown} \mid {\rm C1}) = 0.0533 P(C1∣Z)=P(C1)P(Height=Short∣C1)P(Hair=blond∣C1)P(Eye=Brown∣C1)=0.0533; P ( C 2 ∣ Z ) = P ( C 2 ) P ( H e i g h t = S h o r t ∣ C 2 ) P ( H a i r = b l o n d ∣ C 2 ) P ( E y e = B r o w n ∣ C 2 ) = 0 P({\rm C2}\mid {\rm Z}) = P({\rm C2})P({\rm Height = Short} \mid {\rm C2})P({\rm Hair = blond} \mid {\rm C2})P({\rm Eye = Brown} \mid {\rm C2}) = 0 P(C2∣Z)=P(C2)P(Height=Short∣C2)P(Hair=blond∣C2)P(Eye=Brown∣C2)=0;
在不考虑平滑的前提下, P ( E y e = b r o w n ∣ C 2 ) = 0 P({\rm Eye= brown}\mid {\rm C2}) = 0 P(Eye=brown∣C2)=0 导致 P ( C 2 ∣ Z ) P(\rm C2\mid Z) P(C2∣Z) 为 0 0 0。所以样本 Z 被分类为 C1。
Lab Part
假设一家超市想推销意大利面。使用“Transactions.txt”中的数据作为训练数据来构建基于 C5.0 算法的决策树模型,以预测客户是否会购买意大利面。
1. 使用数据集 “Transactions.txt” 构建决策树,利用其它字段来预测 “pasta” 字段。使用 Field Ops 中的 Type 模块,将除了 COD 字段外的每个字段的 “type” 设置为 “Flag”,将 COD 字段的 “type“ 设置为 “Typeless”,将 “pasta” 字段的 “direction” 属性设置为 “out”。使用 Modeling 中的 C5.0 模块,选择 “Expert” 并将 “Pruning severity” 设置为 65 65 65,将 “Minimum records per child branch” 设置为 95 95 95。
图 5 5 5 为 Clementine 的使用截图。使用数据集 “Transaction.txt” 构建的决策树如图 6 6 6 所示。
图 5 Clementine 使用截图
图 6 决策树
虽然横向显示决策树会比较美观,但是缩放严重出现失真,故还是选择了纵向显示。
2. 使用上面创建好的模型对 “rollout.txt” 数据中的 20 20 20 位客户中的每一位进行预测,以确定客户是否会购买意大利面。
图 7 7 7 和图 8 8 8 分别展示了数据类型配置和对 “rollout.txt” 的预测结果。
图 7 rollout 数据类型配置
图 8 决策树预测结果
前五层的预测规则如下:
tomato souce = 1 [ Mode: 1 ]
tunny = 1 [ Mode: 1 ] => 1
tunny = 0 [ Mode: 1 ]
rice = 1 [ Mode: 1 ] => 1
rice = 0 [ Mode: 0 ]
brioches = 1 [ Mode: 1 ] => 1
brioches = 0 [ Mode: 0 ]
frozen vegetables = 1 [ Mode: 1 ] => 1
frozen vegetables = 0 [ Mode: 0 ]
coffee = 1 [ Mode: 1 ] => 1
coffee = 0 [ Mode: 0 ] => 0
tomato souce = 0 [ Mode: 0 ]
rice = 1 [ Mode: 0 ]
coffee = 1 [ Mode: 1 ] => 1
coffee = 0 [ Mode: 0 ]
biscuits = 1 [ Mode: 1 ] => 1
biscuits = 0 [ Mode: 0 ]
coke = 1 [ Mode: 1 ] => 1
coke = 0 [ Mode: 0 ] => 0
rice = 0 [ Mode: 0 ]
tunny = 1 [ Mode: 0 ] => 0
tunny = 0 [ Mode: 0 ]
oil = 1 [ Mode: 0 ] => 0
oil = 0 [ Mode: 0 ]
water = 1 [ Mode: 0 ] => 0
water = 0 [ Mode: 0 ]
milk = 1 [ Mode: 0 ] => 0
milk = 0 [ Mode: 0 ]
yoghurt = 1 [ Mode: 0 ] => 0
yoghurt = 0 [ Mode: 0 ]
coke = 1 [ Mode: 0 ] => 0
coke = 0 [ Mode: 0 ]
biscuits = 1 [ Mode: 0 ] => 0
biscuits = 0 [ Mode: 0 ]
brioches = 1 [ Mode: 0 ] => 0
brioches = 0 [ Mode: 1 ]
coffee = 1 [ Mode: 0 ] => 0
coffee = 0 [ Mode: 1 ]
frozen vegetables = 1 [ Mode: 0 ] => 0
frozen vegetables = 0 [ Mode: 1 ]
beer = 1 [ Mode: 0 ] => 0
beer = 0 [ Mode: 1 ]
juices = 1 [ Mode: 0 ] => 0
juices = 0 [ Mode: 1 ]
mozzarella = 1 [ Mode: 0 ] => 0
mozzarella = 0 [ Mode: 1 ]
crackers = 1 [ Mode: 0 ] => 0
crackers = 0 [ Mode: 1 ]
frozen fish = 1 [ Mode: 0 ] => 0
frozen fish = 0 [ Mode: 1 ] => 1
通过对某在线培训系统的标注数据集进行建模,预测其它会员期末考试的结果。数据集来自在线培训系统的日志,数据包括每个会员的在线学习行为。请尝试多种不同的模型、不同的参数,建立高质量的预测模型。
训练集有 873 873 873 条记录,测试集有 461 461 461 条记录。训练集和测试集包含如下变量:
人员 ID | 在线总时长(分钟) | 在线阅读时长(分钟) | 在线测试时长(分钟) | 全文阅读次数 | 智能阅读次数 | 知识点阅读次数 | 试题阅读次数 |
回溯原文次数 | 题库测试次数 | 仿真考试次数 | 仿真考试优秀次数 | 仿真考试良好次数 | 仿真考试合格次数 | 仿真考试不合格次数 | Class |
1. 对训练数据集进行决策树分类。将除 “人员 ID” 之外的字段设置为输入。将 “Class” 的 “direction” 设置为 “out”,“type” 设置为 ”Flag“。自定义 “pruning severity” 和 “minimum records per child branch”,然后勾选“use global pruning”。
尝试了多组参数如图 9 9 9 所示。其中,PS 为 pruning severity,MRPCB 为 minimum records per child branch。可见,“最佳”参数组合为 PS=5,MRPCB=5。
图 9 决策树混淆矩阵
2. 使用默认设置的神经网络处理训练数据集。设置同上。
默认设置的神经网络对应的混淆矩阵如图 10 10 10 所示。
图 10 神经网络混淆矩阵
3. 使用默认设置的逻辑回归模型处理训练数据集。设置同上。
默认设置的逻辑回归模型对应的混淆矩阵如图 11 11 11 所示。
图 11 逻辑回归模型混淆矩阵
4. 分析上面三个模型生成的混淆矩阵,评估模型质量。
对比 PS=5, MRPCB=5 的决策树、默认设置的神经网络和逻辑回归模型,决策树在准确率(accuracy)、召回率(recall)还是精度(precision)指标上的效果均优于其它两个模型,但这并不意味着决策树模型更适合这个数据集。
REF
Clementine教程 - 知乎
使用clementine得到混淆矩阵 - CSDN