python logistic_Python Logistic回归分类

1.Logistic回归

人们将已知存在的数据点利用一条直线进行拟合(该直线被称为最佳拟合直线)的过程称为回归。

而今天介绍的Logistic回归分类的主要思想就是依据现有已分类的数据样本建立回归公式,以此进行分类。

“回归”源于最佳拟合,而Logistic回归中训练分类器的做法就是利用一些最优算法寻找符合最佳拟合的拟合参数。

1.1 Logistic分布

设X是连续的随机变量,且具有如下的分布函数和密度函数:

![](http://latex.codecogs.com/svg.latex? \Large $$ F(X) = P(X\leq{x}) = \frac{1}{1+\exp^{-\frac{(x-\mu)}{\gamma}}}$$)

![](http://latex.codecogs.com/svg.latex? \Large $$ f(X) = F'(X) = \frac{\exp{-\frac{x-\mu}{\gamma}}}{\gamma(1+\exp{-\frac{x-\mu}{\gamma}})^2}$$)

其中μ为位置参数,γ > 0为形状参数。

下图是F(X),f(X)的大致图像,人们又把F(X)函数成为sigmoid函数(以后会经常见到它)。

import matplotlib.pyplot as plt

import numpy as np

import scipy

x = np.linspace(-5, 5)

y1 = 1/(1 + np.exp(- x))

y2 = np.exp(- x)/(1 + np.exp(- x))**2

fig1 = plt.figure()

plt.xlabel('x')

plt.ylabel('F(x)')

plt.plot(x, y1, linewidth = 2.0)

fig2 = plt.figure()

plt.xlabel('x')

plt.ylabel('f(x)')

plt.plot(x, y2, linewidth = 2.0)

plt.show()

1.2 二项式Logistic回归

从以上的Logistic分布定义中引申出一种分类模型,就是下面要介绍的二项式Logistic回归模型。

在上述X中,将其分为0、1两类。即随机变量X的取值为实数,其分类变量定义为Y,每个x所属类别可以通过条件概率分布P(Y|X)进行表示。

条件概率分布如下:

![](http://latex.codecogs.com/svg.latex? \Large $$P(Y=1\mid x) = \frac{\exp(\omega \cdot x+b)}{1+\exp(\omega \cdot x+b)}$$)

![](http://latex.codecogs.com/svg.latex? \Large $$P(Y=0\mid x) = \frac{1}{1+\exp(\omega \cdot x+b)}$$)

x∈Rn是输入,Y∈ {0, 1}是输出,ω∈Rn为权值向量,b∈R为偏置,ω·x为ω和x的内积。

这里将ω和x进行扩充,即![](http://latex.codecogs.com/svg.latex? \Large $\omega = {\omega ^{(1)},\omega ^{(2)},...,\omega ^{(n)},b }$)和![](http://latex.codecogs.com/svg.latex? \Large $x = {x{(1)},x{(2)},...,x^{(n)},1}$)

此时的Logistic回归模型如下:

![](http://latex.codecogs.com/svg.latex? \Large $$P(Y=1\mid x) = \frac{\exp(\omega \cdot x)}{1+\exp(\omega \cdot x)}$$)

![](http://latex.codecogs.com/svg.latex? \Large $$P(Y=0\mid x) = \frac{1}{1+\exp(\omega \cdot x)}$$)

在考虑一个事件发生为p,则不发生的概率为1-p,那么这个事件发生的几率(odds)为p/(1-p)。对数几率(log odds)为

![](http://latex.codecogs.com/svg.latex? \Large $$logit(p) = \log{\frac{p}{1-p}}$$)

将上述Logistic回归模型代入其中可以得到:

![](http://latex.codecogs.com/svg.latex? \Large $$\log{\frac{P(Y = 1\mid x)}{1-P(Y = 1\mid x)}} = \omega \cdot x$$)

可以看出输出Y = 1的对数几率是输入x的线性函数,即Y可以用x的线性函数表示。自然地,在Logistic回归模型中,x的线性函数值ω·x越接近于+∞,其概率越接近于1,反之,ω·x越接近于-∞,其概率越接近于0。

1.3 参数估计

假设给定训练数据集![](http://latex.codecogs.com/svg.latex? \Large $T = {(x_1,y_1),(x_2,y_2),...,(x_N,y_N)}$)

其中,xi∈Rn,yi ∈ {0,1},利用极大似然估计法估计模型参数。

设![](http://latex.codecogs.com/svg.latex? \Large $P(Y=1\mid x) =\pi (x)$,则$P(Y=0\mid x) =1-\pi (x)$)

似然函数为:![](http://latex.codecogs.com/svg.latex? \Large $$\prod_{i=1}^{N} [\pi(x_i)]{y_i}[1-\pi(x_i)]{1-y_i}$$)

对数似然函数为:

此时对L(ω)求最大值,即得到ω的估计值。

为此,后续利用梯度下降法或者拟牛顿法进行该值的求解。

假设ω的极大似然估计值为ω',那么Logistic模型为:

![](http://latex.codecogs.com/svg.latex? \Large $$P(Y=1\mid x) = \frac{\exp(\omega' \cdot x)}{1+\exp(\omega' \cdot x)}$$)

![](http://latex.codecogs.com/svg.latex? \Large $$P(Y=0\mid x) = \frac{1}{1+\exp(\omega' \cdot x)}$$)

1.4 梯度法求解估计值

对上述L(ω)中的ω求导,得到:

令L(ω) = 0,可以求得其最大的L(ω)对应的ω',但由于无法直接求解,故采用梯度下降法进行求解。

由上求导过程可以知道,L(ω) 的梯度为

![](http://latex.codecogs.com/svg.latex? \Large $$\triangledown_{\omega}L(\omega) =\sum_{i=1}^{N}{y_i - \pi(x_i)}x_i$$)

故迭代公式(此处为梯度上升算法)为

![](http://latex.codecogs.com/svg.latex? \Large $$\omega = \omega + \alpha \sum_{i=1}^{N}{y_i - \pi(x_i)}x_i$$)

其中α为步长,当![](http://latex.codecogs.com/svg.latex? \Large $\mid\mid \triangledown_{\omega}L(\omega) \mid\mid < \varepsilon$) 即可求得最大的ω,ε为误差。

2、Logistic分类器实现

仍然使用这份数据进行算法实现

以下列数据集为例,进行Logistic分类器的设计。

编号

色泽

根蒂

敲声

纹理

脐部

触感

密度

含糖率

好瓜

1

青绿

蜷缩

浊响

清晰

凹陷

硬滑

0.697

0.460

2

乌黑

蜷缩

沉闷

清晰

凹陷

硬滑

0.774

0.376

3

乌黑

蜷缩

浊响

清晰

凹陷

硬滑

0.634

0.264

4

青绿

蜷缩

沉闷

清晰

凹陷

硬滑

0.608

0.318

5

浅白

蜷缩

浊响

清晰

凹陷

硬滑

0.556

0.215

6

青绿

稍蜷

浊响

清晰

稍凹

软粘

0.403

0.237

7

乌黑

稍蜷

浊响

稍糊

稍凹

软粘

0.481

0.149

8

乌黑

稍蜷

浊响

清晰

稍凹

硬滑

0.437

0.211

9

乌黑

稍蜷

沉闷

稍糊

稍凹

硬滑

0.666

0.091

10

青绿

硬挺

清脆

清晰

平坦

软粘

0.243

0.267

11

浅白

硬挺

清脆

模糊

平坦

硬滑

0.245

0.057

12

浅白

蜷缩

浊响

模糊

平坦

软粘

0.343

0.099

13

青绿

稍蜷

浊响

稍糊

凹陷

硬滑

0.639

0.161

14

浅白

稍蜷

沉闷

稍糊

凹陷

硬滑

0.657

0.198

15

乌黑

稍蜷

浊响

清晰

稍凹

软粘

0.360

0.37

16

浅白

蜷缩

浊响

模糊

平坦

硬滑

0.593

0.042

17

青绿

蜷缩

沉闷

稍糊

稍凹

硬滑

0.719

0.103

2.1 解析数据文件

上一篇的《朴素贝叶斯法》已经利用了Pandas对读入的数据文件进行解析并进行哑变量处理,下面即封装好的解析代码:

#导入numpy和pandas库

import numpy as np

import pandas as pd

#解析数据文件

def loadDataSet(filename):

dataSet = pd.read_csv(filename, sep = '\t', index_col = '编号')

#哑变量处理

featureDict = []

new_dataSet = pd.DataFrame()

for i in range(len(dataSet.columns)):

featureList = dataSet[dataSet.columns[i]]

classSet = list(set(featureList))

count = 0

for feature in classSet:

d = dict()

if isinstance(feature, float):#判断是否为连续变量

continue

else:

featureList[featureList == feature] = count

d[feature] = count

count += 1

featureDict.append(d)

new_dataSet = pd.concat([new_dataSet, featureList], axis = 1)

dataMat = [list(new_dataSet.loc[i][:-1]) for i in range(1,len(new_dataSet) + 1)]

labelMat = list(new_dataSet[new_dataSet.columns[-1]])

return dataMat, labelMat

filename = 'data.txt'

dataMat, labelMat = loadDataSet(filename)

import pprint

pprint.pprint(dataMat)

pprint.pprint(labelMat)

[[1, 1, 2, 2, 0, 0, 0.69700000000000006, 0.46000000000000002],

[0, 1, 1, 2, 0, 0, 0.77400000000000002, 0.376],

[0, 1, 2, 2, 0, 0, 0.63400000000000001, 0.26400000000000001],

[1, 1, 1, 2, 0, 0, 0.60799999999999998, 0.318],

[2, 1, 2, 2, 0, 0, 0.55600000000000005, 0.215],

[1, 2, 2, 2, 1, 1, 0.40299999999999997, 0.23699999999999999],

[0, 2, 2, 0, 1, 1, 0.48100000000000004, 0.14899999999999999],

[0, 2, 2, 2, 1, 0, 0.43700000000000006, 0.21100000000000002],

[0, 2, 1, 0, 1, 0, 0.66599999999999993, 0.090999999999999998],

[1, 0, 0, 2, 2, 1, 0.24299999999999999, 0.26700000000000002],

[2, 0, 0, 1, 2, 0, 0.245, 0.057000000000000002],

[2, 1, 2, 1, 2, 1, 0.34299999999999997, 0.099000000000000005],

[1, 2, 2, 0, 0, 0, 0.63900000000000001, 0.161],

[2, 2, 1, 0, 0, 0, 0.65700000000000003, 0.19800000000000001],

[0, 2, 2, 2, 1, 1, 0.35999999999999999, 0.37],

[2, 1, 2, 1, 2, 0, 0.59299999999999997, 0.042000000000000003],

[1, 1, 1, 0, 1, 0, 0.71900000000000008, 0.10300000000000001]]

[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

可以看到,该操作将字符串型的分类变量解析成为了数值型的分类变量,从而方便了将要进行的数值运算。

2.2 利用梯度上升法求最佳回归系数

在前面的定义中,Logistic分布函数$F(X)$又被称为sigmoid函数,其对数几率为

![](http://latex.codecogs.com/svg.latex? \Large $$\log{\frac{P(Y = 1\mid x)}{1-P(Y = 1\mid x)}} = \omega \cdot x$$)

即将sigmoid函数的输入可以看作是:

![](http://latex.codecogs.com/svg.latex? \Large $$z = \omega {(1)}x{(1)}+\omega {(2)}x{(2)}+,...,+\omega {(n)}x{(n)} = \omega^{T} \cdot x$$)

由此,定义下面的代码进行梯度上升法的实现:

#定义Sigmoid函数

def sigmoid(inX):

return 1.0/(1 + np.exp(- inX))

#随机的梯度上升法

def gradAscent(dataMatIn, classLabels, numIter = 150):

#获得行数和列数,即样本数和特征数

m, n = np.shape(dataMatIn)

#权重初始化

weights = np.ones(n)

for j in range(numIter):

dataIndex = range(m)

for i in range(m):

alpha = 4/(1.0 + j + i) + 0.01

randIndex = int(np.random.uniform(0, len(dataIndex)))

h = sigmoid(sum(dataMatIn[randIndex] * weights))

error = classLabels[randIndex] - h

weights = weights + np.dot(alpha * error, dataMatIn[randIndex])

return weights

weights = gradAscent(dataMat, labelMat)

print(weights)

[-1.91739131 -2.37320272 3.30085298 1.32020706 -2.30328752 0.58413608

0.84630395 -0.63702599]

2.3 分类器设计

由上,求出了相应的输入特征对应权重,利用对数几率公式,可以简单实现分类的效果,相关设计代码如下:

def classfy(testdir, weights):

dataMat, labelMat = loadDataSet(testdir)

dataMat = np.mat(dataMat)

weights = np.mat(weights)

h = sigmoid(dataMat * weights.transpose())

h = h.tolist()

m = len(h)

error = 0.0

for i in range(m):

if h[i][0] > 0.5:

print(int(labelMat[i]),'is classfied as: 1')

if int(labelMat[i])!=1:

error += 1

print('error')

else:

print(int(labelMat[i]),'is classfied as: 0')

if int(labelMat[i])!=0:

error += 1

print('error')

print('error rate is:','%.4f' %(error/m))

classfy(filename, weights)

1 is classfied as: 1

1 is classfied as: 1

1 is classfied as: 1

1 is classfied as: 1

1 is classfied as: 1

1 is classfied as: 1

1 is classfied as: 1

1 is classfied as: 1

0 is classfied as: 0

0 is classfied as: 0

0 is classfied as: 0

0 is classfied as: 0

0 is classfied as: 1

error

0 is classfied as: 0

0 is classfied as: 1

error

0 is classfied as: 0

0 is classfied as: 0

error rate is: 0.1176

将训练的数据样本进行测试,可以看出上述分类中,只有两个样本被分类错误了,准确度达到了88.24%,分类效果不错。

2.4 Scikit - Learn库简单实现Logistic分类

下面的代码是简单通过Scikit - Learn库实现Logistic的分类:

from sklearn.linear_model import LogisticRegression

X, Y = loadDataSet(filename)

clf = LogisticRegression()

clf.fit(X, Y)

y_pred = clf.predict(X)

accuracy = np.mean(Y == y_pred)

print('准确度为:', accuracy)

准确度为: 0.882352941176

可以看出,上述实现的准确度与设计的分类器的准确度基本一样,效果不错。

3、总结

Logist回归分类的优缺点:

优点:计算代价低,易于理解和实现;

缺点:易欠拟合,分类精度普遍不高。

本文实现过程中使用的数据样本量较少,结果也较为单一,后续可以通过训练和测试较多样本量的数据,来感受其作用。

4、 参考文献

[1] 李航. 统计学习方法.清华大学出版社,2012

[2] Peter Harrington. 机器学习实战. 人民邮电出版社,2013

[3] http://blog.csdn.net/lsldd/article/details/41551797

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值