Logistic回归:牛顿迭代法

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

Logistic回归与牛顿迭代法

很早之前介绍过《无约束的最优方法》里面介绍了梯度下降法和牛顿迭代法等优化算法。

同时大家对于Logistic回归中的梯度下降法更为熟悉,而牛顿迭代法对数学要求更高,所以这里介绍如何在Logistic回归问题中使用牛顿迭代法。

似然函数与代价函数

似然函数则是

L(ω)=Πmi=1[g(xi)]yi[1g(xi)]1yi

然后我们的目标是求出使这一似然函数的值最大的参数,最大似然估计就是求出参数.

对上式两边取log或者ln就可以得到熟悉的代价函数了。

lnL(ω)=i=1m[yiln(g(xi))+(1yi)(1g(xi))]=i=1m(yi·lnexiexi+1+(1yi)·ln1exi+1)=i=1m(xiyiln(1+exi))

其中 xi=ω0+ω1xi1+ω2xi2+...+ωnxin 。现在求向量 ω=(ω0,ω1,ω2,...,ωn) 使得 L(ω)

偏导函数为

ln(L(ω))ωk=i=1mxik[yig(xi)]

这是一个多元函数,变元就是 ω0ωn ,在之前的文章中有如何用牛顿迭代法求解多元函数的极值。

Hessian矩阵

极值点的导数一定为零,所以我们可以列出n+1个方程,联立解出所有的参数 ω0ωn

首先,用Hessian矩阵判断极值的存在性,方程组如下:

ln(L(ω))ω0=i=1mxi0[yig(xi)]=0

ln(L(ω))ω1=i=1mxi1[yig(xi)]=0

ln(L(ω))ω2=i=1mxi2[yig(xi)]=0


ln(L(ω))ωn=i=1mxin[yig(xi)]=0

这一共是 n1 个方程,现在的问题变为如何解这个方程组。求Hessian矩阵就得先求二阶偏导,即

2ln(L(ω))ωkωr=(mi=1xin[yig(xi)])ωr=i=1mxik(exi1+exi)i=1mxikexixi(1+exi)e2xixi(1+exi)2=i=1mxikxirg(xi)[g(xi)1]==i=1mxikg(xi)[g(xi)1]xir

用Hessian矩阵表示为

所以得到Hessian矩阵 H=XTAX ,因为 0<g(xi)<1 ,矩阵A是负定的,那么现在证明H也是负定的。

证明:
设任意的 V n维向量,因为A是负定的,那么 (XV)TA(XV) 为二次型,也是负定的,那么

(XV)TA(XV)=VTXTAXV0

所以 H=XTAX 也是负定的。

Hessian矩阵是负定的,也就是说多元函数存在局部极大值,这符合开始需求的最大似然估计。

牛顿迭代法

对于Logistic回归问题,Hessian矩阵对于任意数据都是负定的,所以说极值点只有一个,初始点选取无关紧要。
可以得到如下迭代式子

其中H为Hessian矩阵,而U的表示如下

由于Hessian矩阵H是对称负定的,将矩阵A提取一个负号出来,得到

则Hessian矩阵H就变成了 H=XTAX ,则 H 就是对称正定,则牛顿迭代法公式变成:

现在的重点是如何快速并有效计算 H1U ,即解方程组,通常的做法是直接用高斯消元法求解,
但是这样做有弊端,弊端有两个:

  1. 效率低
  2. 数值稳定性差

由于 H 是对称正定的,可以用Cholesky矩阵分解法来解。

/*****************************************************************************/  
/* Name: matrix.h                                                            */  
/* Uses: Class for matrix math functions.                                    */  
/* Date: 4/19/2011                                                           */  
/* Author: Andrew Que <http://www.DrQue.net/>                                */  
/* Revisions:                                                                */  
/*   0.1 - 2011/04/19 - QUE - Creation.                                      */  
/*   0.5 - 2011/04/24 - QUE - Most functions are complete.                   */  
/*   0.8 - 2011/05/01 - QUE -                                                */  
/*     = Bug fixes.                                                          */  
/*     + Dot product.                                                        */  
/*   1.0 - 2011/11/26 - QUE - Release.                                       */  
/*                                                                           */  
/* Notes:                                                                    */  
/*   This unit implements some very basic matrix functions, which include:   */  
/*    + Addition/subtraction                                                 */  
/*    + Transpose                                                            */  
/*    + Row echelon reduction                                                */  
/*    + Determinant                                                          */  
/*    + Dot product                                                          */  
/*    + Matrix product                                                       */  
/*    + Scalar product                                                       */  
/*    + Inversion                                                            */  
/*    + LU factorization/decomposition                                       */  
/*     There isn't much for optimization in this unit as it was designed as  */  
/*   more of a learning experience.                                          */  
/*                                                                           */  
/* License:                                                                  */  
/*   This program is free software: you can redistribute it and/or modify    */  
/*   it under the terms of the GNU General Public License as published by    */  
/*   the Free Software Foundation, either version 3 of the License, or       */  
/*   (at your option) any later version.                                     */  
/*                                                                           */  
/*   This program is distributed in the hope that it will be useful,         */  
/*   but WITHOUT ANY WARRANTY; without even the implied warranty of          */  
/*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           */  
/*   GNU General Public License for more details.                            */  
/*                                                                           */  
/*   You should have received a copy of the GNU General Public License       */  
/*   along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  
/*                                                                           */  
/*                     (C) Copyright 2011 by Andrew Que                      */  
/*                           http://www.DrQue.net/                           */  
/*****************************************************************************/  
#ifndef _MATRIX_H_  
#define _MATRIX_H_  

#include <iostream>  
#include <cassert>  
#include <climits>  
#include <vector>  

// Class forward for identity matrix.  
template< class TYPE > class IdentityMatrix;  

