机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)

http://blog.csdn.net/zouxy09/article/details/20319673

 

机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)

zouxy09@qq.com

http://blog.csdn.net/zouxy09

 

       机器学习算法与Python实践这个系列主要是参考《机器学习实战》这本书。因为自己想学习Python,然后也想对一些机器学习算法加深下了解,所以就想通过Python来实现几个比较常用的机器学习算法。恰好遇见这本同样定位的书籍,所以就参考这本书的过程来学习了。

       这节学习的是逻辑回归(Logistic Regression),也算进入了比较正统的机器学习算法。啥叫正统呢?我概念里面机器学习算法一般是这样一个步骤:

1)对于一个问题,我们用数学语言来描述它,然后建立一个模型,例如回归模型或者分类模型等来描述这个问题;

2)通过最大似然、最大后验概率或者最小化分类误差等等建立模型的代价函数,也就是一个最优化问题。找到最优化问题的解,也就是能拟合我们的数据的最好的模型参数;

3)然后我们需要求解这个代价函数,找到最优解。这求解也就分很多种情况了:

      a)如果这个优化函数存在解析解。例如我们求最值一般是对代价函数求导,找到导数为0的点,也就是最大值或者最小值的地方了。如果代价函数能简单求导,并且求导后为0的式子存在解析解,那么我们就可以直接得到最优的参数了。

      b)如果式子很难求导,例如函数里面存在隐含的变量或者变量相互间存在耦合,也就互相依赖的情况。或者求导后式子得不到解释解,例如未知参数的个数大于已知方程组的个数等。这时候我们就需要借助迭代算法来一步一步找到最有解了。迭代是个很神奇的东西,它将远大的目标(也就是找到最优的解,例如爬上山顶)记在心上,然后给自己定个短期目标(也就是每走一步,就离远大的目标更近一点),脚踏实地,心无旁贷,像个蜗牛一样,一步一步往上爬,支撑它的唯一信念是:只要我每一步都爬高一点,那么积跬步,肯定能达到自己人生的巅峰,尽享山登绝顶我为峰的豪迈与忘我。

       另外需要考虑的情况是,如果代价函数是凸函数,那么就存在全局最优解,方圆五百里就只有一个山峰,那命中注定了,它就是你要找的唯一了。但如果是非凸的,那么就会有很多局部最优的解,有一望无际的山峰,人的视野是伟大的也是渺小的,你不知道哪个山峰才是最高的,可能你会被命运作弄,很无辜的陷入一个局部最优里面,坐井观天,以为自己找到的就是最好的。没想到山外有山,人外有人,光芒总在未知的远处默默绽放。但也许命运眷恋善良的你,带给你的总是最好的归宿。也有很多不信命的人,觉得人定胜天的人,誓要找到最好的,否则不会罢休,永不向命运妥协,除非自己有一天累了,倒下了,也要靠剩下的一口气,迈出一口气能支撑的路程。好悲凉啊……哈哈。

        呃,不知道扯那去了,也不知道自己说的有没有错,有错的话请大家不吝指正。那下面就进入正题吧。正如上面所述,逻辑回归就是这样的一个过程:面对一个回归或者分类问题,建立代价函数,然后通过优化方法迭代求解出最优的模型参数,然后测试验证我们这个求解的模型的好坏,冥冥人海,滚滚红尘,我们是否找到了最适合的那个她。

 

