logistic回归——PYTHON实现
logistic回归——PYTHON实现概述:logistic回归又称logistic回归分析,是一种线性回归模型。logistic回归应用最广泛的是处理二分类问题。比如,探讨引发疾病的危险因素,判断该病人是否患有该病;探讨房价的涨跌,进而给出在何时购买房子的最优决策。在logistic回归中,自变量可以是连续的,也可以是分立的。以预测房价涨跌为例,选择两种不同类型的房子,一种是涨价组,另一组
logistic回归——PYTHON实现
概述:
logistic回归又称logistic回归分析,是一种线性回归模型。logistic回归应用最广泛的是处理二分类问题。比如,探讨引发疾病的危险因素,判断该病人是否患有该病;探讨房价的涨跌,进而给出在何时购买房子的最优决策。在logistic回归中,自变量可以是连续的,也可以是分立的。
以预测房价涨跌为例,选择两种不同类型的房子,一种是涨价组,另一组是非涨价组,两组房子必定具有不同的占地面积、房屋位置、建筑年限等特征,因此因变量为是否涨价,自变量可以包括很多不同的特征,比如所在城市、占地面积等不同特征。
通过logistic回归,可以得到自变量的权重,从而大致了解影响疾病发作、股票走势、房价涨跌的因素,同时根据这些权重值,预测发生某件事情的可能性。
本文首先会介绍logistic回归所用到的基本的数学知识,接着会给出logistic回归在PYTHON中的编程实现。最后,会在大众比较熟悉且感兴趣的领域——股票预测方面应用logistic回归,观察其在量化投资方面的应用。
logistic回归与线性回归:
logistic回归与线性回归均属于广义的线性模型,只不过logistic回归将输出又输入到sigmoid函数中,通过引入非线性因素,给出二分类问题中不同类别的概率值。
logistic回归所用到的基本数学原理:
首先,与一般的机器学习算法一样,在输入参数时,首先应该选择输入的特征。比如,在预测房屋价格涨跌时,房屋面积可能是一个比较优秀的特征选择,而房屋所处小区的保安年龄可能就不是一个好的特征选择。因为特征提取、特征选择等特征工程是机器学习中的另一研究问题,本文在此不做赘述,仅选择能够获取到的数据当作其特征。
选取好特征后,我们就可以构建一个线性函数:
y
=
w
0
+
w
1
x
1
+
w
2
x
2
+
.
.
.
+
w
k
x
k
y = w_0+w_1x_1+w_2x_2+...+w_kx_k
y=w0+w1x1+w2x2+...+wkxk
其中,
w
w
w 为我们要寻找的各个参数值,
x
x
x 为我们选取的各个特征值。
此时,假设我们已经寻找到所有 w w w 值,则可以将特征空间 x 1 , x 2 , . . . , x k x_1,x_2,...,x_k x1,x2,...,xk 上样本的特征值通过 w 1 , w 2 , . . . , w k w_1,w_2,...,w_k w1,w2,...,wk 映射到值域空间 y y y 上,但此时 y y y 可能为某巨大的数,也可能为某负数,因此,我们引入一个非线性函数,将 y y y 值映射成 ( 0 , 1 ) (0,1) (0,1) 范围内的一个值。sigmoid函数如下图所示。
`于是,我们就建立了概率值
P
P
P 与
y
y
y的关系:
l
n
(
P
1
−
P
)
=
y
P
=
e
y
1
+
e
y
ln(\frac{P}{1-P})=y \\ P=\frac{e^y}{1+e^y}
ln(1−PP)=yP=1+eyey
最终,我们就可以通过这样一个计算图计算出某个类别的概率值:
但是,目前我们只是应用了 W W W 的值,我们并没有通过大量样本计算其值。因此,我们引入一个新的概念——梯度下降,来计算,准确来说是纠正这个向量的值。
梯度下降法,顾名思义,计算过程就是沿梯度下降的方向求解极小值。
现在我们又有一个问题,何为极小值?准确来说,这个值到底是怎么算出来的?在机器学习中,对于每个算法,我们都会引入一个函数,称其为代价函数。该代价函数衡量了我们训练的模型的好坏,衡量了这个算法的性能。代价函数最小为0,最大为正无穷,当代价函数为0时,该算法在训练集上的准确度为100%,但我们在训练时不应让代价函数为0,因为当代价函数为0时,模型会将训练集中的噪声也学习进去,因而在测试集上可能表现并不好。
介绍完代价函数的作用,代价函数到底该怎么选取?对于一般的拟合模型,在不考虑噪声的情况下,最优的结果即为通过那些点的一条曲线。当通过这些点时,拟合值与真实值相等,形象的说就是目标与当前所处位置重合。因此,在定义代价函数时,我们遵循的是:目前状态与当前状态之间的距离差。(该处类似于评估模型TOPSIS法中某方案与最优方案的相对接近程度,也就是TOPSIS中的评估值)
对于这个问题,我们先定义一个样本的损失函数如下:
L
(
y
^
,
y
)
=
−
y
l
o
g
(
y
^
)
−
(
1
−
y
)
l
o
g
(
1
−
y
^
)
L(\hat{y},y)=-ylog(\hat{y})-(1-y)log(1-\hat{y})
L(y^,y)=−ylog(y^)−(1−y)log(1−y^)
然后定义算法的代价函数如下:
J
(
w
)
=
1
k
∑
L
(
y
^
(
i
)
,
y
(
i
)
)
J(w)=\frac{1}{k}\sum{L(\hat{y}^{(i)},y^{(i)})}
J(w)=k1∑L(y^(i),y(i))
该代价函数衡量了训练集整体的混乱度,即信息熵。
所以,梯度下降法就是沿着梯度的方向,寻找一个最优的权重向量 W W W ,使得代价函数的函数值最小(但不是越小越好)。
至此,我们介绍完了logistic回归所要应用的所有数学公式。下面,展示logistic编程与调包。
编程:
# -*- coding: utf-8 -*-
import numpy as np
class Logistic():
def __init__(self):
# 生成训练样本,其中a为特征值,b为标签
a=[[0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 1.75, 2.00, 2.25,2.50, 2.75, 3.00, 3.25, 3.50, 4.00, 4.25, 4.50, 4.75, 5.00, 5.50]]
a=np.array(a)
a=a.T
ones=np.ones((a.shape[0],1))
a=np.column_stack((ones,a))
b=[[0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1]]
b=np.array(b)
b=b.T
self.data_set=a
self.data_target=b
self.feature_size=self.data_set.shape[1]
self.number_size=self.data_set.shape[0]
self.W=np.random.randn(self.feature_size)
pass
def LG_Linear(self):
#线性层,将特征空间映射为值域空间
y=np.dot(self.data_set,self.W.transpose())
y=np.array([y])
y=y.T
return y
pass
def LG_sigmoid(self,y):
#非线性层,将值域空间映射为(0,1)
P=np.exp(y)/(1+np.exp(y))
return P
pass
def LG_cost(self,P,target):
#损失函数
cost=-target*np.log(P)-(1-target)*np.log(1-P)
return cost
pass
def BP(self,P,target):
#反向传播函数
learningrate=0.05
for i in range(self.number_size):
dz=P[i][0]-target[i][0]
#dz为代价函数求导所得
dw=self.data_set[i][:]*dz
self.W=self.W-learningrate*dw
print(self.W)
return self.W
pass
def predict(self,x):
#预测函数
pre=np.dot(self.W,x.transpose())
pre=self.LG_sigmoid(pre)
return pre
pass
pass
def main():
lg=Logistic()
y=lg.LG_Linear()
P=lg.LG_sigmoid(y=y)
# lg.LG_cost(P=P,target=lg.data_target)
for _ in range(10):
lg.BP(P=P,target=lg.data_target)
pre=lg.predict(np.array([[1,5]]))
print(lg.W)
print(pre)
pass
if __name__ == '__main__':
main()
调包:
# -*- coding: utf-8 -*-
# 导包
import numpy as np
from sklearn.linear_model import LogisticRegression
# 加载数据
a = [[0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 1.75, 2.00, 2.25, 2.50, 2.75, 3.00, 3.25, 3.50, 4.00, 4.25, 4.50, 4.75, 5.00,
5.50]]
a = np.array(a)
a = a.T
b = [[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
b = np.array(b)
b = b.T
x=a
y=b
lr = LogisticRegression()
# 训练数据
lr.fit(x,y)
#求出w斜率和b截距的值
w = lr.coef_
b = lr.intercept_
print(w, b)
# 预测一下概率
predict= lr.predict_proba([[3]])
print(predict)
更多推荐










所有评论(0)