//=============================================================================  
// Matrix template class  
//   Contains a set of matrix manipulation functions.  The template is designed  
// so that the values of the matrix can be of any type that allows basic  
// arithmetic.  
//=============================================================================  
template< class TYPE = int >  
  class Matrix  
  {  
    protected:  
      // Matrix data.  
      unsigned rows;  
      unsigned columns;  

      // Storage for matrix data.  
      std::vector< std::vector< TYPE > > matrix;  

      // Order sub-index for rows.  
      //   Use: matrix[ order[ row ] ][ column ].  
      unsigned * order;  

      //-------------------------------------------------------------  
      // Return the number of leading zeros in the given row.  
      //-------------------------------------------------------------  
      unsigned getLeadingZeros  
      (  
        // Row to count  
        unsigned row  
      ) const  
      {  
        TYPE const ZERO = static_cast< TYPE >( 0 );  
        unsigned column = 0;  
        while ( ZERO == matrix[ row ][ column ] )  
          ++column;  

        return column;  
      }  

      //-------------------------------------------------------------  
      // Reorder the matrix so the rows with the most zeros are at  
      // the end, and those with the least at the beginning.  
      //  
      // NOTE: The matrix data itself is not manipulated, just the  
      // 'order' sub-indexes.  
      //-------------------------------------------------------------  
      void reorder()  
      {  
        unsigned * zeros = new unsigned[ rows ];  

        for ( unsigned row = 0; row < rows; ++row )  
        {  
          order[ row ] = row;  
          zeros[ row ] = getLeadingZeros( row );  
        }  

        for ( unsigned row = 0; row < (rows-1); ++row )  
        {  
          unsigned swapRow = row;  
          for ( unsigned subRow = row + 1; subRow < rows; ++subRow )  
          {  
            if ( zeros[ order[ subRow ] ] < zeros[ order[ swapRow ] ] )  
              swapRow = subRow;  
          }  

          unsigned hold    = order[ row ];  
          order[ row ]     = order[ swapRow ];  
          order[ swapRow ] = hold;  
        }  

        delete zeros;  
      }  

      //-------------------------------------------------------------  
      // Divide a row by given value.  An elementary row operation.  
      //-------------------------------------------------------------  
      void divideRow  
      (  
        // Row to divide.  
        unsigned row,  

        // Divisor.  
        TYPE const & divisor  
      )  
      {  
        for ( unsigned column = 0; column < columns; ++column )  
          matrix[ row ][ column ] /= divisor;  
      }  

      //-------------------------------------------------------------  
      // Modify a row by adding a scaled row. An elementary row  
      // operation.  
      //-------------------------------------------------------------  
      void rowOperation  
      (  
        unsigned row,  
        unsigned addRow,  
        TYPE const & scale  
      )  
      {  
        for ( unsigned column = 0; column < columns; ++column )  
          matrix[ row ][ column ] += matrix[ addRow ][ column ] * scale;  
      }  

      //-------------------------------------------------------------  
      // Allocate memory for matrix data.  
      //-------------------------------------------------------------  
      void allocate  
      (  
        unsigned rowNumber,  
        unsigned columnNumber  
      )  
      {  
        // Allocate order integers.  
        order = new unsigned[ rowNumber ];  

        // Setup matrix sizes.  
        matrix.resize( rowNumber );  
        for ( unsigned row = 0; row < rowNumber; ++row )  
          matrix[ row ].resize( columnNumber );  
      }  

      //-------------------------------------------------------------  
      // Free memory used for matrix data.  
      //-------------------------------------------------------------  
      void deallocate  
      (  
        unsigned rowNumber,  
        unsigned columnNumber  
      )  
      {  
        // Free memory used for storing order (if there is any).  
        if ( 0 != rowNumber )  
          delete[] order;  
      }  

    public:  
      // Used for matrix concatenation.  
      typedef enum  
      {  
        TO_RIGHT,  
        TO_BOTTOM  
      } Position;  

      //-------------------------------------------------------------  
      // Return the number of rows in this matrix.  
      //-------------------------------------------------------------  
      unsigned getRows() const  
      {  
        return rows;  
      }  

      //-------------------------------------------------------------  
      // Return the number of columns in this matrix.  
      //-------------------------------------------------------------  
      unsigned getColumns() const  
      {  
        return columns;  
      }  

      //-------------------------------------------------------------  
      // Get an element of the matrix.  
      //-------------------------------------------------------------  
      TYPE get  
      (  
        unsigned row,   // Which row.  
        unsigned column // Which column.  
      ) const  
      {  
        assert( row < rows );  
        assert( column < columns );  

        return matrix[ row ][ column ];  
      }  

      //-------------------------------------------------------------  
      // Proform LU decomposition.  
      // This will create matrices L and U such that A=LxU  
      //-------------------------------------------------------------  
      void LU_Decomposition  
      (  
        Matrix & upper,  
        Matrix & lower  
      ) const  
      {  
        assert( rows == columns );  

        TYPE const ZERO = static_cast< TYPE >( 0 );  

        upper = *this;  
        lower = *this;  

        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
            lower.matrix[ row ][ column ] = ZERO;  

        for ( unsigned row = 0; row < rows; ++row )  
        {  
          TYPE value = upper.matrix[ row ][ row ];  
          if ( ZERO != value )  
          {  
            upper.divideRow( row, value );  
            lower.matrix[ row ][ row ] = value;  
          }  

          for ( unsigned subRow = row + 1; subRow < rows; ++subRow )  
          {  
            TYPE value = upper.matrix[ subRow ][ row ];  
            upper.rowOperation( subRow, row, -value );  
            lower.matrix[ subRow ][ row ] = value;  
          }  
        }  
      }  

      //-------------------------------------------------------------  
      // Set an element in the matrix.  
      //-------------------------------------------------------------  
      void put  
      (  
        unsigned row,  
        unsigned column,  
        TYPE const & value  
      )  
      {  
        assert( row < rows );  
        assert( column < columns );  

        matrix[ row ][ column ] = value;  
      }  

      //-------------------------------------------------------------  
      // Return part of the matrix.  
      // NOTE: The end points are the last elements copied.  They can  
      // be equal to the first element when wanting just a single row  
      // or column.  However, the span of the total matrix is  
      // ( 0, rows - 1, 0, columns - 1 ).  
      //-------------------------------------------------------------  
      Matrix getSubMatrix  
      (  
        unsigned startRow,  
        unsigned endRow,  
        unsigned startColumn,  
        unsigned endColumn,  
        unsigned const * newOrder = NULL  
      )  
      {  
        Matrix subMatrix( endRow - startRow + 1, endColumn - startColumn + 1 );  

        for ( unsigned row = startRow; row <= endRow; ++row )  
        {  
          unsigned subRow;  
          if ( NULL == newOrder )  
            subRow = row;  
          else  
            subRow = newOrder[ row ];  

          for ( unsigned column = startColumn; column <= endColumn; ++column )  
            subMatrix.matrix[ row - startRow ][ column - startColumn ] =  
              matrix[ subRow ][ column ];  
        }  

        return subMatrix;  
      }  

      //-------------------------------------------------------------  
      // Return a single column from the matrix.  
      //-------------------------------------------------------------  
      Matrix getColumn  
      (  
        unsigned column  
      )  
      {  
        return getSubMatrix( 0, rows - 1, column, column );  
      }  

      //-------------------------------------------------------------  
      // Return a single row from the matrix.  
      //-------------------------------------------------------------  
      Matrix getRow  
      (  
        unsigned row  
      )  
      {  
        return getSubMatrix( row, row, 0, columns - 1 );  
      }  

      //-------------------------------------------------------------  
      // Place matrix in reduced row echelon form.  
      //-------------------------------------------------------------  
      void reducedRowEcholon()  
      {  
        TYPE const ZERO = static_cast< TYPE >( 0 );  

        // For each row...  
        for ( unsigned rowIndex = 0; rowIndex < rows; ++rowIndex )  
        {  
          // Reorder the rows.  
          reorder();  

          unsigned row = order[ rowIndex ];  

          // Divide row down so first term is 1.  
          unsigned column = getLeadingZeros( row );  
          TYPE divisor = matrix[ row ][ column ];  
          if ( ZERO != divisor )  
          {  
            divideRow( row, divisor );  

            // Subtract this row from all subsequent rows.  
            for ( unsigned subRowIndex = ( rowIndex + 1 ); subRowIndex < rows; ++subRowIndex )  
            {  
              unsigned subRow = order[ subRowIndex ];  
              if ( ZERO != matrix[ subRow ][ column ] )  
                rowOperation  
                (  
                  subRow,  
                  row,  
                  -matrix[ subRow ][ column ]  
                );  
            }  
          }  

        }  

        // Back substitute all lower rows.  
        for ( unsigned rowIndex = ( rows - 1 ); rowIndex > 0; --rowIndex )  
        {  
          unsigned row = order[ rowIndex ];  
          unsigned column = getLeadingZeros( row );  
          for ( unsigned subRowIndex = 0; subRowIndex < rowIndex; ++subRowIndex )  
          {  
            unsigned subRow = order[ subRowIndex ];  
            rowOperation  
            (  
              subRow,  
              row,  
              -matrix[ subRow ][ column ]  
            );  
          }  
        }  

      } // reducedRowEcholon  

      //-------------------------------------------------------------  
      // Return the determinant of the matrix.  
      // Recursive function.  
      //-------------------------------------------------------------  
      TYPE determinant() const  
      {  
        TYPE result = static_cast< TYPE >( 0 );  

        // Must have a square matrix to even bother.  
        assert( rows == columns );  

        if ( rows > 2 )  
        {  
          int sign = 1;  
          for ( unsigned column = 0; column < columns; ++column )  
          {  
            TYPE subDeterminant;  

            Matrix subMatrix = Matrix( *this, 0, column );  

            subDeterminant  = subMatrix.determinant();  
            subDeterminant *= matrix[ 0 ][ column ];  

            if ( sign > 0 )  
              result += subDeterminant;  
            else  
              result -= subDeterminant;  

            sign = -sign;  
          }  
        }  
        else  
        {  
          result = ( matrix[ 0 ][ 0 ] * matrix[ 1 ][ 1 ] )  
                 - ( matrix[ 0 ][ 1 ] * matrix[ 1 ][ 0 ] );  
        }  

        return result;  

      } // determinant  

      //-------------------------------------------------------------  
      // Calculate a dot product between this and an other matrix.  
      //-------------------------------------------------------------  
      TYPE dotProduct  
      (  
        Matrix const & otherMatrix  
      ) const  
      {  
        // Dimentions of each matrix must be the same.  
        assert( rows == otherMatrix.rows );  
        assert( columns == otherMatrix.columns );  

        TYPE result = static_cast< TYPE >( 0 );  
        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
          {  
            result +=  
              matrix[ row ][ column ]  
              * otherMatrix.matrix[ row ][ column ];  
          }  

        return result;  

      } // dotProduct  

      //-------------------------------------------------------------  
      // Return the transpose of the matrix.  
      //-------------------------------------------------------------  
      Matrix const getTranspose() const  
      {  
        Matrix result( columns, rows );  

        // Transpose the matrix by filling the result's rows will  
        // these columns, and vica versa.  
        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
            result.matrix[ column ][ row ] = matrix[ row ][ column ];  

        return result;  

      } // transpose  

      //-------------------------------------------------------------  
      // Transpose the matrix.  
      //-------------------------------------------------------------  
      void transpose()  
      {  
        *this = getTranspose();  
      }  

      //-------------------------------------------------------------  
      // Return inverse matrix.  
      //-------------------------------------------------------------  
      Matrix const getInverse() const  
      {  
        // Concatenate the identity matrix onto this matrix.  
        Matrix inverseMatrix  
          (  
            *this,  
            IdentityMatrix< TYPE >( rows, columns ),  
            TO_RIGHT  
          );  

        // Row reduce this matrix.  This will result in the identity  
        // matrix on the left, and the inverse matrix on the right.  
        inverseMatrix.reducedRowEcholon();  

        // Copy the inverse matrix data back to this matrix.  
        Matrix result  
        (  
          inverseMatrix.getSubMatrix  
          (  
            0,  
            rows - 1,  
            columns,  
            columns + columns - 1,  
            inverseMatrix.order  
          )  
        );  

        return result;  

      } // invert  


      //-------------------------------------------------------------  
      // Invert this matrix.  
      //-------------------------------------------------------------  
      void invert()  
      {  
        *this = getInverse();  

      } // invert  

      //=======================================================================  
      // Operators.  
      //=======================================================================  

      //-------------------------------------------------------------  
      // Add by an other matrix.  
      //-------------------------------------------------------------  
      Matrix const operator +  
      (  
        Matrix const & otherMatrix  
      ) const  
      {  
        assert( otherMatrix.rows == rows );  
        assert( otherMatrix.columns == columns );  

        Matrix result( rows, columns );  

        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
            result.matrix[ row ][ column ] =  
              matrix[ row ][ column ]  
              + otherMatrix.matrix[ row ][ column ];  

        return result;  
      }  

      //-------------------------------------------------------------  
      // Add self by an other matrix.  
      //-------------------------------------------------------------  
      Matrix const & operator +=  
      (  
        Matrix const & otherMatrix  
      )  
      {  
        *this = *this + otherMatrix;  
        return *this;  
      }  

      //-------------------------------------------------------------  
      // Subtract by an other matrix.  
      //-------------------------------------------------------------  
      Matrix const operator -  
      (  
        Matrix const & otherMatrix  
      ) const  
      {  
        assert( otherMatrix.rows == rows );  
        assert( otherMatrix.columns == columns );  

        Matrix result( rows, columns );  

        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
            result.matrix[ row ][ column ] =  
              matrix[ row ][ column ]  
              - otherMatrix.matrix[ row ][ column ];  

        return result;  
      }  

      //-------------------------------------------------------------  
      // Subtract self by an other matrix.  
      //-------------------------------------------------------------  
      Matrix const & operator -=  
      (  
        Matrix const & otherMatrix  
      )  
      {  
        *this = *this - otherMatrix;  
        return *this;  
      }  

      //-------------------------------------------------------------  
      // Matrix multiplication.  
      //-------------------------------------------------------------  
      Matrix const operator *  
      (  
        Matrix const & otherMatrix  
      ) const  
      {  
        TYPE const ZERO = static_cast< TYPE >( 0 );  

        assert( otherMatrix.rows == columns );  

        Matrix result( rows, otherMatrix.columns );  

        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < otherMatrix.columns; ++column )  
          {  
            result.matrix[ row ][ column ] = ZERO;  

            for ( unsigned index = 0; index < columns; ++index )  
              result.matrix[ row ][ column ] +=  
                matrix[ row ][ index ]  
                * otherMatrix.matrix[ index ][ column ];  
          }  

        return result;  
      }  

      //-------------------------------------------------------------  
      // Multiply self by matrix.  
      //-------------------------------------------------------------  
      Matrix const & operator *=  
      (  
        Matrix const & otherMatrix  
      )  
      {  
        *this = *this * otherMatrix;  
        return *this;  
      }  

      //-------------------------------------------------------------  
      // Multiply by scalar constant.  
      //-------------------------------------------------------------  
      Matrix const operator *  
      (  
        TYPE const & scalar  
      ) const  
      {  
        Matrix result( rows, columns );  

        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
            result.matrix[ row ][ column ] = matrix[ row ][ column ] * scalar;  

        return result;  
      }  

      //-------------------------------------------------------------  
      // Multiply self by scalar constant.  
      //-------------------------------------------------------------  
      Matrix const & operator *=  
      (  
        TYPE const & scalar  
      )  
      {  
        *this = *this * scalar;  
        return *this;  
      }  

      //-------------------------------------------------------------  
      // Copy matrix.  
      //-------------------------------------------------------------  
      Matrix & operator =  
      (  
        Matrix const & otherMatrix  
      )  
      {  
        if ( this == &otherMatrix )  
          return *this;  

        // Release memory currently in use.  
        deallocate( rows, columns );  

        rows    = otherMatrix.rows;  
        columns = otherMatrix.columns;  
        allocate( rows, columns );  

        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
            matrix[ row ][ column ] =  
            otherMatrix.matrix[ row ][ column ];  

        return *this;  
      }  

      //-------------------------------------------------------------  
      // Copy matrix data from array.  
      // Although matrix data is two dimensional, this copy function  
      // assumes the previous row is immediately followed by the next  
      // row's data.  
      //  
      // Example for 3x2 matrix:  
      //     int const data[ 3 * 2 ] =  
      //     {  
      //       1, 2, 3,  
      //       4, 5, 6  
      //     };  
      //    Matrix< int > matrix( 3, 2 );  
      //    matrix = data;  
      //-------------------------------------------------------------  
      Matrix & operator =  
      (  
        TYPE const * data  
      )  
      {  
        unsigned index = 0;  

        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
            matrix[ row ][ column ] = data[ index++ ];  

        return *this;  
      }  

      //-----------------------------------------------------------------------  
      // Return true if this matrix is the same of parameter.  
      //-----------------------------------------------------------------------  
      bool operator ==  
      (  
        Matrix const & value  
      ) const  
      {  
        bool isEqual = true;  
        for ( unsigned row = 0; row < rows; ++row )  
          for ( unsigned column = 0; column < columns; ++column )  
            if ( matrix[ row ][ column ] != value.matrix[ row ][ column ] )  
              isEqual = false;  

        return isEqual;  
      }  

      //-----------------------------------------------------------------------  
      // Return true if this matrix is NOT the same of parameter.  
      //-----------------------------------------------------------------------  
      bool operator !=  
      (  
        Matrix const & value  
      ) const  
      {  
        return !( *this == value );  
      }  

      //-------------------------------------------------------------  
      // Constructor for empty matrix.  
      // Only useful if matrix is being assigned (i.e. copied) from  
      // somewhere else sometime after construction.  
      //-------------------------------------------------------------  
      Matrix()  
      :  
        rows( 0 ),  
        columns( 0 )  
      {  
        allocate( 0, 0 );  
      }  

      //-------------------------------------------------------------  
      // Constructor using rows and columns.  
      //-------------------------------------------------------------  
      Matrix  
      (  
        unsigned rowsParameter,  
        unsigned columnsParameter  
      )  
      :  
        rows( rowsParameter ),  
        columns( columnsParameter )  
      {  
        TYPE const ZERO = static_cast< TYPE >( 0 );  

        // Allocate memory for new matrix.  
        allocate( rows, columns );  

        // Fill matrix with zero.  
        for ( unsigned row = 0; row < rows; ++row )  
        {  
          order[ row ] = row;  

          for ( unsigned column = 0; column < columns; ++column )  
            matrix[ row ][ column ] = ZERO;  
        }  
      }  

      //-------------------------------------------------------------  
      // This constructor will allow the creation of a matrix based off  
      // an other matrix.  It can copy the matrix entirely, or omitted a  
      // row/column.  
      //-------------------------------------------------------------  
      Matrix  
      (  
        Matrix const & copyMatrix,  
        unsigned omittedRow    = INT_MAX,  
        unsigned omittedColumn = INT_MAX  
      )  
      {  
        // Start with the number of rows/columns from matrix to be copied.  
        rows    = copyMatrix.getRows();  
        columns = copyMatrix.getColumns();  

        // If a row is omitted, then there is one less row.  
        if ( INT_MAX != omittedRow  )  
          rows--;  

        // If a column is omitted, then there is one less column.  
        if ( INT_MAX != omittedColumn )  
          columns--;  

        // Allocate memory for new matrix.  
        allocate( rows, columns );  

        unsigned rowIndex = 0;  
        for ( unsigned row = 0; row < rows; ++row )  
        {  
          // If this row is to be skipped...  
          if ( rowIndex == omittedRow )  
            rowIndex++;  

          // Set default order.  
          order[ row ] = row;  

          unsigned columnIndex = 0;  
          for ( unsigned column = 0; column < columns; ++column )  
          {  
            // If this column is to be skipped...  
            if ( columnIndex == omittedColumn )  
              columnIndex++;  

            matrix[ row ][ column ] = copyMatrix.matrix[ rowIndex ][ columnIndex ];  

            columnIndex++;  
          }  

          ++rowIndex;  
        }  

      }  

      //-------------------------------------------------------------  
      // Constructor to concatenate two matrices.  Concatenation  
      // can be done to the right, or to the bottom.  
      //   A = [B | C]  
      //-------------------------------------------------------------  
      Matrix  
      (  
        Matrix const & copyMatrixA,  
        Matrix const & copyMatrixB,  
        Position position = TO_RIGHT  
      )  
      {  
        unsigned rowOffset    = 0;  
        unsigned columnOffset = 0;  

        if ( TO_RIGHT == position )  
          columnOffset = copyMatrixA.columns;  
        else  
          rowOffset = copyMatrixA.rows;  

        rows    = copyMatrixA.rows    + rowOffset;  
        columns = copyMatrixA.columns + columnOffset;  

        // Allocate memory for new matrix.  
        allocate( rows, columns );  

        for ( unsigned row = 0; row < copyMatrixA.rows; ++row )  
          for ( unsigned column = 0; column < copyMatrixA.columns; ++column )  
            matrix[ row ][ column ] = copyMatrixA.matrix[ row ][ column ];  

        for ( unsigned row = 0; row < copyMatrixB.rows; ++row )  
          for ( unsigned column = 0; column < copyMatrixB.columns; ++column )  
            matrix[ row + rowOffset ][ column + columnOffset ] =  
              copyMatrixB.matrix[ row ][ column ];  
      }  

      //-------------------------------------------------------------  
      // Destructor.  
      //-------------------------------------------------------------  
      ~Matrix()  
      {  
        // Release memory.  
        deallocate( rows, columns );  
      }  

  };  

