KNN算法在保险业精准营销中的应用

一、KNN算法概述

KNN是Machine Learning领域一个简单又实用的算法,与之前讨论过的算法主要存在两点不同:

  1. 它是一种非参方法。即不必像线性回归、逻辑回归等算法一样有固定格式的模型,也不需要去拟合参数。
  2. 它既可用于分类,又可应用于回归。

KNN的基本思想有点类似“物以类聚,人以群分”,打个通俗的比方就是“如果你要了解一个人,可以从他最亲近的几个朋友去推测他是什么样的人”。

在分类领域,对于一个未知点,选取K个距离(可以是欧氏距离,也可以是其他相似度度量指标)最近的点,然后统计这K个点,在这K个点中频数最多的那一类就作为分类结果。比如下图,若令K=4,则?处应分成红色三角形;若令K=6,则?处应分类蓝色正方形。

在回归(简单起见,这里讨论一元回归)领域,如果只知道某点的预测变量$x$,要回归响应变量$y$,只需要在横坐标轴上(因为不知道纵坐标的值,所以没法计算欧氏距离)选取K个最近的点,然后平均(也可以加权平均)这些点的响应值,作为该点的响应值即可。比如下图中,已知前5个点的横纵坐标值,求$x=6.5$时,$y$为多少?若令K=2,则距6.5最近的2个点是(5.1, 8)和(4, 27),把这两个点的纵坐标平均值17.5就可以当作回归结果,认为$x=6.5时,y=17.5。$

KNN具体的算法步骤可参考延伸阅读文献1。

二、KNN性能讨论

KNN的基本思想与计算过程很简单,你只需要考虑两件事:

  1. K预设值取多少?
  2. 如何定义距离?

其中如何定义距离这个需要结合具体的业务应用背景,本文不细致讨论,距离计算方法可参看延伸阅读文献2。这里只讨论K取值时对算法性能的影响。

在上图中,紫色虚线是贝叶斯决策边界线,也是最理想的分类边界,黑色实线是KNN的分类边界。

可以发现:K越小,分类边界曲线越光滑,偏差越小,方差越大;K越大,分类边界曲线越平坦,偏差越大,方差越小。

所以即使简单如KNN,同样要考虑偏差和方差的权衡问题,表现为K的选取。

KNN的优点就是简单直观,无需拟合参数,在样本本身区分度较高的时候效果会很不错;但缺点是当样本量大的时候,找出K个最邻近点的计算代价会很大,会导致算法很慢,此外KNN的可解释性较差。

KNN的一些其他问题的思考可参看延伸阅读文献3。

三、实战案例

1、KNN在保险业中挖掘潜在用户的应用

这里应用ISLR包里的Caravan数据集,先大致浏览一下:

> library(ISLR)
> str(Caravan)
'data.frame':    5822 obs. of  86 variables:
 $ Purchase: Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
> table(Caravan$Purchase)/sum(as.numeric(table(Caravan$Purchase)))
        No        Yes 
0.94022673 0.05977327

5822行观测,86个变量,其中只有Purchase是分类型变量,其他全是数值型变量。Purchase两个水平,NoYes分别表示不买或买保险。可见到有约6%的人买了保险。

由于KNN算法要计算距离,这85个数值型变量量纲不同,相同两个点在不同特征变量上的距离差值可能非常大。因此要归一化,这是Machine Learning的常识。这里直接用scale()函数将各连续型变量进行正态标准化,即转化为服从均值为0,标准差为1的正态分布。

> standardized.X=scale(Caravan[,-86])
> mean(standardized.X[,sample(1:85,1)])
[1] -2.047306e-18
> var(standardized.X[,sample(1:85,1)])
[1] 1
> mean(standardized.X[,sample(1:85,1)])
[1] 1.182732e-17
> var(standardized.X[,sample(1:85,1)])
[1] 1
> mean(standardized.X[,sample(1:85,1)])
[1] -3.331466e-17
> var(standardized.X[,sample(1:85,1)])
[1] 1