一、逻辑回归(LogisticRegression)

       Logistic regression (逻辑回归)是当前业界比较常用的机器学习方法,用于估计某种事物的可能性。之前在经典之作《数学之美》中也看到了它用于广告预测,也就是根据某广告被用户点击的可能性,把最可能被用户点击的广告摆在用户能看到的地方,然后叫他“你点我啊!”用户点了,你就有钱收了。这就是为什么我们的电脑现在广告泛滥的原因了。

       还有类似的某用户购买某商品的可能性,某病人患有某种疾病的可能性啊等等。这个世界是随机的(当然了,人为的确定性系统除外,但也有可能有噪声或产生错误的结果,只是这个错误发生的可能性太小了,小到千万年不遇,小到忽略不计而已),所以万物的发生都可以用可能性或者几率(Odds)来表达。“几率”指的是某事物发生的可能性与不发生的可能性的比值。

       Logistic regression可以用来回归,也可以用来分类,主要是二分类。还记得上几节讲的支持向量机SVM吗?它就是个二分类的例如,它可以将两个不同类别的样本给分开,思想是找到最能区分它们的那个分类超平面。但当你给一个新的样本给它,它能够给你的只有一个答案,你这个样本是正类还是负类。例如你问SVM,某个女生是否喜欢你,它只会回答你喜欢或者不喜欢。这对我们来说,显得太粗鲁了,要不希望,要不绝望,这都不利于身心健康。那如果它可以告诉我,她很喜欢、有一点喜欢、不怎么喜欢或者一点都不喜欢,你想都不用想了等等,告诉你她有49%的几率喜欢你,总比直接说她不喜欢你,来得温柔。而且还提供了额外的信息,她来到你的身边你有多少希望,你得再努力多少倍,知己知彼百战百胜,哈哈。Logistic regression就是这么温柔的,它给我们提供的就是你的这个样本属于正类的可能性是多少。

       还得来点数学。(更多的理解,请参阅参考文献)假设我们的样本是{x, y},y是0或者1,表示正类或者负类,x是我们的m维的样本特征向量。那么这个样本x属于正类,也就是y=1的“概率”可以通过下面的逻辑函数来表示:

       这里θ是模型参数,也就是回归系数,σ是sigmoid函数。实际上这个函数是由下面的对数几率(也就是x属于正类的可能性和负类的可能性的比值的对数)变换得到的:

       换句话说,y也就是我们关系的变量,例如她喜不喜欢你,与多个自变量(因素)有关,例如你人品怎样、车子是两个轮的还是四个轮的、长得胜过潘安还是和犀利哥有得一拼、有千尺豪宅还是三寸茅庐等等,我们把这些因素表示为x1, x2,…, xm。那这个女的怎样考量这些因素呢?最快的方式就是把这些因素的得分都加起来,最后得到的和越大,就表示越喜欢。但每个人心里其实都有一杆称,每个人考虑的因素不同,萝卜青菜,各有所爱嘛。例如这个女生更看中你的人品,人品的权值是0.6,不看重你有没有钱,没钱了一起努力奋斗,那么有没有钱的权值是0.001等等。我们将这些对应x1, x2,…, xm的权值叫做回归系数,表达为θ1, θ2,…, θm。他们的加权和就是你的总得分了。请选择你的心仪男生,非诚勿扰!哈哈。

       所以说上面的logistic回归就是一个线性分类模型,它与线性回归的不同点在于:为了将线性回归输出的很大范围的数,例如从负无穷到正无穷,压缩到0和1之间,这样的输出值表达为“可能性”才能说服广大民众。当然了,把大值压缩到这个范围还有个很好的好处,就是可以消除特别冒尖的变量的影响(不知道理解的是否正确)。而实现这个伟大的功能其实就只需要平凡一举,也就是在输出加一个logistic函数。另外,对于二分类来说,可以简单的认为:如果样本x属于正类的概率大于0.5,那么就判定它是正类,否则就是负类。实际上,SVM的类概率就是样本到边界的距离,这个活实际上就让logistic regression给干了。

       所以说,LogisticRegression 就是一个被logistic方程归一化后的线性回归,仅此而已。

