乐趣区

关于算法:R语言非参数方法使用核方法和KNNk近邻算法分类预测心脏病数据

本文考虑一下基于核办法进行分类预测。留神,在这里,咱们不应用规范逻辑回归,它是参数模型。

非参数办法

用于函数预计的非参数办法大抵上有三种:核办法、部分多项式办法、样条办法。
非参的函数预计的长处在于持重,对模型没有什么特定的假如,只是认为函数润滑,防止了模型抉择带来的危险;然而,表达式简单,难以解释,计算量大是非参的一个很大的故障。所以说应用非参有危险,抉择需谨慎。
非参的想法很简略:函数在观测到的点取观测值的概率较大,用 x 左近的值通过加权均匀的方法预计函数 f(x)的值。

核办法

当加权的权重是某一函数的核, 这种办法就是核办法,常见的有 Nadaraya-Watson 核预计与 Gasser-Muller 核预计办法,也就是很多教材里谈到的 NW 核预计与 GM 核预计,这里咱们还是不谈核的抉择,将所有的核预计都默认用 Gauss 核解决。
NW 核预计模式为:

 

GM 核预计模式为:

式中

数据

应用心脏病数据,预测急诊病人的心肌梗死,蕴含变量:

心脏指数
心搏量指数
舒张压
肺动脉压
心室压力
肺阻力
是否存活
既然咱们晓得核预计是什么,咱们假如 k 是 N(0,1)散布的密度。在 x 点,应用带宽 h,咱们失去以下代码

dnorm((心搏量指数 -x)/bw, mean=0,sd=1)
weighted.mean(存活,w)}
plot(u,v,ylim=0:1, 
 

当然,咱们能够扭转带宽。

Vectorize(mean_x(x,2))(u)

咱们察看到:带宽越小,咱们失去的方差越大,偏差越小。“越大的方差”在这里意味着越大的可变性(因为邻域越小,计算平均值的点就越少,估计值也就越不稳固),以及“偏差越小”,即期望值应该在 x 点计算,所以邻域越小越好。

应用润滑函数

用 R 函数来计算这个核回归。

smooth(心搏量指数, 存活, ban  = 2*exp(1) 

咱们能够复制之前的预计。然而,输入不是一个函数,而是两个向量序列。此外,正如咱们所看到的,带宽与咱们以前应用的带宽并不完全相同。

smooth(心搏量指数, 存活,"normal",bandwidth = bk)
optim(bk,f)$par}
x=seq(1,10,by=.1)
plot(x,y)
abline(0,exp(-1),col="red")
 

斜率为 0.37,实际上是 e^{-1}。

高维利用

当初思考咱们的双变量数据集,并思考一些单变量(高斯)核的乘积

  w = dnorm((df$x1-x)/bw1, mean=0,sd=1)*
      dnorm((df$x2-y)/bw2, mean=0,sd=1)
  w.mean(df$y=="1",w)
contour(u,u,v,levels = .5,add=TRUE)


咱们失去以下预测

在这里,不同的色彩是概率。

K-NN(k 近邻算法)

另一种办法是思考一个邻域,它不是用到点的间隔来定义的,而是用咱们失去的 n 观测值来定义 k 邻域(也就是 k 近邻算法)。

接下来,咱们本人编写函数来实现 K -NN(k 近邻算法):

艰难的是咱们须要一个无效的间隔。

如果每个重量的单位都十分不同,那么应用欧几里德间隔将毫无意义。所以,咱们思考马氏间隔

mahalanobis = function(x,y,Sinv){as.numeric(x-y)%*%Sinv%*%t(x-y)}
mahalanobis(my[i,1:7],my[j,1:7])



这里咱们有一个函数来寻找 k 最近的街坊察看样本。而后能够做两件事来失去一个预测。咱们的指标是预测一个类,所以咱们能够思考应用一个少数规定:对 yi 的预测与大多数街坊样本的预测是一样的。

  for(i in 1:length(Y)) Y[i] = sort(存活[k_closest(i,k)])[(k+1)/2]


咱们也能够计算出最近街坊中黑点的比例。它实际上能够被解释为是彩色的概率,

for(i in 1:length(Y)) Y[i] = mean(存活[k_closest(i,k)])


咱们能够在数据集上看到察看后果,基于少数准则的预测,以及死亡样本在 7 个最近的街坊中的比例

k_ma(7),PROPORTION=k_mean(7))

这里,咱们失去了一个位于 x 的观测点的预测,但实际上,能够寻找任何 x 的最近邻 k。回到咱们的单变量例子(失去一个图表),咱们有

  w = rank(abs(心搏量指数 -x),method ="random")
  mean(存活[which(<=9)])}


不是很平滑,但咱们的点也不是很多。
如果咱们在二维数据集上应用这种办法,咱们就会失去以下的后果。

  k = 6
   dist = function(j)  mahalanobis(c(x,y))
  vect = Vectorize(dist)(1:nrow(df)) 
  idx  = which(rank(vect<=k)
 
contour(u,u,v,levels = .5,add=TRUE)
 


这就是部分推理的思维,用 kernel 对 x 的邻域进行推理,或者用 k -NN 近邻。

退出移动版