C++实现

“linear_regression.h”

//二分类逻辑回归模型
struct elem_log
{double y;double* x;              //用数组传入自变量数据(x[0]=1,便于之后的计算)
};class logistic_reg
{//与线性回归的不同点在于hx不同
public:logistic_reg(int xnum, elem_log* p, int size, double rate);               //初始化(训练集的x0全部固定为1) ~logistic_reg();                                                           //析构void scaling();                                                            //特征缩放器(将所有特征值统一缩放至1--10)void scalback();                                                           //特征还原(参数缩放)double hx(int i);                                                          //sigmoid函数:计算第i组训练集数据对应的hx函数值(0--setsize-1)double cost_fuction();                                                     //返回当前预测方程对应代价函数的值void update();                                                             //同时更新方程参数void find();                                                               //最小化代价函数,找到收敛点时对应的方程参数double* get_par(int &par_num);                                             //获得当前方程的参数double est_val(double* x);                                                 //使用拟合后的回归方程进行预测private:int x_num;                         //自变量个数elem_log* tran_set;                //训练集(读入时将x【0】赋值为1)int setsize;                       //训练集数据量double* par;                       //参数数组(大小为实际x_num+1):h(x)=par0*x0(赋值为1)+par1*x1+par2+x^2+...+par(x_num)*x^x_numdouble learn_rate;                 //学习速率double* x_scal;                    //特征缩放率};

“linear_regression.cpp”

//二分类逻辑回归
logistic_reg::logistic_reg(int xnum, elem_log* p, int size, double rate)
{//初始化(训练集的x0全部固定为1)//参数列表:自变量数目,训练集地址,训练集容量,学习速率x_num = xnum + 1;                //设置自变量数目setsize = size;                  //获取训练集大小tran_set = p;                    //指针指向训练集数组learn_rate = rate;               //设置学习速率par = new double[xnum + 1];      //系数初始化为0memset(par, 0, sizeof(double)*(xnum + 1));x_scal = new double[xnum + 1];   //特征缩放率初始化为1for (int i = 0;i < x_num;i++)x_scal[i] = 1;
}logistic_reg::~logistic_reg()
{//析构tran_set = NULL;setsize = 0;delete[]par;par = NULL;delete[]x_scal;x_scal = NULL;
}void logistic_reg::scaling()
{//特征缩放器(将所有特征值统一缩放至1--10)for (int j = 0;j < x_num;j++){//以第一组数据确定缩放率while (tran_set[0].x[j] > 10 || tran_set[0].x[j] < 1){if (tran_set[0].x[j] > 10){tran_set[0].x[j] /= 10.0;x_scal[j] *= 10.0;}else{tran_set[0].x[j] *= 10.0;x_scal[j] /= 10.0;}}}for (int i = 1;i < setsize;i++){//对剩余数据进行缩放for (int j = 0;j < x_num;j++){tran_set[i].x[j] /= x_scal[j];}}
}void logistic_reg::scalback()
{//特征还原(参数缩放)for (int i = 0;i < x_num;i++)par[i] /= x_scal[i];
}double logistic_reg::hx(int i)
{//sigmoid函数:计算第i组训练集数据对应的hx函数值(0--setsize - 1)double sum=0;for (int j = 0;j < x_num;j++)sum += par[j] * tran_set[i].x[j];double hx = 1 / (1 + exp(0 - sum));            //double exp(double x)----求e的x次幂return hx;
}double logistic_reg::cost_fuction()
{//返回当前预测方程对应代价函数的值double cost = 0;for (int i = 0;i < setsize;i++){cost += (tran_set[i].y*log(hx(i)) + (1 - tran_set[i].y)*log(1 - hx(i)));}return -1.0 / (double)setsize*cost;
}void logistic_reg::update()
{//同时更新方程参数double* sum = new double[x_num];for (int j = 0;j < x_num;j++){sum[j] = 0;for (int i = 0;i < setsize;i++){sum[j] += (hx(i) - tran_set[i].y)*tran_set[i].x[j];}}for (int i = 0;i < x_num;i++)par[i] -= learn_rate * sum[i] / (double)setsize;delete[]sum;
}void logistic_reg::find()
{//最小化代价函数,找到收敛点时对应的方程参数scaling();                     //数据放缩double cost_pre, cost_last;cost_pre = cost_fuction();update();                      //更新参数cost_last = cost_fuction();while (cost_pre != cost_last){//寻找收敛点/*cout << cost_pre << " " << cost_last << endl;        //用来选择学习率*/cost_pre = cost_last;update();cost_last = cost_fuction();}//获得假设函数最优拟合时的参数scalback();//特征还原,参数缩放
}double* logistic_reg::get_par(int &par_num)
{//获得当前方程的参数par_num = x_num;return par;
}double logistic_reg::est_val(double* x)
{//使用拟合后的回归方程进行预测double sum = 0;for (int j = 0;j < x_num;j++)sum += par[j] * x[j];double hx = 1 / (1 + exp(0 - sum));            //double exp(double x)----求e的x次幂return hx;
}

主函数部分:

//二分类逻辑回归测试
int main()
{int size, xnum;cout << "请输入训练集容量:";cin >> size;cout << "请输入变量个数: ";cin >> xnum;elem_log transet[200];for (int i = 0;i < size;i++){transet[i].y = 0;transet[i].x = new double[xnum + 1];memset(transet[i].x, 0, sizeof(double)*(xnum + 1));}cout << "请输入训练集数据:" << endl;for (int i = 0;i < size;i++){transet[i].x[0] = 1;for (int j = 1;j <= xnum;j++)cin >> transet[i].x[j];cin >> transet[i].y;}logistic_reg obj(xnum, transet, size, 0.4);obj.find();double*par = NULL;int parnum;par = obj.get_par(parnum);cout << "h(x)=" << par[0];for (int i = 1;i < parnum;i++){if (par[i] > 0)cout << '+' << par[i] << "*x" << i;else{if (par[i] < 0)cout << par[i] << "*x" << i;}}cout << endl;double*x = new double[xnum + 1];memset(x, 0, sizeof(double)*(xnum + 1));string str;double ans;while (cin >> str){//预测部分if (str == "end")break;x[0] = 1;for (int i = 1;i <= xnum;i++)cin >> x[i];ans = obj.est_val(x);cout << ans << endl;}delete[]x;for (int i = 0;i < size;i++){delete[]transet[i].x;}return 0;
}

运行结果



用octave可视化:

>> A=load('ex2data1.txt');
>>  x1=A(:,[1]);
>> x2=A(:,[2]);
>> y=A(:,[3]);
>> pos = find(y==1); neg = find(y == 0);
>> X=[x1,x2];
>> plot(X(pos, 1), X(pos, 2), 'k+','LineWidth', 2,'MarkerSize', 7);
>> hold on;
>> plot(X(neg, 1), X(neg, 2), 'ko', 'MarkerFaceColor', 'y','MarkerSize', 7);
>> hold on;
>> x2=(-0.206231*x1+25.1612)/0.201471;
>> plot(x1,x2,'r');
>> xlabel('Exam 1 score');
>> ylabel('Exam 2 score');
>> title('logistic regression');
>> legend('Admitted','Not admitted');
>> print -dpng 'linear_logistic.png';


按照自己做出的模型得出的决策边界进行分类如上图。

吴恩达机器学习之线性逻辑回归实现部分相关推荐

  1. 吴恩达机器学习课后习题——逻辑回归

    机器学习课后作业-逻辑回归 逻辑回归 逻辑回归算法,是一种给分类算法,这个算法的实质是:它输出值永远在0到 1 之间. 将要构建一个逻辑回归模型来预测,某个学生是否被大学录取.设想你是大学相关部分的管 ...

  2. 吴恩达机器学习作业二——逻辑回归

    有了作业一的铺垫,作业二的代码更容易理解了. 逻辑回归 题目描述:在训练的初始阶段,我们将要构建一个逻辑回归模型来预测,某个学生是否被大学录取.设想你是大学相关部分的管理者,想通过申请学生两次测试的评 ...

  3. 吴恩达机器学习 8.6 逻辑回归(Logistic Regression)

    6.1 分类问题 参考文档: 6 - 1 - Classification (8 min).mkv 在这个以及接下来的几个视频中,开始介绍分类问题. 在分类问题中,你要预测的变量 $y$ 是离散的值, ...

  4. 吴恩达第三周逻辑回归

    分类问题 我们尝试预测的是结果是否属于某一个类(例如正确或错误) 分类举例 判断一封电子邮件是否是垃圾邮件 判断一次金融交易是否是欺诈 判断一个肿瘤是恶性的还是良性的 考查二元分类问题 我们将因变量( ...

  5. 吴恩达机器学习笔记 —— 7 Logistic回归

    http://www.cnblogs.com/xing901022/p/9332529.html 本章主要讲解了逻辑回归相关的问题,比如什么是分类?逻辑回归如何定义损失函数?逻辑回归如何求最优解?如何 ...

  6. 吴恩达机器学习作业1-线性回归讲解版奔雷手

    机器学习作业 1 - 线性回归 奔雷手 1.单变量线性回归 导入需要使用的包 import numpy as np import pandas as pd import matplotlib.pypl ...

  7. 吴恩达作业1:逻辑回归实现猫的分类

    思路:输入样本X与随机初始权重W相乘,利用sigmoid激活函数输出值,对于二分类问题,用交叉熵损失函数来计算损失值,通过交叉熵损失函数利用链式法则求出W和b的偏导,梯度下降更新W和b即可,(梯度下降 ...

  8. 吴恩达|机器学习作业2.0Logistic 回归

    2.0.Logistic 回归 1)题目: 在本部分的练习中,您将使用Logistic回归模型来预测一个学生是否被大学录取.假设你是大学某个院系的管理员,你想通过申请人在两门考试中的表现来决定每个人的 ...

  9. 吴恩达机器学习作业1-线性回归

    题目概述: 整个2的部分需要根据城市人口数量,预测开小吃店的利润 数据在ex1data1.txt里,第一列是城市人口数量,第二列是该城市小吃店利润. 用到2个公式: 代价函数: 批量梯度下降 进行优化 ...

最新文章

  1. [转]关于MyEclipse下的项目无法使用BASE64Encoder问题的解决办法
  2. 初中参观机器人博物馆的作文_2021考研英语二大作文模板整理
  3. 美团工程师上演“谍战”剧?“黑了一把”拼多多获取薪资信息
  4. 关于事件相关电位P300应用于视频游戏的研究
  5. hdu5012 水搜索
  6. C++实现插入排序算法
  7. [剑指offer]面试题15:链表中倒数第k个结点
  8. 组件分页_如何创建分页组件
  9. 服务器任务栏不显示程序,Win10任务栏不显示应用程序标签怎么办?
  10. swap函数_C++ vector成员函数实现[持续更新]
  11. swoole 固定包头格式
  12. ug装配绕轴旋转_UG绘制小吊扇模型,建模装配还能运动起来
  13. 让你彻悟人生的555句金玉良言
  14. 新闻丨5G牌照发布,智链万源携手动物健康与食品安全创新联盟在农业领域先声夺人...
  15. safari支持java_BLOB URL无法在Safari中使用
  16. 游戏服务器到底是什么?
  17. CY7C68000 UTMI PHY芯片介绍
  18. Telnet 服务 开启 步骤
  19. 内蒙古计算机职业高中高考分数线,内蒙古高考本科三批和高职高专录取分数线公布...
  20. 如何用HTML制作下载文件的网页

热门文章

  1. css 历史及css3 新特性
  2. 锂电池保护板原理(转)
  3. jsp中动态include与静态include的区别
  4. 关于MVC与三层架构
  5. 编码 GBK 的不可映射字符
  6. 博客园编辑器插入code功能试用及与EditPlus的语法高亮比较
  7. 机器学习读书笔记(一)k-近邻算法
  8. 基于C语言EOF与getchar()的使用详解
  9. android基本控件学习-----ProgressBar
  10. php.ini中Magic_Quotes_Gpc开关设置