好了,关于LR的八卦就聊到这。归入到正统的机器学习框架下,模型选好了,只是模型的参数θ还是未知的,我们需要用我们收集到的数据来训练求解得到它。那我们下一步要做的事情就是建立代价函数了。

       LogisticRegression最基本的学习算法是最大似然。啥叫最大似然,可以看看我的另一篇博文“从最大似然到EM算法浅解”。

       假设我们有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个样本出现的概率就是他们各自出现的概率相乘):

       那最大似然法就是求模型中使得似然函数最大的系数取值θ*。这个最大似然就是我们的代价函数(cost function)了。

       OK,那代价函数有了,我们下一步要做的就是优化求解了。我们先尝试对上面的代价函数求导,看导数为0的时候可不可以解出来,也就是有没有解析解,有这个解的时候,就皆大欢喜了,一步到位。如果没有就需要通过迭代了,耗时耗力。

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

       这时候,用L(θ)对θ求导,得到:

       然后我们令该导数为0,你会很失望的发现,它无法解析求解。不信你就去尝试一下。所以没办法了,只能借助高大上的迭代来搞定了。这里选用了经典的梯度下降算法。

 

二、优化求解

2.1、梯度下降(gradient descent)

        Gradient descent 又叫 steepest descent,是利用一阶的梯度信息找到函数局部最优解的一种方法,也是机器学习里面最简单最常用的一种优化方法。它的思想很简单,和我开篇说的那样,要找最小值,我只需要每一步都往下走(也就是每一步都可以让代价函数小一点),然后不断的走,那肯定能走到最小值的地方,例如下图所示:

      但,我同时也需要更快的到达最小值啊,怎么办呢?我们需要每一步都找下坡最快的地方,也就是每一步我走某个方向,都比走其他方法,要离最小值更近。而这个下坡最快的方向,就是梯度的负方向了。

对logistic Regression来说,梯度下降算法新鲜出炉,如下:

      其中,参数α叫学习率,就是每一步走多远,这个参数蛮关键的。如果设置的太多,那么很容易就在最优值附加徘徊,因为你步伐太大了。例如要从广州到上海,但是你的一步的距离就是广州到北京那么远,没有半步的说法,自己能迈那么大步,是幸运呢?还是不幸呢?事物总有两面性嘛,它带来的好处是能很快的从远离最优值的地方回到最优值附近,只是在最优值附近的时候,它有心无力了。但如果设置的太小,那收敛速度就太慢了,向蜗牛一样,虽然会落在最优的点,但是这速度如果是猴年马月,我们也没这耐心啊。所以有的改进就是在这个学习率这个地方下刀子的。我开始迭代是,学习率大,慢慢的接近最优值的时候,我的学习率变小就可以了。所谓采两者之精华啊!这个优化具体见2.3 。

       梯度下降算法的伪代码如下:

################################################

初始化回归系数为1

重复下面步骤直到收敛{

        计算整个数据集的梯度

        使用alpha x gradient来更新回归系数

}

返回回归系数值

################################################

 

2.2、随机梯度下降SGD (stochastic gradient descent)

      梯度下降算法在每次更新回归系数的时候都需要遍历整个数据集(计算整个数据集的回归误差),该方法对小数据集尚可。但当遇到有数十亿样本和成千上万的特征时,就有点力不从心了,它的计算复杂度太高。改进的方法是一次仅用一个样本点(的回归误差)来更新回归系数。这个方法叫随机梯度下降算法。由于可以在新的样本到来的时候对分类器进行增量的更新(假设我们已经在数据库A上训练好一个分类器h了,那新来一个样本x。对非增量学习算法来说,我们需要把x和数据库A混在一起,组成新的数据库B,再重新训练新的分类器。但对增量学习算法,我们只需要用新样本x来更新已有分类器h的参数即可),所以它属于在线学习算法。与在线学习相对应,一次处理整个数据集的叫“批处理”。

        随机梯度下降算法的伪代码如下:

################################################

初始化回归系数为1

重复下面步骤直到收敛{

        对数据集中每个样本

               计算该样本的梯度

                使用alpha xgradient来更新回归系数

 }

返回回归系数值

################################################

 