//=============================================================================  
// Class for identity matrix.  
//=============================================================================  
template< class TYPE >  
  class IdentityMatrix : public Matrix< TYPE >  
  {  
    public:  
      IdentityMatrix  
      (  
        unsigned rowsParameter,  
        unsigned columnsParameter  
      )  
      :  
        Matrix< TYPE >( rowsParameter, columnsParameter )  
      {  
        TYPE const ZERO = static_cast< TYPE >( 0 );  
        TYPE const ONE  = static_cast< TYPE >( 1 );  

        for ( unsigned row = 0; row < Matrix< TYPE >::rows; ++row )  
        {  
          for ( unsigned column = 0; column < Matrix< TYPE >::columns; ++column )  
            if ( row == column )  
              Matrix< TYPE >::matrix[ row ][ column ] = ONE;  
            else  
              Matrix< TYPE >::matrix[ row ][ column ] = ZERO;  
        }  
      }  
  };  

//-----------------------------------------------------------------------------  
// Stream operator used to convert matrix class to a string.  
//-----------------------------------------------------------------------------  
template< class TYPE >  
  std::ostream & operator<<  
  (  
    // Stream data to place string.  
    std::ostream & stream,  

    // A matrix.  
    Matrix< TYPE > const & matrix  
  )  
  {  
    for ( unsigned row = 0; row < matrix.getRows(); ++row )  
    {  
      for ( unsigned column = 0; column < matrix.getColumns(); ++column )  
        stream << "\t" << matrix.get( row , column );  

      stream << std::endl;  
    }  

    return stream;  
  }  

