现在,我们来学习如何让计算机学习模型的参数。
我们的例子用的是鸢尾花数据集,其中的每一个数据点都表示一种鸢尾花的特点。不同的属性用来表示花萼的长度和宽度,以及花瓣的长度和宽度。
一、下载数据集
让我们下载数据集:
x=read.csv("http://archive.ics.uci.edu/ml/machine-learning-databases/
iris/iris.data",col.names=c("sepal_length","sepal_width","petal_
length","petal_width","class"))
head(x)
二、参数估计
1. 计算经验平均值和经验方差
我们可以使用数据集做一些简单的估计。例如我们只考虑第一个变量sepal_length,并假设这个变量服从高斯分布,那么高斯分布中两个参数(平均值和方差)的最大似然估计可以简单地通过计算经验平均值和经验方差得到。
在 R 中,几行代码如下:
mean(x$sepal_length)
var(x$sepal_length)
2. 处理离散变量
如果我们想处理离散变量,正如本章中的大多数情形,我们可以使用著名的程序包 plyr 来简化计算。我们计算变量 class 上的分布。在 data.frame 中,可以执行:
library(plyr)
y =daply(x,.(class),nrow) /nrow(x)
y
有意思的是,可以看到每种类型的分布大概是 33%。我们只是把 data.frame 中 class 列的每个值的出现计了数,并除以值的总数。这样的操作给出了分布值,也可以用来作为每一类的先验概率。在这个例子中,我们的分布基本上是均匀分布。
3. 连续的条件概率分布
假设 sepal_length 服从平均值为 μ,方差为 σ2 的高斯分布。一个简单的联合分布由以下分解给出:
P(SepalLength,Class)=P(SepalLength|Class) · P(Class)
daply(x,.(class), function(n) mean(n$sepal_length))
daply(x,.(class), function(n) var(n$sepal_length))
4. 离散的条件概率分布
首先,对变量 sepal_width 离散化转换成离散值。它表示宽度,因此(简化起见)我们可以设定 3 个不同的值:{small,medium, large}。我们可以使用下列代码自动完成:
q <-quantile(x$sepal_width, seq(0, 1, 0.33))
q
我们找出了变量 sepal_width 的 33% 和 66% 分位数。33% 以下的值对应small,33% 和 66% 之间的值对应 medium,大于 66% 的值对应 large。
然后我们在 data.frame 中创建一个新的变量, sepal_width 的离散版本。执行下列代码:
x$dsw[ x$sepal_width <q['33%']] = "small"
x$dsw[ x$sepal_width >=q['33%'] &x$sepal_width <q['66%'] ] = "medium"
x$dsw[ x$sepal_width >=q['66%'] ] = "large"
x$dsw
对于分位数定义的每一个区间,我们都关联上 small、medium 或 large值,放在 x 中新的列 dsw(即 discrete sepal width)中。
最终,我们可以通过下列代码学到条件概率分布 P(dsw|class) :
p1 <-daply(x,.(dsw,class), function(n) nrow(n))
p1
这样在指定 class 值后,可以得到 dsw 中每一个值每次出现的计数。如果我们想把它们变成概率,只需要除以每个列的和。事实上,每个列都代表一个概率分布。可以执行下列代码:
p1 <-p1/colSums(p1)
p1
使用之前 class 上的分布,我们可以完全参数化模型,得到联合分布:
P(SepalWidth,Class)=P(SepalWidth|Class) · P(Class)。
如果我们分析完成的过程,并试着抽取一条经验规则,可以说参数通过对class 每一个值下的 sepal_width 值出现次数计数来找出参数。我们还可以说我们分别发现了分布的每个因子的参数:一个是 P(SepalWidth|Class),一个是P(Class)。
- 概率图模型基于R