2.3、改进的随机梯度下降

      评价一个优化算法的优劣主要是看它是否收敛,也就是说参数是否达到稳定值,是否还会不断的变化?收敛速度是否快?

       上图展示了随机梯度下降算法在200次迭代中(请先看第三和第四节再回来看这里。我们的数据库有100个二维样本,每个样本都对系数调整一次,所以共有200*100=20000次调整)三个回归系数的变化过程。其中系数X2经过50次迭代就达到了稳定值。但系数X1和X0到100次迭代后稳定。而且可恨的是系数X1和X2还在很调皮的周期波动,迭代次数很大了,心还停不下来。产生这个现象的原因是存在一些无法正确分类的样本点,也就是我们的数据集并非线性可分,但我们的logistic regression是线性分类模型,对非线性可分情况无能为力。然而我们的优化程序并没能意识到这些不正常的样本点,还一视同仁的对待,调整系数去减少对这些样本的分类误差,从而导致了在每次迭代时引发系数的剧烈改变。对我们来说,我们期待算法能避免来回波动,从而快速稳定和收敛到某个值。

       对随机梯度下降算法,我们做两处改进来避免上述的波动问题:

1)在每次迭代时,调整更新步长alpha的值。随着迭代的进行,alpha越来越小,这会缓解系数的高频波动(也就是每次迭代系数改变得太大,跳的跨度太大)。当然了,为了避免alpha随着迭代不断减小到接近于0(这时候,系数几乎没有调整,那么迭代也没有意义了),我们约束alpha一定大于一个稍微大点的常数项,具体见代码。

2)每次迭代,改变样本的优化顺序。也就是随机选择样本来更新回归系数。这样做可以减少周期性的波动,因为样本顺序的改变,使得每次迭代不再形成周期性。

       改进的随机梯度下降算法的伪代码如下:

################################################

初始化回归系数为1

重复下面步骤直到收敛{

       对随机遍历的数据集中的每个样本

              随着迭代的逐渐进行,减小alpha的值

              计算该样本的梯度

              使用alpha x gradient来更新回归系数

    }

返回回归系数值

################################################

       比较原始的随机梯度下降和改进后的梯度下降,可以看到两点不同:

1)系数不再出现周期性波动。2)系数可以很快的稳定下来,也就是快速收敛。这里只迭代了20次就收敛了。而上面的随机梯度下降需要迭代200次才能稳定。

 

三、Python实现

      我使用的Python是2.7.5版本的。附加的库有Numpy和Matplotlib。具体的安装和配置见前面的博文。在代码中已经有了比较详细的注释了。不知道有没有错误的地方,如果有,还望大家指正(每次的运行结果都有可能不同)。里面我写了个可视化结果的函数,但只能在二维的数据上面使用。直接贴代码:

logRegression.py

 