#endif // _MATRIX_H_  
#include <string.h>  
#include <fstream>  
#include <stdio.h>  
#include <math.h>  

#include "matrix.h"  
#define Type double  
#define Vector vector  

using namespace std;  

/** 定义数据集结构体 */  
struct Data  
{  
    Vector<Type> x;  
    Type y;  
};  

/** 预处理数据给data */  
void PreProcessData(Vector<Data>& data, string path)  
{  
    string filename = path;  
    ifstream file(filename.c_str());  
    char s[1024];  
    if(file.is_open())  
    {  
        while(file.getline(s, 1024))  
        {  
            Data tmp;  
            Type x1, x2, x3, x4, x5, x6, x7;  
            sscanf(s,"%lf %lf %lf %lf %lf %lf %lf", &x1, &x2, &x3, &x4, &x5, &x6, &x7);  
            tmp.x.push_back(1);  
            tmp.x.push_back(x2);  
            tmp.x.push_back(x3);  
            tmp.x.push_back(x4);  
            tmp.x.push_back(x5);  
            tmp.x.push_back(x6);  
            tmp.y = x7;  
            data.push_back(tmp);  
        }  
    }  
}  

void Init(Vector<Data> &data, Vector<Type> &w)  
{  
    w.clear();  
    data.clear();  
    PreProcessData(data, "TrainData.txt");  
    for(int i = 0; i < data[0].x.size(); i++)  
        w.push_back(0);  
}  

