博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用逻辑回归对用户分类 (理论+实战)
阅读量:5980 次
发布时间:2019-06-20

本文共 3486 字,大约阅读时间需要 11 分钟。

hot3.png

如果你在运营一个2C的平台,那么你肯定关心用户流失的问题。腾讯有个产品叫信鸽Pro,它能够通过对用户往期行为的挖掘,预测用户潜在的流失(付费)行为,进而实现精准营销。据说,腾讯自己的手游就是用这个系统做用户分析的。

信鸽Pro获取大量用户数据,提取用户特征,然后通过算法建模,评估出用户可能的行为。算法建模中最基础的一步就是对用户进行分类。这里就介绍一种常用的分类算法 - 逻辑回归。

模型

用户数据比较复杂,这里用平面上的点举例。假设平面上有一些点,如图所示:

整个平面上只有两种图形,一种是三角形,另一种是圆形。可以把它们想象为两种不同的用户,比如活跃用户/非活跃用户。

问题:如果随意在这个平面新增加一个点, 比如点P(5,19),那怎知把它归到哪一组更合适?可以想象为对新用户的预测。

思路

我们发现,三角形大都位于左上方,而圆形大都位于右下方。我们可以用尺子在图上画一条直线,该直线尽可能的将三角形和圆形分到两边。然后观察新点位于哪一侧。若与三角形在同一侧,则它应该属于三角形;若位于圆形一侧,则应属于圆形。在本例中,坐标P应该属于三角形更合适。

这个问题似乎很简单。但是,如果三维空间存在类似的问题,答案就没有那么显而易见了。那4维空间呢? 1024维空间呢?

不过别担心!借助计算机算法,N维空间分类的问题已经很容易解决,逻辑回归就是常用的一种。

逻辑回归

逻辑回归的核心思想就是通过现有数据,对分类边界线建立回归公式,以此进行分类。

在介绍算法之前,需要先介绍一个函数: Sigmoid函数。

Sigmoid函数

Sigmoid函数的表达式为:

在坐标系中的图形为:

x>0时,x越大y越接近于1;x<0时,x越小,y越接近于0。如果把坐标拉长,曲线中间就会很“陡”。直观上x的“轻微”变化,都会导致y接近于0或1。

Sigmoid函数的作用是将任意实数转换成0~1的数,而0和1刚好可以用做分类,比如,用1表示三角形,用0表示圆形。小于0.5的可以划分为0类,大于0.5的划分为1类。(注:Sigmoid是单调增长函数,因而多个数字通过Sigmoid转换后相对位置不变,这是选择该函数的重要原因。)

分析步骤

 

简化模型

为便于分析,把模型中的坐标简化一些。下面的六个坐标点和一条分割线:

其中红色三角形坐标分别是(1,2)、(1.5,7)和(2,6)。绿色圆点坐标分别是(1,0)、(2,3)和(2.5,6)。分割线的函数为y=4x-3. 它的形式还可以转换成:3-4x+y=0 。

我们设表达式f(x,y) = 3-4x+y

把六个点的坐标代到这个方程式里,有

<表1>

(注:标识1表示三角形;标识0表示圆形)

f(x,y)>0的点在分割线上方,是三角形;f(x,y)<0的点在分割线下方,是圆形.

如果有个三角形的坐标是(2,4.5),那这个点的f(x,y)值等于-0.5,这个点就被分割线错误划分了。

现在的问题是,我们只有一些坐标以及这些坐标的分类信息,如何找到一条最优的分割线,使得尽可能少的点被错误划分?

 

损失函数

损失函数 (Loss Function) 的作用是判断直线错误划分数据的程度。一种方法是计算被错误划分的点的个数,错误点越少,直线越好。但,这种方法很难优化。另一种方法是计算点到直线的距离。

如果是一个平面来划分三维空间的点,那距离公式为

一般的,n维空间上一个点到超平面的距离为

w是超平面的参数向量,

x是超平面的自变量,

b是截距

超平面函数:

表示x向量的第i个元素(特性);后面会用到,表示空间中的第i个点。

为了方便计算,一般在x中增加一个元素1,w中增加一个元素w0=b

于是超平面函数变为:

距离公式变为:

超平面上方的点f(x)>0, 下方的点f(x)<0,因此点到超平面的距离(分正负):

d是一个负无穷到正无穷的数。

通过sigmoid函数,将d变成一个0~1的值,设h = sigmoid(d)。若d为正且越大,h越接近于1,也就越应该属于三角形(分类1);若d为负,且绝对值越大,h越接近于0,该点也就越应该属于圆形(分类0)。因此,h越接近于分类标识,划分的准确性越高。

设第j个点的分类表示为,那么下面的公式就表示点j被错误划分的概率。