[python] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #################################################  
  2. # logRegression: Logistic Regression  
  3. # Author : zouxy  
  4. # Date   : 2014-03-02  
  5. # HomePage : http://blog.csdn.net/zouxy09  
  6. # Email  : zouxy09@qq.com  
  7. #################################################  
  8.   
  9. from numpy import *  
  10. import matplotlib.pyplot as plt  
  11. import time  
  12.   
  13.   
  14. # calculate the sigmoid function  
  15. def sigmoid(inX):  
  16.     return 1.0 / (1 + exp(-inX))  
  17.   
  18.   
  19. # train a logistic regression model using some optional optimize algorithm  
  20. # input: train_x is a mat datatype, each row stands for one sample  
  21. #        train_y is mat datatype too, each row is the corresponding label  
  22. #        opts is optimize option include step and maximum number of iterations  
  23. def trainLogRegres(train_x, train_y, opts):  
  24.     # calculate training time  
  25.     startTime = time.time()  
  26.   
  27.     numSamples, numFeatures = shape(train_x)  
  28.     alpha = opts['alpha']; maxIter = opts['maxIter']  
  29.     weights = ones((numFeatures, 1))  
  30.   
  31.     # optimize through gradient descent algorilthm  
  32.     for k in range(maxIter):  
  33.         if opts['optimizeType'] == 'gradDescent'# gradient descent algorilthm  
  34.             output = sigmoid(train_x * weights)  
  35.             error = train_y - output  
  36.             weights = weights + alpha * train_x.transpose() * error  
  37.         elif opts['optimizeType'] == 'stocGradDescent'# stochastic gradient descent  
  38.             for i in range(numSamples):  
  39.                 output = sigmoid(train_x[i, :] * weights)  
  40.                 error = train_y[i, 0] - output  
  41.                 weights = weights + alpha * train_x[i, :].transpose() * error  
  42.         elif opts['optimizeType'] == 'smoothStocGradDescent'# smooth stochastic gradient descent  
  43.             # randomly select samples to optimize for reducing cycle fluctuations   
  44.             dataIndex = range(numSamples)  
  45.             for i in range(numSamples):  
  46.                 alpha = 4.0 / (1.0 + k + i) + 0.01  
  47.                 randIndex = int(random.uniform(0, len(dataIndex)))  
  48.                 output = sigmoid(train_x[randIndex, :] * weights)  
  49.                 error = train_y[randIndex, 0] - output  
  50.                 weights = weights + alpha * train_x[randIndex, :].transpose() * error  
  51.                 del(dataIndex[randIndex]) # during one interation, delete the optimized sample  
  52.         else:  
  53.             raise NameError('Not support optimize method type!')  
  54.       
  55.   
  56.     print 'Congratulations, training complete! Took %fs!' % (time.time() - startTime)  
  57.     return weights  
  58.   
  59.   
  60. # test your trained Logistic Regression model given test set  
  61. def testLogRegres(weights, test_x, test_y):  
  62.     numSamples, numFeatures = shape(test_x)  
  63.     matchCount = 0  
  64.     for i in xrange(numSamples):  
  65.         predict = sigmoid(test_x[i, :] * weights)[00] > 0.5  
  66.         if predict == bool(test_y[i, 0]):  
  67.             matchCount += 1  
  68.     accuracy = float(matchCount) / numSamples  
  69.     return accuracy  
  70.   
  71.   
  72. # show your trained logistic regression model only available with 2-D data  
  73. def showLogRegres(weights, train_x, train_y):  
  74.     # notice: train_x and train_y is mat datatype  
  75.     numSamples, numFeatures = shape(train_x)  
  76.     if numFeatures != 3:  
  77.         print "Sorry! I can not draw because the dimension of your data is not 2!"  
  78.         return 1  
  79.   
  80.     # draw all samples  
  81.     for i in xrange(numSamples):  
  82.         if int(train_y[i, 0]) == 0:  
  83.             plt.plot(train_x[i, 1], train_x[i, 2], 'or')  
  84.         elif int(train_y[i, 0]) == 1:  
  85.             plt.plot(train_x[i, 1], train_x[i, 2], 'ob')  
  86.   
  87.     # draw the classify line  
  88.     min_x = min(train_x[:, 1])[00]  
  89.     max_x = max(train_x[:, 1])[00]  
  90.     weights = weights.getA()  # convert mat to array  
  91.     y_min_x = float(-weights[0] - weights[1] * min_x) / weights[2]  
  92.     y_max_x = float(-weights[0] - weights[1] * max_x) / weights[2]  
  93.     plt.plot([min_x, max_x], [y_min_x, y_max_x], '-g')  
  94.     plt.xlabel('X1'); plt.ylabel('X2')  
  95.     plt.show()  

 

 

四、测试结果

        测试代码:

test_logRegression.py

 