Type WX(const Vector<Type>& w, const Data& data)  
{  
    Type ans = 0;  
    for(int i = 0; i < w.size(); i++)  
        ans += w[i] * data.x[i];  
    return ans;  
}  

Type Sigmoid(const Vector<Type>& w, const Data& data)  
{  
    Type x = WX(w, data);  
    Type ans = exp(x) / (1 + exp(x));  
    return ans;  
}  

void PreMatrix(Matrix<Type> &H, Matrix<Type> &U, const Vector<Data> &data, Vector<Type> &w)  
{  
    int ROWS = data[0].x.size();  
    int COLS = data.size();  
    Matrix<Type> A(COLS, COLS), P(ROWS, COLS), Q(COLS, 1), X(COLS, ROWS);  
    for(int i = 0; i < COLS; i++)  
    {  
        Type t = Sigmoid(w, data[i]);  
        A.put(i, i, t *(1 - t));  
        Q.put(i, 0, data[i].y - t);  
    }  
    for(int i = 0; i < ROWS; i++)  
    {  
        for(int j = 0; j < COLS; j++)  
            P.put(i, j, data[j].x[i]);  
    }  
    X = P.getTranspose();  

    /** 计算矩阵U和矩阵H的值 */  
    U = P * Q;  
    H = X.getTranspose() * A * X;  
}  

Vector<Type> Matrix2Vector(Matrix<Type> &M)  
{  
    Vector<Type> X;  
    X.clear();  
    int ROWS = M.getRows();  
    for(int i = 0; i < ROWS; i++)  
        X.push_back(M.get(i, 0));  
    return X;  
}  

Matrix<Type> Vector2Matrix(Vector<Type> &X)  
{  
    int ROWS = X.size();  
    Matrix<Type> matrix(ROWS, 1);  
    for(int i = 0; i < ROWS; i++)  
        matrix.put(i, 0, X[i]);  
    return matrix;  
}  

