吴恩达机器学习之线性逻辑回归实现部分
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';
按照自己做出的模型得出的决策边界进行分类如上图。
吴恩达机器学习之线性逻辑回归实现部分相关推荐
- 吴恩达机器学习课后习题——逻辑回归
机器学习课后作业-逻辑回归 逻辑回归 逻辑回归算法,是一种给分类算法,这个算法的实质是:它输出值永远在0到 1 之间. 将要构建一个逻辑回归模型来预测,某个学生是否被大学录取.设想你是大学相关部分的管 ...
- 吴恩达机器学习作业二——逻辑回归
有了作业一的铺垫,作业二的代码更容易理解了. 逻辑回归 题目描述:在训练的初始阶段,我们将要构建一个逻辑回归模型来预测,某个学生是否被大学录取.设想你是大学相关部分的管理者,想通过申请学生两次测试的评 ...
- 吴恩达机器学习 8.6 逻辑回归(Logistic Regression)
6.1 分类问题 参考文档: 6 - 1 - Classification (8 min).mkv 在这个以及接下来的几个视频中,开始介绍分类问题. 在分类问题中,你要预测的变量 $y$ 是离散的值, ...
- 吴恩达第三周逻辑回归
分类问题 我们尝试预测的是结果是否属于某一个类(例如正确或错误) 分类举例 判断一封电子邮件是否是垃圾邮件 判断一次金融交易是否是欺诈 判断一个肿瘤是恶性的还是良性的 考查二元分类问题 我们将因变量( ...
- 吴恩达机器学习笔记 —— 7 Logistic回归
http://www.cnblogs.com/xing901022/p/9332529.html 本章主要讲解了逻辑回归相关的问题,比如什么是分类?逻辑回归如何定义损失函数?逻辑回归如何求最优解?如何 ...
- 吴恩达机器学习作业1-线性回归讲解版奔雷手
机器学习作业 1 - 线性回归 奔雷手 1.单变量线性回归 导入需要使用的包 import numpy as np import pandas as pd import matplotlib.pypl ...
- 吴恩达作业1:逻辑回归实现猫的分类
思路:输入样本X与随机初始权重W相乘,利用sigmoid激活函数输出值,对于二分类问题,用交叉熵损失函数来计算损失值,通过交叉熵损失函数利用链式法则求出W和b的偏导,梯度下降更新W和b即可,(梯度下降 ...
- 吴恩达|机器学习作业2.0Logistic 回归
2.0.Logistic 回归 1)题目: 在本部分的练习中,您将使用Logistic回归模型来预测一个学生是否被大学录取.假设你是大学某个院系的管理员,你想通过申请人在两门考试中的表现来决定每个人的 ...
- 吴恩达机器学习作业1-线性回归
题目概述: 整个2的部分需要根据城市人口数量,预测开小吃店的利润 数据在ex1data1.txt里,第一列是城市人口数量,第二列是该城市小吃店利润. 用到2个公式: 代价函数: 批量梯度下降 进行优化 ...
最新文章
- [转]关于MyEclipse下的项目无法使用BASE64Encoder问题的解决办法
- 初中参观机器人博物馆的作文_2021考研英语二大作文模板整理
- 美团工程师上演“谍战”剧?“黑了一把”拼多多获取薪资信息
- 关于事件相关电位P300应用于视频游戏的研究
- hdu5012 水搜索
- C++实现插入排序算法
- [剑指offer]面试题15:链表中倒数第k个结点
- 组件分页_如何创建分页组件
- 服务器任务栏不显示程序,Win10任务栏不显示应用程序标签怎么办?
- swap函数_C++ vector成员函数实现[持续更新]
- swoole 固定包头格式
- ug装配绕轴旋转_UG绘制小吊扇模型,建模装配还能运动起来
- 让你彻悟人生的555句金玉良言
- 新闻丨5G牌照发布,智链万源携手动物健康与食品安全创新联盟在农业领域先声夺人...
- safari支持java_BLOB URL无法在Safari中使用
- 游戏服务器到底是什么?
- CY7C68000 UTMI PHY芯片介绍
- Telnet 服务 开启 步骤
- 内蒙古计算机职业高中高考分数线,内蒙古高考本科三批和高职高专录取分数线公布...
- 如何用HTML制作下载文件的网页