[python] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #################################################  
  2. # logRegression: Logistic Regression  
  3. # Author : zouxy  
  4. # Date   : 2014-03-02  
  5. # HomePage : http://blog.csdn.net/zouxy09  
  6. # Email  : zouxy09@qq.com  
  7. #################################################  
  8.   
  9. from numpy import *  
  10. import matplotlib.pyplot as plt  
  11. import time  
  12.   
  13. def loadData():  
  14.     train_x = []  
  15.     train_y = []  
  16.     fileIn = open('E:/Python/Machine Learning in Action/testSet.txt')  
  17.     for line in fileIn.readlines():  
  18.         lineArr = line.strip().split()  
  19.         train_x.append([1.0, float(lineArr[0]), float(lineArr[1])])  
  20.         train_y.append(float(lineArr[2]))  
  21.     return mat(train_x), mat(train_y).transpose()  
  22.   
  23.   
  24. ## step 1: load data  
  25. print "step 1: load data..."  
  26. train_x, train_y = loadData()  
  27. test_x = train_x; test_y = train_y  
  28.   
  29. ## step 2: training...  
  30. print "step 2: training..."  
  31. opts = {'alpha'0.01'maxIter'20'optimizeType''smoothStocGradDescent'}  
  32. optimalWeights = trainLogRegres(train_x, train_y, opts)  
  33.   
  34. ## step 3: testing  
  35. print "step 3: testing..."  
  36. accuracy = testLogRegres(optimalWeights, test_x, test_y)  
  37.   
  38. ## step 4: show the result  
  39. print "step 4: show the result..."    
  40. print 'The classify accuracy is: %.3f%%' % (accuracy * 100)  
  41. showLogRegres(optimalWeights, train_x, train_y)   

 

 

        测试数据是二维的,共100个样本。有2个类。如下:

testSet.txt

 

[python] view plaincopy在CODE上查看代码片派生到我的代码片
  1. -0.017612   14.053064   0  
  2. -1.395634   4.662541    1  
  3. -0.752157   6.538620    0  
  4. -1.322371   7.152853    0  
  5. 0.423363    11.054677   0  
  6. 0.406704    7.067335    1  
  7. 0.667394    12.741452   0  
  8. -2.460150   6.866805    1  
  9. 0.569411    9.548755    0  
  10. -0.026632   10.427743   0  
  11. 0.850433    6.920334    1  
  12. 1.347183    13.175500   0  
  13. 1.176813    3.167020    1  
  14. -1.781871   9.097953    0  
  15. -0.566606   5.749003    1  
  16. 0.931635    1.589505    1  
  17. -0.024205   6.151823    1  
  18. -0.036453   2.690988    1  
  19. -0.196949   0.444165    1  
  20. 1.014459    5.754399    1  
  21. 1.985298    3.230619    1  
  22. -1.693453   -0.557540   1  
  23. -0.576525   11.778922   0  
  24. -0.346811   -1.678730   1  
  25. -2.124484   2.672471    1  
  26. 1.217916    9.597015    0  
  27. -0.733928   9.098687    0  
  28. -3.642001   -1.618087   1  
  29. 0.315985    3.523953    1  
  30. 1.416614    9.619232    0  
  31. -0.386323   3.989286    1  
  32. 0.556921    8.294984    1  
  33. 1.224863    11.587360   0  
  34. -1.347803   -2.406051   1  
  35. 1.196604    4.951851    1  
  36. 0.275221    9.543647    0  
  37. 0.470575    9.332488    0  
  38. -1.889567   9.542662    0  
  39. -1.527893   12.150579   0  
  40. -1.185247   11.309318   0  
  41. -0.445678   3.297303    1  
  42. 1.042222    6.105155    1  
  43. -0.618787   10.320986   0  
  44. 1.152083    0.548467    1  
  45. 0.828534    2.676045    1  
  46. -1.237728   10.549033   0  
  47. -0.683565   -2.166125   1  
  48. 0.229456    5.921938    1  
  49. -0.959885   11.555336   0  
  50. 0.492911    10.993324   0  
  51. 0.184992    8.721488    0  
  52. -0.355715   10.325976   0  
  53. -0.397822   8.058397    0  
  54. 0.824839    13.730343   0  
  55. 1.507278    5.027866    1  
  56. 0.099671    6.835839    1  
  57. -0.344008   10.717485   0  
  58. 1.785928    7.718645    1  
  59. -0.918801   11.560217   0  
  60. -0.364009   4.747300    1  
  61. -0.841722   4.119083    1  
  62. 0.490426    1.960539    1  
  63. -0.007194   9.075792    0  
  64. 0.356107    12.447863   0  
  65. 0.342578    12.281162   0  
  66. -0.810823   -1.466018   1  
  67. 2.530777    6.476801    1  
  68. 1.296683    11.607559   0  
  69. 0.475487    12.040035   0  
  70. -0.783277   11.009725   0  
  71. 0.074798    11.023650   0  
  72. -1.337472   0.468339    1  
  73. -0.102781   13.763651   0  
  74. -0.147324   2.874846    1  
  75. 0.518389    9.887035    0  
  76. 1.015399    7.571882    0  
  77. -1.658086   -0.027255   1  
  78. 1.319944    2.171228    1  
  79. 2.056216    5.019981    1  
  80. -0.851633   4.375691    1  
  81. -1.510047   6.061992    0  
  82. -1.076637   -3.181888   1  
  83. 1.821096    10.283990   0  
  84. 3.010150    8.401766    1  
  85. -1.099458   1.688274    1  
  86. -0.834872   -1.733869   1  
  87. -0.846637   3.849075    1  
  88. 1.400102    12.628781   0  
  89. 1.752842    5.468166    1  
  90. 0.078557    0.059736    1  
  91. 0.089392    -0.715300   1  
  92. 1.825662    12.693808   0  
  93. 0.197445    9.744638    0  
  94. 0.126117    0.922311    1  
  95. -0.679797   1.220530    1  
  96. 0.677983    2.556666    1  
  97. 0.761349    10.693862   0  
  98. -2.168791   0.143632    1  
  99. 1.388610    9.341997    0  
  100. 0.317029    14.739025   0  

 

         训练结果:

       (a)梯度下降算法迭代500次。(b)随机梯度下降算法迭代200次。(c)改进的随机梯度下降算法迭代20次。(d)改进的随机梯度下降算法迭代200次。

 