/** Cholesky分解得到矩阵L和矩阵D */  
void Cholesky(Matrix<Type> &H, Matrix<Type> &L, Matrix<Type> &D)  
{  
    Type t = 0;  
    int n = H.getRows();  
    for(int k = 0; k < n; k++)  
    {  
        for(int i = 0; i < k; i++)  
        {  
            t = H.get(i, i) * H.get(k, i) * H.get(k, i);  
            H.put(k, k, H.get(k, k) - t);  
        }  
        for(int j = k + 1; j < n; j++)  
        {  
            for(int i = 0; i < k; i++)  
            {  
                t = H.get(j, i) * H.get(i, i) * H.get(k, i);  
                H.put(j, k, H.get(j, k) - t);  
            }  
            t = H.get(j, k) / H.get(k, k);  
            H.put(j, k, t);  
        }  
    }  
    for(int i = 0; i < n; i++)  
    {  
        D.put(i, i, H.get(i, i));  
        L.put(i, i, 1);  
        for(int j = 0; j < i; j++)  
            L.put(i, j, H.get(i, j));  
    }  
}  

/** 回带求出线性方程组的解 */  
void Solve(Matrix<Type> &H, Vector<Type> &X)  
{  
    int ROWS = H.getRows();  
    int COLS = H.getColumns();  
    Matrix<Type> L(ROWS, COLS), D(ROWS, COLS);  
    Cholesky(H, L, D);  

    int n = ROWS;  
    for(int k = 0; k < n; k++)  
    {  
        for(int i = 0; i < k; i++)  
            X[k] -= X[i] * L.get(k, i);  
        X[k] /= L.get(k, k);  
    }  
    L = D * L.getTranspose();  
    for(int k = n - 1; k >= 0; k--)  
    {  
        for(int i = k + 1; i < n; i++)  
            X[k] -= X[i] * L.get(k, i);  
        X[k] /= L.get(k, k);  
    }  
}  

/** 打印迭代步骤 */  
void Display(int cnt, Type error, Vector<Type> w)  
{  
    cout<<"第"<<cnt<<"次迭代前后的目标差为: "<<error<<endl;  
    cout<<"参数w为: ";  
    for(int i = 0; i < w.size(); i++)  
        cout<<w[i]<<" ";  
    cout<<endl;  
    cout<<endl;  
}  

Type StopFlag(Vector<Type> w1, Vector<Type> w2)  
{  
    Type ans = 0;  
    int size = w1.size();  
    for(int i = 0; i < size; i++)  
        ans += 0.5 * (w1[i] - w2[i]) * (w1[i] - w2[i]);  
    return ans;  
}  

/** 牛顿迭代步骤 */  
void NewtonIter(Vector<Data> &data, Vector<Type> &w)  
{  
    int cnt = 0;  
    Type delta = 0.0001;  
    int ROWS = data[0].x.size();  
    int COLS = data.size();  

    while(1)  
    {  
        Matrix<Type> H(ROWS, ROWS), U(ROWS, 1), W(ROWS, 1);  
        PreMatrix(H, U, data, w);  
        Vector<Type> X = Matrix2Vector(U);  
        Solve(H, X);  
        Matrix<Type> x = Vector2Matrix(X);  
        W = Vector2Matrix(w);  
        W += x;  
        Vector<Type> _w = Matrix2Vector(W);  
        Type error = StopFlag(_w, w);  
        w = _w;  
        cnt++;  
        Display(cnt, error, w);  
        if(error < delta) break;  
    }  
}  

/** 训练数据得到w数组,构造分类器 */  
void TrainData(Vector<Data> &data, Vector<Type> &w)  
{  
    Init(data, w);  
    NewtonIter(data, w);  
}  

/** 根据构造好的分类器对数据进行分类 */  
void Separator(Vector<Type> w)  
{  
    vector<Data> data;  
    PreProcessData(data, "TestData.txt");  
    cout<<"预测分类结果:"<<endl;  
    for(int i = 0; i < data.size(); i++)  
    {  
        Type p0 = 0;  
        Type p1 = 0;  
        Type x = WX(w, data[i]);  
        p1 = exp(x) / (1 + exp(x));  
        p0 = 1 - p1;  
        cout<<"实例: ";  
        for(int j = 0; j < data[i].x.size(); j++)  
            cout<<data[i].x[j]<<" ";  
        cout<<"所属类别为:";  
        if(p1 >= p0) cout<<1<<endl;  
        else cout<<0<<endl;  
    }  
}  

int main()  
{  
    Vector<Type> w;  
    Vector<Data> data;  
    TrainData(data, w);  
    Separator(w);  
    return 0;  
}  

训练数据

