python 逻辑回归权重_python代码实现逻辑回归logistic原理

Logistic Regression Classifier逻辑回归主要思想就是用最大似然概率方法构建出方程,为最大化方程,利用牛顿梯度上升求解方程参数。

优点:计算代价不高,易于理解和实现。

缺点:容易欠拟合,分类精度可能不高。

使用数据类型:数值型和标称型数据。

介绍逻辑回归之前,我们先看一问题,有个黑箱,里面有白球和黑球,如何判断它们的比例。

我们从里面抓3个球,2个黑球,1个白球。这时候,有人就直接得出了黑球67%,白球占比33%。这个时候,其实这个人使用了最大似然概率的思想,通俗来讲,当黑球是67%的占比的时候,我们抓3个球,出现2黑1白的概率最大。我们直接用公式来说明。

假设黑球占比为P,白球为1-P。于是我们要求解MAX(PP(1-P)),显而易见P=67%(求解方法:对方程求导,使导数为0的P值即为最优解)

我们看逻辑回归,解决的是二分类问题,是不是和上面黑球白球问题很像,是的,逻辑回归也是最大似然概率来求解。

假设我们有n个独立的训练样本{(x1, y1) ,(x2, y2),…, (xn, yn)},y={0, 1}。那每一个观察到的样本(xi, yi)出现的概率是:

上面为什么是这样呢?当y=1的时候,后面那一项是不是没有了,那就只剩下x属于1类的概率,当y=0的时候,第一项是不是没有了,那就只剩下后面那个x属于0的概率(1减去x属于1的概率)。所以不管y是0还是1,上面得到的数,都是(x, y)出现的概率。那我们的整个样本集,也就是n个独立的样本出现的似然函数为(因为每个样本都是独立的,所以n个样本出现的概率就是他们各自出现的概率相乘):

这里我们稍微变换下L(θ):取自然对数,然后化简(不要看到一堆公式就害怕哦,很简单的哦,只需要耐心一点点,自己动手推推就知道了。注:有xi的时候,表示它是第i个样本,下面没有做区分了,相信你的眼睛是雪亮的),得到:

其中第三步到第四步使用了下面替换。

这时候为求最大值,对L(θ)对θ求导,得到:

然后我们令该导数为0,即可求出最优解。但是这个方程是无法解析求解(这里就不证明了)。

最后问题变成了,求解参数使方程L最大化,求解参数的方法梯度上升法(原理这里不解释了,看详细的代码的计算方式应该更容易理解些)。

根据这个转换公式

我们代入参数和特征,求P,也就是发生1的概率。

上面这个也就是常提及的sigmoid函数,俗称激活函数,最后用于分类(若P(y=1|x;Θ\ThetaΘ )大于0.5,则判定为1)。

下面是详细的逻辑回归代码,代码比较简单,主要是要理解上面的算法思想。个人建议,可以结合代码看一步一步怎么算的,然后对比上面推导公式,可以让人更加容易理解,并加深印象。

from numpy import *

filename='...\\testSet.txt' #文件目录

def loadDataSet(): #读取数据(这里只有两个特征)

dataMat = []

labelMat = []

fr = open(filename)

for line in fr.readlines():

lineArr = line.strip().split()

dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #前面的1,表示方程的常量。比如两个特征X1,X2,共需要三个参数,W1+W2*X1+W3*X2

labelMat.append(int(lineArr[2]))

return dataMat,labelMat

def sigmoid(inX): #sigmoid函数

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

def gradAscent(dataMat, labelMat): #梯度上升求最优参数

dataMatrix=mat(dataMat) #将读取的数据转换为矩阵

classLabels=mat(labelMat).transpose() #将读取的数据转换为矩阵

m,n = shape(dataMatrix)

alpha = 0.001 #设置梯度的阀值,该值越大梯度上升幅度越大

maxCycles = 500 #设置迭代的次数,一般看实际数据进行设定,有些可能200次就够了

weights = ones((n,1)) #设置初始的参数,并都赋默认值为1。注意这里权重以矩阵形式表示三个参数。

for k in range(maxCycles):

h = sigmoid(dataMatrix*weights)

error = (classLabels - h) #求导后差值

weights = weights + alpha * dataMatrix.transpose()* error #迭代更新权重

return weights

def stocGradAscent0(dataMat, labelMat): #随机梯度上升,当数据量比较大时,每次迭代都选择全量数据进行计算,计算量会非常大。所以采用每次迭代中一次只选择其中的一行数据进行更新权重。

dataMatrix=mat(dataMat)

classLabels=labelMat

m,n=shape(dataMatrix)

alpha=0.01

maxCycles = 500

weights=ones((n,1))

for k in range(maxCycles):

for i in range(m): #遍历计算每一行

h = sigmoid(sum(dataMatrix[i] * weights))

