机器学习算法逻辑回归Logistic Regression之c++实现(不调用外源库)

 目前玩机器学习的小伙伴,上来就是使用现有的sklearn机器学习包,写两行代码,调调参数就能跑起来,看似方便,实则有时不利于个人能力发展,要知道现在公司需要的算法工程师,不仅仅只是会调参(这种工作,入门几个月的人就可以干了),而是要深入底层,能优化代码,能自己搭。

本文章适合以下几类人:

1)初学者,了解机器学习的实现过程

2)想提升自己的代码能力

第一步:原理

    简单来说, 逻辑回归(Logistic Regression)是一种用于解决二分类(0 or 1)问题的机器学习方法,用于估计某种事物的可能性。比如某用户购买某商品的可能性,某病人患有某种疾病的可能性,以及某广告被用户点击的可能性等。 注意,这里用的是“可能性”,而非数学上的“概率”,logisitc回归的结果并非数学定义中的概率值,不可以直接当做概率值来用。该结果往往用于和其他特征值加权求和,而非直接相乘。

那么逻辑回归与线性回归是什么关系呢?

逻辑回归(Logistic Regression)与线性回归(Linear Regression)都是一种广义线性模型(generalized linear model)。逻辑回归假设因变量 y 服从伯努利分布,而线性回归假设因变量 y 服从高斯分布。 因此与线性回归有很多相同之处,去除Sigmoid映射函数的话,逻辑回归算法就是一个线性回归。可以说,逻辑回归是以线性回归为理论支持的,但是逻辑回归通过Sigmoid函数引入了非线性因素,因此可以轻松处理0/1分类问题。

第二步:代码实现

#include <iostream>
#include <stdlib.h>
#include <string>
#include <math.h>
#include "matrix.h"
#include <fstream>
#include <sstream>
#include <stack>
#include <random>
#include<time.h>
using namespace std;
#define MAX 1000000
#define MIN -100000

double sigmoid(double z)
{
    return 1.0/(1 + exp(-z));
}

/**
梯度上升算法,主要是确定负梯度方向,步长,采用迭代的思想迭代n至收敛,
当目标函数是凸规划问题,那么局部最小值就是全局最小值

在这里梯度下降和上升的区别,可以参考 http://blog.csdn.net/dongtingzhizi/article/details/15962797
**/
void gradAscent(Matrix dataMatIn, Matrix classLabels)
{
    double alpha = 0.001;
    int maxCycles = 500;
    int m = dataMatIn.col;
    int n = dataMatIn.row;
    Matrix weights;
    weights.initMatrix(&weights,n,1,1);

    Matrix dataMuWeights;
    dataMuWeights.initMatrix(&dataMuWeights, m, 1);

    Matrix error;
    error.initMatrix(&error, m, 1);

    Matrix dataMatInT;
    dataMatInT.initMatrix(&dataMatInT,n,m);
    dataMatInT.transposematrix(dataMatIn, &dataMatInT);

    Matrix dataMuError;
    dataMuError.initMatrix(&dataMuError,n,1);

    for (int i = 0; i < maxCycles; i++)
    {
        dataMuWeights.multsmatrix(&dataMuWeights, dataMatIn, weights);
        for (int j = 0; j < m; j++)
        {
            dataMuWeights.mat[j][0] = sigmoid(dataMuWeights.mat[j][0]);
        }
        error.submatrix(&error, classLabels, dataMuWeights);

        dataMuError.multsmatrix(&dataMuError, dataMatInT, error);
        for (int j = 0; j < n; j++)
        {
            dataMuError.mat[j][0] = alpha * dataMuError.mat[j][0];
        }

        weights.addmatrix(&weights,weights, dataMuError);
    }
    weights.print(weights);
    /**
    验证算法的正确性
    **/

    Matrix test;
    test.initMatrix(&test,dataMatIn.col, 1);
    test.multsmatrix(&test, dataMatIn, weights);
    for (int i = 0; i < m; i++)
    {
        if (test.mat[i][0] > 0)
        {
            cout<<1<<endl;
        }
        else
            cout<<0<<endl;
    }
}


void stocGradAscent(Matrix dataMatIn, Matrix classLabels)
{

}

/**
随机梯度下降与梯度下降法不同的是在负梯度方向的确定,梯度下降是根据所有的样本来确定负梯度方向,
而随机梯度下降每次只看一个样本点来确定负梯度方向,虽然不完全可信,但随着迭代次数增加,同样收敛

**/



//通过随机选取样本来更新回归系数,这种方法可以减少周期性的波动
//步长在不断的减少

void stocGradAscent1(Matrix dataMatIn, Matrix classLabels, int numIter = 150)
{

}



/**
逻辑回归,这里主要考虑其常用的两种求参数算法,一种是梯度下降,一种是随机梯度下降

*/

int main()
{
    srand((unsigned)time(NULL));
    dataToMatrix dtm;
    cout<<"loadData"<<endl;
    cout<<"----------------------"<<endl;
    char file[20]="logReg.txt";
    dtm.loadData(&dtm,file);

    Matrix x;
    x.loadMatrix(&x,dtm);

    Matrix y;
    y.initMatrix(&y,x.col,1);
    y=y.getOneRow(x,x.row - 1);

    x.deleteOneRow(&x,x.row);

    //gradAscent(x,y);
    stocGradAscent1(x,y);
    return 0;
}

第三步:运行过程

运行结果

用到的软件是vs2010以上的版本都可以,不用额外配置什么,没调包,会用这个软件进行c++开发,就会使用这个软件

此程序由于不调用任何外源库,所以读者可以看清楚每一个算法的原理,要想学好机器学习算法,必须打好基础,不要好高骛远,另外,程序都是有备注,应该很好理解的,实在不懂,可以来问店主

代码的下载路径(新窗口打开链接)机器学习算法逻辑回归Logistic Regression之c++实现(不调用外源库)

有问题可以私信或者留言,有问必答

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值