1 0 0 1 0 1
0 0 1 2 0 0
1 0 0 1 1 0
0 0 0 0 1 0
0 0 1 0 0 0
0 0 1 0 1 0
0 0 1 2 1 0
1 0 0 0 0 0
0 0 1 0 1 0
1 0 1 0 0 0
0 0 1 0 1 0
0 0 1 0 0 0
0 0 1 0 1 0
1 0 0 1 0 0
1 0 0 0 1 0
2 0 0 0 1 0
1 0 0 2 1 0
2 0 0 0 1 0
2 0 1 0 0 0
0 0 1 0 1 0
0 0 1 2 0 0
0 0 0 0 0 0
0 0 1 0 1 0
1 0 1 0 1 1
0 0 1 2 1 0
1 0 1 0 0 0
0 0 1 0 0 0
0 0 0 2 0 0
1 0 0 0 1 0
2 0 1 0 0 0
2 0 1 1 1 0
1 0 1 1 0 0
1 0 1 2 0 0
1 0 0 1 1 0
0 0 0 0 1 0
1 1 0 0 1 0
1 0 1 2 1 0
0 0 0 0 1 0
0 0 1 0 0 0
1 0 1 1 1 0
1 0 1 0 1 0
2 0 1 2 0 0
0 0 1 2 1 0
0 0 1 0 1 0
2 0 1 0 1 0
0 0 1 0 1 0
1 0 0 0 0 0
1 0 0 0 1 0
0 0 0 0 1 0
0 0 1 2 1 0
0 1 1 0 0 0
0 1 0 0 1 0
2 1 0 0 0 0
2 1 0 0 0 0
1 1 0 2 0 0
1 1 0 0 0 1
0 1 0 0 0 0
2 1 0 0 1 0
0 1 0 0 1 0
2 1 0 2 1 0
2 1 0 2 1 0
1 1 0 2 1 0
0 1 0 0 0 1
2 1 1 0 1 0
2 1 0 1 1 0
1 1 0 0 0 1
2 1 0 0 0 0
1 1 0 0 1 0
1 1 0 0 0 0
2 1 0 1 1 0
1 1 0 0 1 0
1 0 1 1 0 1
2 1 0 1 1 0
0 1 0 0 1 0
1 0 1 0 0 0
0 0 1 0 0 1
1 0 0 0 0 0
0 0 0 2 1 0
1 0 1 2 0 1
1 0 0 1 1 0
2 0 1 2 1 0
2 0 0 0 1 0
1 0 0 1 1 0
1 0 1 0 1 0
0 0 1 0 0 0
1 0 0 2 1 0
2 0 1 1 1 0
0 0 1 0 1 0
0 0 0 0 1 0
2 0 0 1 0 1
0 0 1 0 0 0
0 0 0 0 0 0
1 0 1 1 1 1
2 0 1 0 1 0
0 0 0 0 0 0
1 0 1 0 1 0
0 0 0 0 1 0
0 0 0 2 0 0
0 0 0 0 0 0
0 0 1 2 0 0
0 0 1 0 1 0
0 0 1 0 0 1
0 0 0 2 1 0
1 0 1 1 1 0
1 0 0 1 1 0
0 0 1 0 1 0
1 0 0 0 0 0
1 0 1 0 1 0
2 0 0 0 1 0
1 0 0 0 1 0
2 0 0 1 1 0
0 0 1 2 1 0
1 0 1 2 0 0
0 0 1 2 1 0
1 0 0 0 0 0
0 0 1 0 1 0
0 0 0 1 1 0
1 0 0 0 1 0
2 0 0 1 1 0
1 0 0 1 1 0
1 0 1 0 0 0
1 1 0 1 1 0
2 1 0 0 1 0
0 1 0 0 0 0
1 1 0 1 0 1
1 1 0 2 1 0
0 1 0 0 0 0
1 1 0 2 0 0
0 1 0 0 1 0
1 1 0 0 1 1
1 1 0 2 1 0
1 0 0 2 1 0
2 1 1 1 1 0
0 1 0 0 1 0
0 1 0 0 1 0
2 1 0 0 0 1
1 1 0 2 1 0
1 1 0 0 1 0
1 1 1 0 0 0
2 1 0 2 1 0
2 1 1 1 0 0
0 1 0 0 1 0
1 1 0 2 1 0
0 1 0 0 1 0
1 1 0 1 1 0
0 1 0 0 1 0
0 1 0 0 0 0
1 1 0 0 0 0
1 1 0 2 1 0
1 1 0 0 0 0
0 1 1 2 0 0
2 1 0 0 1 0
2 0 1 0 0 1
0 0 1 0 1 0
1 0 1 0 0 0
0 0 1 2 1 0
0 0 1 0 0 0
1 0 1 0 1 0
0 0 1 0 1 0
0 0 1 0 1 0
1 0 1 0 1 0
0 0 0 0 0 1
0 0 1 2 1 0
0 0 1 0 1 0
0 0 1 0 1 0
0 0 1 0 0 0
0 0 1 0 0 1
0 0 1 2 1 0
2 0 1 2 1 0
0 0 1 0 1 0
0 0 1 0 1 0
0 0 1 0 1 0
1 0 0 0 0 0
2 0 1 1 1 0
0 0 1 0 0 1
1 0 1 0 0 0
1 0 1 1 1 0
1 0 1 1 0 0
0 0 1 0 0 0
1 0 1 1 1 0
1 0 1 2 0 0
2 0 0 0 1 0
0 0 1 0 0 1
0 0 1 0 1 0
0 0 1 0 1 0
1 0 1 0 0 0
0 0 1 0 0 0
2 0 1 1 0 0
0 0 1 2 0 0
1 0 0 1 1 1
0 0 0 0 1 0
0 0 0 0 0 1
0 0 1 0 1 0
2 0 1 2 1 0
1 0 0 1 0 0
0 0 1 0 0 0
2 0 0 1 1 1
0 0 1 0 0 0
0 0 1 0 1 0
2 0 1 0 1 0
0 0 1 0 1 0
2 0 0 0 1 0
1 0 1 0 1 0
1 0 0 0 1 0
0 0 1 0 0 1
2 0 0 0 0 0
2 0 0 1 1 0
0 0 1 0 1 0
0 0 0 0 1 0
2 0 1 0 0 0
1 0 1 0 1 0
0 0 0 0 1 0
1 0 1 0 1 0
0 0 1 0 0 0
1 0 1 0 1 0
1 0 1 0 1 0
1 0 1 0 1 0
0 0 1 2 0 0
2 0 1 0 1 1
0 0 1 0 1 0
0 0 1 2 1 0
0 0 0 0 0 0
0 0 1 0 1 0
1 0 1 0 1 0
0 0 1 0 1 0
1 0 1 0 0 0
0 0 1 0 1 0
0 0 1 0 0 0
1 0 1 0 0 0
0 0 1 0 1 0
0 0 1 0 1 0
1 0 0 0 1 0
0 0 1 0 0 0
0 0 0 0 1 0
1 0 1 1 1 0
0 0 0 2 0 0
0 0 1 0 1 0
0 0 1 0 1 0
0 0 1 0 1 0
1 0 0 1 1 0
2 0 0 0 1 0
1 0 0 0 0 0
2 0 0 2 1 0
0 0 1 2 1 0
1 0 1 0 0 1
0 0 1 2 1 0
0 0 1 2 1 0
0 0 1 0 1 0
1 0 1 2 1 0
0 0 0 2 0 0
1 0 0 0 0 0
0 0 0 2 1 0
0 0 1 0 1 0
2 0 0 0 1 0
1 0 0 0 0 0
1 0 0 1 1 0
1 0 1 1 1 0
1 0 1 0 1 1
0 0 1 0 1 0
1 1 0 2 1 0
1 1 0 1 0 0
2 1 0 2 1 0
1 1 1 0 0 0
0 1 1 0 0 0
0 1 1 0 0 1
0 1 0 0 1 0
1 1 1 0 0 0
1 1 1 0 1 0
0 1 0 0 1 0
0 1 1 0 0 1
1 1 1 1 1 0
1 1 0 2 1 0
0 1 0 2 0 0
1 1 0 2 1 0
0 0 1 2 1 0
2 1 1 1 1 0
0 1 0 0 1 0
0 0 1 0 1 0
2 1 0 1 1 0
0 1 0 0 1 0
1 1 0 0 0 0
1 1 0 0 1 0
0 1 0 0 0 0
0 1 1 0 0 0
2 1 0 0 1 0
2 1 0 0 0 0
1 1 0 0 1 0
2 1 0 1 1 0