error = classLabels[i] - h

weights = weights + alpha * error * dataMatrix[i].transpose()

return weights

def stocGradAscent1(dataMat, labelMat): #改进版随机梯度上升,在每次迭代中随机选择样本来更新权重,并且随迭代次数增加,权重变化越小。

dataMatrix=mat(dataMat)

classLabels=labelMat

m,n=shape(dataMatrix)

weights=ones((n,1))

maxCycles=500

for j in range(maxCycles): #迭代

dataIndex=[i for i in range(m)]

for i in range(m): #随机遍历每一行

alpha=4/(1+j+i)+0.0001 #随迭代次数增加,权重变化越小。

randIndex=int(random.uniform(0,len(dataIndex))) #随机抽样

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

error=classLabels[randIndex]-h

weights=weights+alpha*error*dataMatrix[randIndex].transpose()

del(dataIndex[randIndex]) #去除已经抽取的样本

return weights

def plotBestFit(weights): #画出最终分类的图

import matplotlib.pyplot as plt

dataMat,labelMat=loadDataSet()

dataArr = array(dataMat)

n = shape(dataArr)[0]

xcord1 = []; ycord1 = []

xcord2 = []; ycord2 = []

for i in range(n):

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

xcord1.append(dataArr[i,1])

ycord1.append(dataArr[i,2])

else:

xcord2.append(dataArr[i,1])

ycord2.append(dataArr[i,2])

fig = plt.figure()

ax = fig.add_subplot(111)

ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')

ax.scatter(xcord2, ycord2, s=30, c='green')

x = arange(-3.0, 3.0, 0.1)

y = (-weights[0]-weights[1]*x)/weights[2]

ax.plot(x, y)

plt.xlabel('X1')

plt.ylabel('X2')

plt.show()

def main():

dataMat, labelMat = loadDataSet()

weights=gradAscent(dataMat, labelMat).getA()

plotBestFit(weights)

if __name__=='__main__':

main()

跑完代码结果:

当然,还可以换随机梯度上升和改进的随机梯度上升算法试试,效果都还不错。

下面是代码使用的数据,可以直接复制本地text里面,跑上面代码。

-0.01761214.0530640

-1.3956344.6625411

-0.7521576.5386200

-1.3223717.1528530

0.42336311.0546770

0.4067047.0673351

0.66739412.7414520

-2.4601506.8668051

0.5694119.5487550

-0.02663210.4277430

0.8504336.9203341

1.34718313.1755000

1.1768133.1670201

-1.7818719.0979530

-0.5666065.7490031

0.9316351.5895051

-0.0242056.1518231

-0.0364532.6909881

-0.1969490.4441651

1.0144595.7543991

1.9852983.2306191

-1.693453-0.5575401

-0.57652511.7789220

-0.346811-1.6787301

-2.1244842.6724711

1.2179169.5970150

-0.7339289.0986870

-3.642001-1.6180871

0.3159853.5239531

1.4166149.6192320

-0.3863233.9892861

0.5569218.2949841

1.22486311.5873600

-1.347803-2.4060511

1.1966044.9518511

0.2752219.5436470

0.4705759.3324880

-1.8895679.5426620

-1.52789312.1505790

-1.18524711.3093180

-0.4456783.2973031

1.0422226.1051551

-0.61878710.3209860

1.1520830.5484671

0.8285342.6760451

-1.23772810.5490330

-0.683565-2.1661251

0.2294565.9219381

-0.95988511.5553360

0.49291110.9933240

0.1849928.7214880

-0.35571510.3259760

-0.3978228.0583970

0.82483913.7303430

1.5072785.0278661

0.0996716.8358391

-0.34400810.7174850

1.7859287.7186451

-0.91880111.5602170

-0.3640094.7473001

-0.8417224.1190831

0.4904261.9605391

-0.0071949.0757920

0.35610712.4478630

0.34257812.2811620

-0.810823-1.4660181

2.5307776.4768011

1.29668311.6075590

0.47548712.0400350

-0.78327711.0097250

0.07479811.0236500

-1.3374720.4683391

-0.10278113.7636510

-0.1473242.8748461

0.5183899.8870350

1.0153997.5718820

-1.658086-0.0272551

1.3199442.1712281

2.0562165.0199811

-0.8516334.3756911

-1.5100476.0619920

-1.076637-3.1818881

1.82109610.2839900

3.0101508.4017661

-1.0994581.6882741

-0.834872-1.7338691

-0.8466373.8490751

1.40010212.6287810

1.7528425.4681661

0.0785570.0597361

0.089392-0.7153001

1.82566212.6938080

0.1974459.7446380

0.1261170.9223111

-0.6797971.2205301

0.6779832.5566661

0.76134910.6938620

-2.1687910.1436321

1.3886109.3419970

0.31702914.7390250

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值