我们把损失函数设定为所有点被错误划分的平均概率

平方是为了保证概率为正,前面的1/2是为了求导数后消除参数。

那么,问题转化成:找到w的一个值,使得损失函数的值最小。

 

用梯度下降法求w

所谓梯度,就是函数在某个点增长最快的方向,有时称为斜度。如果函数是一个曲线,某个点的梯度就是该点的斜率,或导数。

如果是曲面,梯度是在两个方向上求偏导。

梯度下降法的核心思想是:欲求函数的最小值,先从某一点出发,沿着函数的梯度的反方向探寻,直到找到最小值。设每次探寻Delta(w),步长为alpha,则梯度下降的算法的公式为:

 

求导

用梯度下降法需要先对损失函数求导,我们的损失函数被分成三部分:

  •  ——— (1)

  •  ——— (2)

  •  ———- (3)

可以通过复合函数求导法对损失函数求偏导:

梯度公式重点关注的是导数的符号,所以这里可以简化一下。函数(2)是单调递增函数,所以导数是正数,不影响整体导数的符号,可以去除。 公式(3)的分母是正数,也不影响导数的符号,也可以去掉。最后得:

代入梯度下降算法公式得:

1/m为正数,也可用去掉。

 

代码

loadData()函数返回坐标值和分类标识。第一个返回值取前三列 x0,x1,x2;第二个返回值取第四列,即label

from numpy import *def loadData():  data = [[1, 1, 2, 1],          [1, 2, 6, 1],          [1, 1.5, 7, 1],          [1, 1, 0, 0],          [1, 2, 3, 0],          [1, 2.5, 6, 0]]  ds = [e[0:3] for e in data]  label = [e[-1] for e in data]  return ds, label

Sigmoid函数

def sigmoid(x):    return 1.0/(1+exp(-x))

梯度下降算法

input ds: 坐标数据; label: 标签
return w: 系数向量, nx1的矩阵

def reduce(ds, label):  #转换成矩阵  dmat = mat(ds)  lmat = mat(label).T  #mxn的矩阵的行数和列数  m,n = shape(dmat)  #步长  alpha = 0.1  #循环次数  loops = 200  #初始化w为[1,1,1],即分割线为 1+x+y=0  w = ones((n,1))  for i in range(loops):     h = sigmoid(dmat*w)    err = (h - lmat)    w = w - alpha * dmat.T* err   return w.A[:,0]

测试

def test():  ds,l = loadData()  print reduce(ds,l)

运行结果

>>> import lr>>> lr.test()[ 3.1007773  -5.54393712  1.60563033]

 

也就是说w=(3.1, -5.5, 1.6), 即w0=3.1, w1=-5.5, w2 = 1.6

分割线的表达式为:w0+w1x+w2y=0, 代入w后得 3.1-5.5x+1.6y=0, 即y=3.44x-1.9 。 见下图,该直线正确地将图形划分开。

执行过程

w的初始值为(1,1,1),也就是0号线。

每次循环都会调整分割线的位置,执行到第200次的时候,分割线已经能够很好对坐标分组了。
<分割线调整图> 线编号n表示第n次调整(循环)之后的位置

应用

把上面的x,y转换成用户特征,比如登录时间,登录频率等等。把三角形和圆形转换成付费用户和免费用户,就得到了付费用户预测模型;把三角形和圆形转换成流失用户和有效用户,就得到了流失用户预测模型。

当然,这只是个理论模型,实际应用要比这复杂的多的多。

 

相关文章

转载于:https://my.oschina.net/stanleysun/blog/614752

你可能感兴趣的文章
【刷算法】整数中1出现的次数(从1到n整数中1出现的次数)
查看>>
软件测试常见面试题及答案
查看>>
JavaScript深入系列15篇正式完结!
查看>>
HotSpot JVM 内存管理
查看>>
Kafka 学习笔记
查看>>
Swift 中的运行时小技巧
查看>>
第三十三章:修改SpringBoot启动Banner
查看>>
《Functional Programming in 40 minutes》笔记
查看>>
11个简单的Java性能调优技巧
查看>>
谈谈TCP协议的三次握手和四次挥手
查看>>
idea中live-template的使用
查看>>
理解区块链 这一篇就够
查看>>
Mac配置MySQL以及Squel Pro
查看>>
ES6入门---let和const
查看>>
遗传算法组卷使用心得
查看>>
linux入门学习
查看>>
那些年命途多舛的千千静听,归来能否再现当年荣光?
查看>>
Scrapy框架的使用之Scrapy对接Splash
查看>>
ECMAScript Decorators---装饰器
查看>>
小白入门学习Python,值得你重视的那些事儿
查看>>