【R语言-20行代码】牛顿迭代求伽马函数极大似然估计的参数估计 简述 研究了下计算公式,简化了一下,用r语言实现了。 算解释 牛顿迭代 xk+1=xk−f(xk)f′(xk)x_{k+1} = x_k - \frac{f(x_k)}{f&amp;#x27;(x_k)}xk+1​=xk​−f′(xk​)f(xk​)​ 求解的方程是 f(x)=0f(x) = 0f(x)=0 通过极大似然估计,构造对数似然方程,之后再关于α\alphaα和β\betaβ... 阅读详情

相关推荐

回归、Lasso回归logistic回归

Lasso模型的求解方:坐标下降 目标函数形式:min⁡β12N∑i=1N(yi−βzi)2+λ∣β∣(λ>0)\min\limits_{\beta}{\frac{1}{2N}\sum\limits_{i=1}^{N}(y_i-\beta z_i)^2+\lambda|\beta|}\quad(\lambda>0)βmin​2N1​i=1∑N​(yi​−βzi​)2+λ∣β∣(...

qq_40267462的博客 7114

统计信号处理作业牛顿求最大似然估计matlab

统计信号处理作业牛顿求最大似然估计matlab,题目为xn = sign(b*sn +wn), sn、xn已知,wn为高斯白噪声,求b的最大似然估计,不喜勿喷

Pytorch深度学习实战1-6:图解牛顿迭代,牛顿不止力学三定律

图文详解牛顿迭代原理+手推公式,附Python实战代码加深理解

FRIGIDWINTER的博客 3469

深度学习5牛顿

牛顿解最大似然估计 对于之前我们解最大似然估计使用了梯度下降,这边我们使用牛顿,速度更快。 牛顿也就是要求解,可导,θ用下面进行迭代。 具体看这个图 对于我们刚刚的求最大似然估计,也就是,则 下面在原理上说一说。 摘自:http://blog.csdn.net/luoleicn/article/details/6527049 对于一个目标函数f,求函...

weixin_30632899的博客 431

基于R和Python的极大似然估计的牛顿实现

前言 最近在学习Theory and Method of Statistics(统计理论方),使用的教材是由Bradley Efron 、Trevor Hastie共同编写的Computer Age Statistical Inference: Algorithms, Evidence, and Data Science(《计算机时代的统计推断:算、演化和数据科学》)。书中第四章讲述的Fisherian Inference and Maximum Likelihood Estimati...

zns972630879的博客 7257

深度学习—— 最小二乘 & 极大似然估计 & 梯度下降

一、最小二乘 狭义的最小二乘,指的是在线性回归下采用最小二乘准则(或者说叫做最小平方),进行线性拟合参数求解的、矩阵形式的公式方。所以,这里的「最小二乘」应叫做「最小二乘算」或者「最小二乘方」,百度百科「最小二乘」词条中对应的英文为「The least square method」。狭义的最小二乘方,是线性假设下的一种有全局最优的闭式解的参数求解方,最终结果为全局最优; 而广义...

Gloria的博客 7389

机器学习 | 实验三:逻辑回归和牛顿

在本练习中,我们将使用牛顿对分类问题实现逻辑回归

知识库搭建ing 1564

Logistic回归牛顿迭代

在上一篇文章中,我讲述了Logistic回归的原理以及它的梯度上升实现。现在来研究Logistic回归的另一种 实现,即牛顿迭代。   在上篇文章中,我们求出Logistic回归的似然函数的偏导数为                    由于是一个多元函数,变元是,多元函数求极值问题以前已经讲过,参考如下文章   链接:http://blog.csdn.net/acdream

ACdreamer 1万+

Logistic回归原理及公式推导

原文见 http://blog.csdn.net/acdreamers/article/details/27365941

AriesSurfer的专栏 14万+

python logistic回归_Logistic回归的python实现

Logistic回归的python实现有时候你可能会遇到这样的问题:明天的天气是晴是阴?病人的肿瘤是否是阳性?……这些问题有着共同的特点:被解释变量的取值是不连续的。此时我们可以利用logistic回归的方解答。下面便来对这一方进行简单的介绍。Logistic回归的介绍logistic回归是一种广义线性回归(generalized linear model),因此与多重线性回归分析有...

weixin_39743064的博客 797

Logistic回归和梯度上升算

Logistic回归和梯度上升算

PKU_ZZY的博客 1504

matlab 对数回归,[线性模型] 对数几率回归Logistic Regression)

公式推导对数几率回归用于处理二分类问题,其数学基础为对数几率函数,是一种 Sigmoid 函数\[y = \frac{1}{1+e^{-z}} \tag 1\]其函数图像如下取 $z = \boldsymbol{w}^T\boldsymbol{x}+b$,并对式 $(1)$ 进行一定变换,得$$\ln\frac{y}{1-y}= \boldsymbol{w}^T\boldsymbol{x}+b \...

weixin_42314448的博客 1959

分类-1-逻辑回归Logistic regression)、感知学习算(perceptron learning algorithm)、牛顿迭代

逻辑回归Logistic regression)我们现在只考虑二分类,即y∈{0,1}y\in \{0,1\}。 类似于线性回归问题,我们同样定义一个估计(hypothesis)函数hθ(x)h_\theta(x)。显然我们的输出值要限定在{0,1}\{0,1\}之间会更加有利。因此选择模型: hθ(x)=g(θTx)=11+e−θTxwhereg(z)=11+e−zh_\theta(x)=g

哎呦喂的博客 3270

线性回归 and Logistic回归

回归分析回归分析本质上就是一个函数估计的问题(函数估计包括参数估计和非参数估计),就是找出因变量(DV, Dependent Variable)和自变量(IV,Independent Variable)之间的因果关系。本文讲两种回归分析的方:一般线性回归(ordinary linear regression)和逻辑斯谛回归logistic regression)。更确切地讲线性回归和Logis

u014524249的博客 551

机器学习--初步了解手写数字识别之logistic回归

1.首先对于一个样例来说,我们先分析得出它的因变量(各因变量之间彼此不相关)。对该样例的各个因变量已知的数据集合我们称之为样本数据(若因变量有m个,则样本数据是m维的);对我们想要得到或者预测出的数据称之为输出数据;一般通过一个函数来拟合已知的样本数据和输出数据,从而在输入新的训练数据的时候得到未知的输出数据,我们把这个函数叫做预测函数(or假设or模型)。2.logistic回归是一个回归模型,主

thj19980720的博客 1万+

logit回归模型假设_一文让你搞懂Logistic回归模型

注:本文是我和夏文俊同学共同撰写的现考虑二值响应变量,比如是否购车,是否点击,是否患病等等,而是相应的自变量或者称特征。现希望构建一个模型用于描述和的关系,并对进行预测。线性模型可以吗?我们首先想到的是构建线性模型。形式如下:对于线性模型,可采用最小二乘进行估计。 但这样的模型和估计方是否合理呢?采用线性模型对离散变量进行建模,往往存在以下问题:在模型左边只取两个值,而右边的取值范围在整个实数轴...

weixin_28950015的博客 3055
上一篇: java 线程的基础
下一篇: Spark性能优化指南
SuPhoebe
博客等级 码龄13年 2181粉丝 483原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值