简介
成都创新互联公司2013年至今,先为张北等服务建站,张北等地企业,进行企业商务咨询服务。为张北企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
本例子是通过对一组逻辑回归映射进行输出,使得网络的权重和偏置达到最理想状态,最后再进行预测。其中,使用GD算法对参数进行更新,损耗函数采取交叉商来表示,一共训练10000次。
2.python代码
#!/usr/bin/python
import numpy
import theano
import theano.tensor as T
rng=numpy.random
N=400
feats=784
# D[0]:generate rand numbers of size N,element between (0,1)
# D[1]:generate rand int number of size N,0 or 1
D=(rng.randn(N,feats),rng.randint(size=N,low=0,high=2))
training_steps=10000
# declare symbolic variables
x=T.matrix('x')
y=T.vector('y')
w=theano.shared(rng.randn(feats),name='w') # w is shared for every input
b=theano.shared(0.,name='b') # b is shared too.
print('Initial model:')
print(w.get_value())
print(b.get_value())
# construct theano expressions,symbolic
p_1=1/(1+T.exp(-T.dot(x,w)-b)) # sigmoid function,probability of target being 1
prediction=p_10.5
xent=-y*T.log(p_1)-(1-y)*T.log(1-p_1) # cross entropy
cost=xent.mean()+0.01*(w**2).sum() # cost function to update parameters
gw,gb=T.grad(cost,[w,b]) # stochastic gradient descending algorithm
#compile
train=theano.function(inputs=[x,y],outputs=[prediction,xent],updates=((w,w-0.1*gw),(b,b-0.1*gb)))
predict=theano.function(inputs=[x],outputs=prediction)
# train
for i in range(training_steps):
pred,err=train(D[0],D[1])
print('Final model:')
print(w.get_value())
print(b.get_value())
print('target values for D:')
print(D[1])
print('prediction on D:')
print(predict(D[0]))
print('newly generated data for test:')
test_input=rng.randn(30,feats)
print('result:')
print(predict(test_input))
3.程序解读
如上面所示,首先导入所需的库,theano是一个用于科学计算的库。然后这里我们随机产生一个输入矩阵,大小为400*784的随机数,随机产生一个输出向量大小为400,输出向量为二值的。因此,称为逻辑回归。
然后初始化权重和偏置,它们均为共享变量(shared),其中权重初始化为较小的数,偏置初始化为0,并且打印它们。
这里我们只构建一层网络结构,使用的激活函数为logistic sigmoid function,对输入量乘以权重并考虑偏置以后就可以算出输入的激活值,该值在(0,1)之间,以0.5为界限进行二值化,然后算出交叉商和损耗函数,其中交叉商是代表了我们的激活值与实际理论值的偏离程度。接着我们使用cost分别对w,b进行求解偏导,以上均为符号表达式运算。
接着我们使用theano.function进行编译优化,提高计算效率。得到train函数和predict函数,分别进行训练和预测。
接着,我们对数据进行10000次的训练,每次训练都会按照GD算法进行更新参数,最后我们得到了想要的模型,产生一组新的输入,即可进行预测。
实际上完成逻辑回归是相当简单的,首先指定要预测变量的列,接着指定模型用于做预测的列,剩下的就由算法包去完成了。
本例中要预测的是admin列,使用到gre、gpa和虚拟变量prestige_2、prestige_3、prestige_4。prestige_1作为基准,所以排除掉,以防止多元共线性(multicollinearity)和引入分类变量的所有虚拟变量值所导致的陷阱(dummy variable trap)。
程序缩进如图所示
Logistic函数的表示形式如下:
它的函数图像如下,由于函数图像很像一个“S”型,所以该函数又叫 sigmoid 函数。
满足的性质:
1.对称性,关于(0,0.5)中心对称
2.逻辑斯谛方程即微分方程
最早logistic函数是皮埃尔·弗朗索瓦·韦吕勒在1844或1845年在研究它与人口增长的关系时命名的。广义Logistic曲线可以模仿一些情况人口增长( P )的 S 形曲线。起初阶段大致是 指数增长 ;然后随着开始变得饱和,增加变慢;最后,达到成熟时增加停止。
当一个物种迁入到一个新生态系统中后,其数量会发生变化。假设该物种的起始数量小于环境的最大容纳量,则数量会增长。该物种在此生态系统中有天敌、食物、空间等资源也不足(非理想环境),则增长函数满足逻辑斯谛方程,图像呈S形,此方程是描述在资源有限的条件下种群增长规律的一个最佳数学模型。在以下内容中将具体介绍逻辑斯谛方程的原理、生态学意义及其应用。
Logistic regression (逻辑回归)是当前业界比较常用的机器学习方法,用于估计某种事物的可能性。之前在经典之作《数学之美》中也看到了它用于广告预测,也就是根据某广告被用户点击的可能性,把最可能被用户点击的广告摆在用户能看到的地方,然后叫他“你点我啊!”用户点了,你就有钱收了。这就是为什么我们的电脑现在广告泛滥的原因了。
还有类似的某用户购买某商品的可能性,某病人患有某种疾病的可能性啊等等。这个世界是随机的(当然了,人为的确定性系统除外,但也有可能有噪声或产生错误的结果,只是这个错误发生的可能性太小了,小到千万年不遇,小到忽略不计而已),所以万物的发生都可以用可能性或者几率(Odds)来表达。“几率”指的是某事物发生的可能性与不发生的可能性的比值。
Logistic regression可以用来回归,也可以用来分类,主要是二分类。它不像SVM直接给出一个分类的结果,Logistic Regression给出的是这个样本属于正类或者负类的可能性是多少,当然在多分类的系统中给出的是属于不同类别的可能性,进而通过可能性来分类。
假设我们的样本是{ x , y},y是0或者1,表示正类或者负类, x 是我们的m维的样本特征向量。那么这个样本 x 属于正类,也就是y=1的“概率”可以通过下面的逻辑函数来表示:
这里的 θ 是模型参数,也就是回归系数,σ是sigmoid函数。这样y=0的“概率”就是:
考查逻辑斯蒂回归模型的特点,一个事件的几率(oods)是指这件事发生的概率与不发生概率的比值,如果事件发生的概率是p,那么该事件的几率是p/(1-p),该事件的对数几率(log odds)或者logit函数是
对于逻辑斯蒂回归而言,可以得到如下的对数几率
这就是说,在逻辑斯蒂回归模型中,输出y=1的对数几率是输入x的线性函数,或者说,输出y=1的对数几率是由输入x的线性函数表示的模型,即逻辑斯蒂回归模型。换句话说,y就是我们的关系变量,例如她喜不喜欢你,与多个因素有关,比如你的人品,你的长相,你是否有钱等。我们把这些因素表示成变量x 1 , x 2 ,…, x m ,那么这个女生是怎么考虑这些因素的呢,每个人心理其实都有一杆秤,例如有人比较看重你的人品,人品的权重是0.8,;也有人比较看重你有钱,有钱的权重设置成0.7等等。我们把这些对应于x 1 , x 2 ,…, x m 的权值叫做回归系数,表达为θ 1 , θ 2 ,…, θ m 。他们的加权和就是你在心目中的得分。
在参数学习时,可以用极大似然估计方法求解。假设我们有n个独立的训练样本{( x 1 , y 1 ) ,( x 2 , y 2 ),…, ( x n , y n )},y={0, 1}。那每一个观察到的样本( x i , y i )出现的概率是
对于整个样本集,每个样本的出现都是独立的,n个样本出现的似然函数为(n个样本的出现概率是他们各自的概率乘积)
那么上述的似然函数就是模型的代价函数(cost function),我们要求的参数就是θ*。我们稍微对上式进行转换
对L(θ)的极大值,得到θ的估计值。问题变成了以对数似然函数为木匾函数的最优化问题。用L(θ)对θ求导,得到
无法解析求解的,所以一般使用迭代的方法求解,通常采用梯度下降法和拟牛顿法。
上面介绍的是儿分类的模型,用于二类分类。可以将其推广为多项逻辑斯蒂回归模型(multi-nominal regression model),用于多分类,假设离散随机变量Y的取值是{1,2,3,...,K}那么多项逻辑斯蒂回归的模型是
同理,二项逻辑斯蒂回归的参数估计的方法也可以推广到多项逻辑斯蒂回归。
[1]. 机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)
[2].《统计学习方法》 李航 著
1. 常用函数库
scipy包中的stats模块和statsmodels包是python常用的数据分析工具,scipy.stats以前有一个models子模块,后来被移除了。这个模块被重写并成为了现在独立的statsmodels包。
scipy的stats包含一些比较基本的工具,比如:t检验,正态性检验,卡方检验之类,statsmodels提供了更为系统的统计模型,包括线性模型,时序分析,还包含数据集,做图工具等等。
2. 小样本数据的正态性检验
(1) 用途
夏皮罗维尔克检验法 (Shapiro-Wilk) 用于检验参数提供的一组小样本数据线是否符合正态分布,统计量越大则表示数据越符合正态分布,但是在非正态分布的小样本数据中也经常会出现较大的W值。需要查表来估计其概率。由于原假设是其符合正态分布,所以当P值小于指定显著水平时表示其不符合正态分布。
正态性检验是数据分析的第一步,数据是否符合正态性决定了后续使用不同的分析和预测方法,当数据不符合正态性分布时,我们可以通过不同的转换方法把非正太态数据转换成正态分布后再使用相应的统计方法进行下一步操作。
(2) 示例
(3) 结果分析
返回结果 p-value=0.029035290703177452,比指定的显著水平(一般为5%)小,则拒绝假设:x不服从正态分布。
3. 检验样本是否服务某一分布
(1) 用途
科尔莫戈罗夫检验(Kolmogorov-Smirnov test),检验样本数据是否服从某一分布,仅适用于连续分布的检验。下例中用它检验正态分布。
(2) 示例
(3) 结果分析
生成300个服从N(0,1)标准正态分布的随机数,在使用k-s检验该数据是否服从正态分布,提出假设:x从正态分布。最终返回的结果,p-value=0.9260909172362317,比指定的显著水平(一般为5%)大,则我们不能拒绝假设:x服从正态分布。这并不是说x服从正态分布一定是正确的,而是说没有充分的证据证明x不服从正态分布。因此我们的假设被接受,认为x服从正态分布。如果p-value小于我们指定的显著性水平,则我们可以肯定地拒绝提出的假设,认为x肯定不服从正态分布,这个拒绝是绝对正确的。
4.方差齐性检验
(1) 用途
方差反映了一组数据与其平均值的偏离程度,方差齐性检验用以检验两组或多组数据与其平均值偏离程度是否存在差异,也是很多检验和算法的先决条件。
(2) 示例
(3) 结果分析
返回结果 p-value=0.19337536323599344, 比指定的显著水平(假设为5%)大,认为两组数据具有方差齐性。
5. 图形描述相关性
(1) 用途
最常用的两变量相关性分析,是用作图描述相关性,图的横轴是一个变量,纵轴是另一变量,画散点图,从图中可以直观地看到相关性的方向和强弱,线性正相关一般形成由左下到右上的图形;负面相关则是从左上到右下的图形,还有一些非线性相关也能从图中观察到。
(2) 示例
(3) 结果分析
从图中可以看到明显的正相关趋势。
6. 正态资料的相关分析
(1) 用途
皮尔森相关系数(Pearson correlation coefficient)是反应两变量之间线性相关程度的统计量,用它来分析正态分布的两个连续型变量之间的相关性。常用于分析自变量之间,以及自变量和因变量之间的相关性。
(2) 示例
(3) 结果分析
返回结果的第一个值为相关系数表示线性相关程度,其取值范围在[-1,1],绝对值越接近1,说明两个变量的相关性越强,绝对值越接近0说明两个变量的相关性越差。当两个变量完全不相关时相关系数为0。第二个值为p-value,统计学上,一般当p-value0.05时,可以认为两变量存在相关性。
7. 非正态资料的相关分析
(1) 用途
斯皮尔曼等级相关系数(Spearman’s correlation coefficient for ranked data ),它主要用于评价顺序变量间的线性相关关系,在计算过程中,只考虑变量值的顺序(rank, 值或称等级),而不考虑变量值的大小。常用于计算类型变量的相关性。
(2) 示例
(3) 结果分析
返回结果的第一个值为相关系数表示线性相关程度,本例中correlation趋近于1表示正相关。第二个值为p-value,p-value越小,表示相关程度越显著。
8. 单样本T检验
(1) 用途
单样本T检验,用于检验数据是否来自一致均值的总体,T检验主要是以均值为核心的检验。注意以下几种T检验都是双侧T检验。
(2) 示例
(3) 结果分析
本例中生成了2列100行的数组,ttest_1samp的第二个参数是分别对两列估计的均值,p-value返回结果,第一列1.47820719e-06比指定的显著水平(一般为5%)小,认为差异显著,拒绝假设;第二列2.83088106e-01大于指定显著水平,不能拒绝假设:服从正态分布。
9. 两独立样本T检验
(1) 用途
由于比较两组数据是否来自于同一正态分布的总体。注意:如果要比较的两组数据不满足方差齐性, 需要在ttest_ind()函数中添加参数equal_var = False。
(2) 示例
(3) 结果分析
返回结果的第一个值为统计量,第二个值为p-value,pvalue=0.19313343989106416,比指定的显著水平(一般为5%)大,不能拒绝假设,两组数据来自于同一总结,两组数据之间无差异。
10. 配对样本T检验
(1) 用途
配对样本T检验可视为单样本T检验的扩展,检验的对象由一群来自正态分布独立样本更改为二群配对样本观测值之差。它常用于比较同一受试对象处理的前后差异,或者按照某一条件进行两两配对分别给与不同处理的受试对象之间是否存在差异。
(2) 示例
(3) 结果分析
返回结果的第一个值为统计量,第二个值为p-value,pvalue=0.80964043445811551,比指定的显著水平(一般为5%)大,不能拒绝假设。
11. 单因素方差分析
(1) 用途
方差分析(Analysis of Variance,简称ANOVA),又称F检验,用于两个及两个以上样本均数差别的显著性检验。方差分析主要是考虑各组之间的平均数差别。
单因素方差分析(One-wayAnova),是检验由单一因素影响的多组样本某因变量的均值是否有显著差异。
当因变量Y是数值型,自变量X是分类值,通常的做法是按X的类别把实例成分几组,分析Y值在X的不同分组中是否存在差异。
(2) 示例
(3) 结果分析
返回结果的第一个值为统计量,它由组间差异除以组间差异得到,上例中组间差异很大,第二个返回值p-value=6.2231520821576832e-19小于边界值(一般为0.05),拒绝原假设, 即认为以上三组数据存在统计学差异,并不能判断是哪两组之间存在差异 。只有两组数据时,效果同 stats.levene 一样。
12. 多因素方差分析
(1) 用途
当有两个或者两个以上自变量对因变量产生影响时,可以用多因素方差分析的方法来进行分析。它不仅要考虑每个因素的主效应,还要考虑因素之间的交互效应。
(2) 示例
(3) 结果分析
上述程序定义了公式,公式中,"~"用于隔离因变量和自变量,”+“用于分隔各个自变量, ":"表示两个自变量交互影响。从返回结果的P值可以看出,X1和X2的值组间差异不大,而组合后的T:G的组间有明显差异。
13. 卡方检验
(1) 用途
上面介绍的T检验是参数检验,卡方检验是一种非参数检验方法。相对来说,非参数检验对数据分布的要求比较宽松,并且也不要求太大数据量。卡方检验是一种对计数资料的假设检验方法,主要是比较理论频数和实际频数的吻合程度。常用于特征选择,比如,检验男人和女人在是否患有高血压上有无区别,如果有区别,则说明性别与是否患有高血压有关,在后续分析时就需要把性别这个分类变量放入模型训练。
基本数据有R行C列, 故通称RC列联表(contingency table), 简称RC表,它是观测数据按两个或更多属性(定性变量)分类时所列出的频数表。
(2) 示例
(3) 结果分析
卡方检验函数的参数是列联表中的频数,返回结果第一个值为统计量值,第二个结果为p-value值,p-value=0.54543425102570975,比指定的显著水平(一般5%)大,不能拒绝原假设,即相关性不显著。第三个结果是自由度,第四个结果的数组是列联表的期望值分布。
14. 单变量统计分析
(1) 用途
单变量统计描述是数据分析中最简单的形式,其中被分析的数据只包含一个变量,不处理原因或关系。单变量分析的主要目的是通过对数据的统计描述了解当前数据的基本情况,并找出数据的分布模型。
单变量数据统计描述从集中趋势上看,指标有:均值,中位数,分位数,众数;从离散程度上看,指标有:极差、四分位数、方差、标准差、协方差、变异系数,从分布上看,有偏度,峰度等。需要考虑的还有极大值,极小值(数值型变量)和频数,构成比(分类或等级变量)。
此外,还可以用统计图直观展示数据分布特征,如:柱状图、正方图、箱式图、频率多边形和饼状图。
15. 多元线性回归
(1) 用途
多元线性回归模型(multivariable linear regression model ),因变量Y(计量资料)往往受到多个变量X的影响,多元线性回归模型用于计算各个自变量对因变量的影响程度,可以认为是对多维空间中的点做线性拟合。
(2) 示例
(3) 结果分析
直接通过返回结果中各变量的P值与0.05比较,来判定对应的解释变量的显著性,P0.05则认为自变量具有统计学意义,从上例中可以看到收入INCOME最有显著性。
16. 逻辑回归
(1) 用途
当因变量Y为2分类变量(或多分类变量时)可以用相应的logistic回归分析各个自变量对因变量的影响程度。
(2) 示例
(3) 结果分析
直接通过返回结果中各变量的P值与0.05比较,来判定对应的解释变量的显著性,P0.05则认为自变量具有统计学意义。
以下为python代码,由于训练数据比较少,这边使用了批处理梯度下降法,没有使用增量梯度下降法。
##author:lijiayan##data:2016/10/27
##name:logReg.pyfrom numpy import *import matplotlib.pyplot as pltdef loadData(filename):
data = loadtxt(filename)
m,n = data.shape print 'the number of examples:',m print 'the number of features:',n-1 x = data[:,0:n-1]
y = data[:,n-1:n] return x,y#the sigmoid functiondef sigmoid(z): return 1.0 / (1 + exp(-z))#the cost functiondef costfunction(y,h):
y = array(y)
h = array(h)
J = sum(y*log(h))+sum((1-y)*log(1-h)) return J# the batch gradient descent algrithmdef gradescent(x,y):
m,n = shape(x) #m: number of training example; n: number of features x = c_[ones(m),x] #add x0 x = mat(x) # to matrix y = mat(y)
a = 0.0000025 # learning rate maxcycle = 4000 theta = zeros((n+1,1)) #initial theta J = [] for i in range(maxcycle):
h = sigmoid(x*theta)
theta = theta + a * (x.T)*(y-h)
cost = costfunction(y,h)
J.append(cost)
plt.plot(J)
plt.show() return theta,cost#the stochastic gradient descent (m should be large,if you want the result is good)def stocGraddescent(x,y):
m,n = shape(x) #m: number of training example; n: number of features x = c_[ones(m),x] #add x0 x = mat(x) # to matrix y = mat(y)
a = 0.01 # learning rate theta = ones((n+1,1)) #initial theta J = [] for i in range(m):
h = sigmoid(x[i]*theta)
theta = theta + a * x[i].transpose()*(y[i]-h)
cost = costfunction(y,h)
J.append(cost)
plt.plot(J)
plt.show() return theta,cost#plot the decision boundarydef plotbestfit(x,y,theta):
plt.plot(x[:,0:1][where(y==1)],x[:,1:2][where(y==1)],'ro')
plt.plot(x[:,0:1][where(y!=1)],x[:,1:2][where(y!=1)],'bx')
x1= arange(-4,4,0.1)
x2 =(-float(theta[0])-float(theta[1])*x1) /float(theta[2])
plt.plot(x1,x2)
plt.xlabel('x1')
plt.ylabel(('x2'))
plt.show()def classifyVector(inX,theta):
prob = sigmoid((inX*theta).sum(1)) return where(prob = 0.5, 1, 0)def accuracy(x, y, theta):
m = shape(y)[0]
x = c_[ones(m),x]
y_p = classifyVector(x,theta)
accuracy = sum(y_p==y)/float(m) return accuracy
调用上面代码:
from logReg import *
x,y = loadData("horseColicTraining.txt")
theta,cost = gradescent(x,y)print 'J:',cost
ac_train = accuracy(x, y, theta)print 'accuracy of the training examples:', ac_train
x_test,y_test = loadData('horseColicTest.txt')
ac_test = accuracy(x_test, y_test, theta)print 'accuracy of the test examples:', ac_test
学习速率=0.0000025,迭代次数=4000时的结果:
似然函数走势(J = sum(y*log(h))+sum((1-y)*log(1-h))),似然函数是求最大值,一般是要稳定了才算最好。
下图为计算结果,可以看到训练集的准确率为73%,测试集的准确率为78%。
这个时候,我去看了一下数据集,发现没个特征的数量级不一致,于是我想到要进行归一化处理:
归一化处理句修改列loadData(filename)函数:
def loadData(filename):
data = loadtxt(filename)
m,n = data.shape print 'the number of examples:',m print 'the number of features:',n-1 x = data[:,0:n-1]
max = x.max(0)
min = x.min(0)
x = (x - min)/((max-min)*1.0) #scaling y = data[:,n-1:n] return x,y
在没有归一化的时候,我的学习速率取了0.0000025(加大就会震荡,因为有些特征的值很大,学习速率取的稍大,波动就很大),由于学习速率小,迭代了4000次也没有完全稳定。现在当把特征归一化后(所有特征的值都在0~1之间),这样学习速率可以加大,迭代次数就可以大大减少,以下是学习速率=0.005,迭代次数=500的结果:
此时的训练集的准确率为72%,测试集的准确率为73%
从上面这个例子,我们可以看到对特征进行归一化操作的重要性。