可见随机抽取一个标准化后的变量,基本都是均值约为0,标准差为1。

> #前1000观测作为测试集,其他当训练集
> test <- 1:1000
> train.X <- standardized.X[-test,]
> test.X <- standardized.X[test,]
> train.Y <- Caravan$Purchase[-test]
> test.Y <- Caravan$Purchase[test]
> knn.pred <- knn(train.X,test.X,train.Y,k=)
> mean(test.Y!=knn.pred)
[1] 0.117
> mean(test.Y!="No")
[1] 0.059

当K=1时,KNN总体的分类结果在测试集上的错误率约为12%。由于大部分的人都不买保险(先验概率只有6%),那么如果模型预测不买保险的准确率应当很高,纠结于预测不买保险实际上却买保险的样本没有意义,同样的也不必考虑整体的准确率(Accuracy)。作为保险销售人员,只需要关心在模型预测下会买保险的人中有多少真正会买保险,这是精准营销的精确度(Precision);因此,在这样的业务背景中,应该着重分析模型的Precesion,而不是Accuracy。

> table(knn.pred,test.Y)
        test.Y
knn.pred  No Yes
     No  874  50
     Yes  67   9
> 9/(67+9)
[1] 0.1184211

可见K=1时,KNN模型的Precision约为12%,是随机猜测概率(6%)的两倍!

下面尝试K取不同的值:

> knn.pred <- knn(train.X,test.X,train.Y,k=3)
> table(knn.pred,test.Y)[2,2]/rowSums(table(knn.pred,test.Y))[2]
Yes 
0.2 
> knn.pred <- knn(train.X,test.X,train.Y,k=5)
> table(knn.pred,test.Y)[2,2]/rowSums(table(knn.pred,test.Y))[2]
      Yes 
0.2666667

可以发现当K=3时,Precision=20%;当K=5时,Precision=26.7%。

作为对比,这个案例再用逻辑回归做一次!

> glm.fit <- glm(Purchase~.,data=Caravan,family = binomial,subset = -test)
Warning message:
glm.fit:拟合機率算出来是数值零或一 
> glm.probs <- predict(glm.fit,Caravan[test,],type = "response")
> glm.pred <- ifelse(glm.probs >0.5,"Yes","No")
> table(glm.pred,test.Y)
        test.Y
glm.pred  No Yes
     No  934  59
     Yes   7   0

这个分类效果就差很多,Precision竟然是0!事实上,分类概率阈值为0.5是针对等可能事件,但买不买保险显然不是等可能事件,把阈值降低到0.25再看看:

> glm.pred <- ifelse(glm.probs >0.25,"Yes","No")
> table(glm.pred,test.Y)
        test.Y
glm.pred  No Yes
     No  919  48
     Yes  22  11

这下子Precision就达到1/3了,比随机猜测的精确度高出5倍不止!

以上试验都充分表明,通过机器学习算法进行精准营销的精确度比随机猜测的效果要强好几倍!

2、KNN回归

在R中,KNN分类函数是knn(),KNN回归函数是knnreg()

> #加载数据集BloodBrain,用到向量logBBB和数据框bbbDescr
> library(caret)
> data(BloodBrain)
> class(logBBB)
[1] "numeric"
> dim(bbbDescr)
[1] 208 134
> #取约80%的观测作训练集。
> inTrain <- createDataPartition(logBBB, p = .8)[[1]]
> trainX <- bbbDescr[inTrain,] 
> trainY <- logBBB[inTrain]
> testX <- bbbDescr[-inTrain,]
> testY <- logBBB[-inTrain]
> #构建KNN回归模型
> fit <- knnreg(trainX, trainY, k = 3) 
> fit
3-nearest neighbor regression model
> #KNN回归模型预测测试集
> pred <- predict(fit, testX)
> #计算回归模型的MSE
> mean((pred-testY)^2)
[1] 0.5821147