五、参考文献

[1] Logisticregression (逻辑回归) 概述

[2] LogisticRegression 之基础知识准备

[3] LogisticRegression

 

转载于:https://www.cnblogs.com/DjangoBlog/p/3653071.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

protected访问权限_复习封装与访问控制

java 中的封装性是通过对成员变量和方法进行访问控制实现的,访问控制分为个等级 :私有 private ;默认 ;保护 protected ;公有 public ;访问权限表控制等级 同一个类 同一个包 不同包的子包 不同包非子类 私…

html日期选择框_第十课 日期选择框(datepicker)的操作

有客户问:datepicker是怎么操作的?我答:datepicker可以直接用"输入文本"组件。客户说:不是,现在我操作的这个网页上datepicker是不能直接输入的,否则就直接用“输入文本”组件搞定,很…

E-triples II_2019牛客暑期多校训练营(第四场)

求用n个3的倍数的数按位或出数字a的方案数有多少种(0也算3的倍数) 题解 若数b的每个二进制位上的1,在a中也为1,则称b为a的子集容易知道任意个a的子集按位或出来的结果还是a的子集若问题改为按位或出来的结果是a的子集的方案数&…

SRTE测试

网络拓扑: XRV1 hostname XRV1explicit-path name SRTE index 10 next-address strict ipv4 unicast 10.10.2.2 index 20 next-address strict ipv4 unicast 10.10.3.2 index 30 next-address strict ipv4 unicast 10.10.4.1 index 40 next-address strict ipv4 un…

java笔记:自己动手写javaEE框架(七)--使用JSON和Ajax技术

今天我要将json和ajax引入到我所写的框架,不过今天用到的技术有部分不是我框架最终使用到的技术,比如ajax技术,我用到的是最为原始的ajax技术,这次算是对老技术的回顾,不过不管技术如何演进,对技术的本质的…

系统分析师成长之路

去年拿到软件设计师证书后,查了下高级认证中系统分析师,原来发现自己目前工作内容更像系统分析师(与用户调研、明确需求内容、熟悉企业数据模型、安排开发人员设计程序、牵头日常维护工作、团队人员管理)。去年底马上下决定趁热打…

python 收发邮件_python发送各类邮件的主要基本方法