这个KNN回归模型的MSE只有0.58,可见回归效果很不错,偏差很小!下面用可视化图形比较一下结果。

> #将训练集、测试集和预测值结果集中比较
> df <-data.frame(class=c(rep("trainY",length(trainY)),rep("testY",length(testY)),rep("predY",length(pred))),Yval=c(trainY,testY,pred))
> ggplot(data=df,mapping = aes(x=Yval,fill=class))+
+   geom_dotplot(alpha=0.8)

这是dotplot,横坐标才是响应变量的值,纵坐标表频率。比较相邻的红色点和绿色点在横轴上的差异,即表明测试集中预测值与实际值的差距。

> #比较测试集的预测值和实际值
> df2 <- data.frame(testY,pred)
> ggplot(data=df2,mapping = aes(x=testY,y=pred))+
+   geom_point(color="steelblue",size=3)+
+   geom_abline(slope = 1,size=1.5,linetype=2)

这张散点图则直接将测试集中的实际值和预测值进行对比,虚线是$y=x$。点离这条虚线越近,表明预测值和实际值之间的差异就越小。

本文已获作者授权。

原文发布于微信公众号 - PPV课数据科学社区(ppvke123)

原文发表时间:2017-09-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏量化投资与机器学习

量化投资之机器学习应用——基于 SVM 模型的商品期货择时交易策略(提出质疑和讨论)

2016年在东证期货的量化报告里,读到一篇文章,关于量化投资策略之机器学习应用——基于 SVM 模型的期货择时交易策略 。就顺手算了一下,发现了一些问题,因此和...

56990
来自专栏人工智能头条

机器学习的“小无相功”:高斯过程回归的深度科普

18830
来自专栏人工智能LeadAI

最终章 | TensorFlow战Kaggle“手写识别达成99%准确率

这是一个TensorFlow的系列文章,本文是第三篇,在这个系列中,你讲了解到机器学习的一些基本概念、TensorFlow的使用,并能实际完成手写数字识别、图像...

42290
来自专栏机器学习之旅

总结:常见算法工程师面试题目整理(一)

最近抽风,出去面试了不少公司,和不少算法工程师招聘的朋友有所交流,整理了相关比较有意思的题目,供大家参考:

15140
来自专栏小小挖掘机

推荐系统遇上深度学习(二十三)--大一统信息检索模型IRGAN在推荐领域的应用

信息检索领域的一个重要任务就是针对用户的一个请求query,返回一组排好序的召回列表。

20630
来自专栏IT派

随机森林之美

导语:随机森林和决策树相比,能更好的防止过拟合。虽然每个基分类器很弱,但最后组合的结果通常很强,这也类似于:“三个臭皮匠顶个诸葛亮”的思想。对比发现Random...

45540
来自专栏人工智能LeadAI

最全算法工程师面试题目整理(一)

1 基于每日用户搜索内容,假设只有少量已知商品的情况下,如何根据用户搜索内容获取平台内没有的新商品? ? ? 答案:这是一条类似于分词“新词获取问题”,答案是...

44560
来自专栏ATYUN订阅号

自动驾驶中机器学习算法应用大盘点

今天,机器学习算法被广泛应用于解决自动驾驶汽车制造的各种挑战问题中。人类将传感器数据处理集成到汽车的ECU(电子控制单元)中。 提高机器学习的利用率去完成新...

36040
来自专栏人工智能LeadAI

LSTM模型在问答系统中的应用

在问答系统的应用中,用户输入一个问题,系统需要根据问题去寻找最合适的答案。 1、采用句子相似度的方式。根据问题的字面相似度选择相似度最高的问题对应的答案,但是采...

48470
来自专栏AI科技评论

王宇龙:如何通过关键数据通路去理解网络行为?

AI科技评论按:神经网络长久以来的“黑盒”属性,导致人们一直无法理解网络的内部是如何运作的,针对这个困扰已久的问题,学界主要存在三种研究方向:数据归因模式、特征...

6330

扫码关注云+社区

领取腾讯云代金券