利用python实现基本的邮件发送。 感谢以下博客的整理,本人在学习的同时也做了一些整理 一、相关模块介绍 发送邮件主要用到了smtplib和email两个模块,这里首先就两个模块进行一下简单的介绍: 1、smtplib模块 smtplib.SMTP([host[, port[, loc…

区分Activity的四种加载模式

在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。 这需要为Activity配置特定的加载模式,而不是使用默认的加载模…

laravel常用响应操作

转载于:https://www.cnblogs.com/saintdingspage/p/11298246.html

python中mat函数_python matplotlib中的subplot函数使用详解

python里面的matplotlib.pylot是大家比较常用的,功能也还不错的一个包。基本框架比较简单,但是做一个功能完善且比较好看整洁的图,免不了要网上查找一些函数。于是,为了节省时间,可以一劳永逸。我把常用函数作了一个总…

if else if else语句格式_你还在用if/else吗?

你还在用if/else吗?前提我们在日常开发当中经常会遇到复杂的条件判断,一般的做法是用if/else,或者优雅一点的写法是用switch语句来实现多个条件的判断,这样的话会有很多问题,随着判断条件的增加,代码中if/e…

乔梁专访——让持续交付变为可能

本月起,图灵社区陆续推出专业IT人访谈版块,首期人物是百度公司项目管理部高级架构师、《持续交付》译者乔梁。   本次访谈分三个主题:   1、 从概念和技术两个层次来解释持续交付   2、.持续交付是可实施的   3、持续交付将变成必备…

java 变量锁_并发编程高频面试题:可重入锁+线程池+内存模型等(含答案)

对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能力,更为考验一个程序员的内功。那到底应该怎么学习并发编程呢? Java SDK的并发工具包有很多,是…

element中select默认选中第一个_探索在网页中使用“标注”

github地址:https://github.com/1314mxc/yunUI ,欢迎star!说起“标注”,在HTML5之前,你可能想起的是各种浏览器插件,emmmmmmm或者说你根本不认为浏览器上可以有这种玩意。但是HTML5来了,这是它的…

佳能g3800故障灯说明书_热水器维修电话|史密斯燃气热水器出现16故障码

热水器出现故障代码其实是一件很常见的事情,大多是住户的热水器都出现过这样的问题,为了防止这样的事情也发生在我身上,我熟读热水器说明书,终于参透其中的道理,那么接下来我为大家介绍史密斯燃气热水器出现16故障码。…

git语言包安装_Git分布式版本管理系统快速入门指南

为什么要使用版本管理系统无论有没有使用过专业化工具,每个人都或多或少地有版本管理的需求。我们在做论文、写报告或者设计方案时,因为难以避免的不断改动,总会形成很多个不同的版本,我们可能会用“某某设计方案_20180910”这样加…

(十)、java内部类与内部类的闭包和回调

一、成员内部类 1.可以把一个内部类看做是一个成员。成员内部类可以无条件访问外部类的所有成员属性和成员方法。 class OutterClass {//外部类private int in 0;static int inn4;public OutterClass(int in) {this.in in;}class InnerClass { //内部类public void outpu…

vb.net中滚动条一直显示没有数据时也显示_Android Studio 中 System Trace 的新增功能...

Android Studio 中 System Trace 的新增功能在 Android Studio 4.0 中,我们已经对 CPU Profiler 的 UI 做了大量调整来提供更加直观的工作流记录,而在 Android Studio 4.1 中,我们基于开发者们的反馈对此功能进行了持续改进,并且新…

第一节 Memcached分布式缓存入门

关于Memcached的博文太多了,以下是个人学习的收集整理。 本节讨论问题: 简单介绍与应用下载安装注意事项简单测试Memcached分布式原理 一、介绍与应用 在常规的WEB开发下,基本都会利用到缓存用以降低对数据库的压力,提高访问速度。有时候缓存…

tomcat 拦截指定url_一口气说出 过滤器 和 拦截器 6个区别,别再傻傻分不清了

点击“ 程序员内点事 ”关注,选择“ 设置星标 ”坚持学习,好文每日送达!周末有个小伙伴加我微信,向我请教了一个问题:老哥,「过滤器 (Filter) 和 拦截器 (Interceptor) 有啥区别啊?」 听到题目我…