机器学习之线性回归

线性回归

线性回归是最简单的机器学习模型之一,但是它也包含了机器学习中最基本的思想,个人觉得它的实现思路与神经网络等深度学习从原理上并没有太大的区别。对于回归问题:
y = w T x + b y=w^Tx + b y=wTx+b
利用梯度下降原理对 w w w b b b进行更新:
w t + 1 = w t − α ∗ 1 / m ∗ ∑ i = 1 n ( y i p − y i r ) w^{t+1}=w^t - \alpha*1/m*\sum_{i=1}^{n}{(y^p_i-y^r_i)} wt+1=wtα1/mi=1n(yipyir)
b t + 1 = b t − α ∗ 1 / m ∗ ∑ i = 1 n ( ( y i p − y i r ) ∗ x i ) b^{t+1}=b^{t}-\alpha*1/m*\sum_{i=1}^{n}{((y^p_i-y^r_i)*x_i}) bt+1=btα1/mi=1n((yipyir)xi)

主函数:

#include <iostream>
#include "LinearRegression.h"
#include<fstream>

using namespace std;

double* readFile(string fileName) {
	ifstream in;
	in.open(fileName);
	double temp;
	int index = 0;
	double* data = new double[50];
	while (in >> temp) {
		data[index] = temp;
		index++;
	}
	for (int i = 0; i < 50; i++)
		cout << "X,Y" << data[i] << endl;
	return data;
}

int main() {
	double alpha = 0.07;
	int iterations = 200;
	double x_predict = 2.1212;
	double y_predict;

	// 读取文件
	string fileNameX = "ex2x.dat";
	string fileNameY = "ex2y.dat";
	ifstream in;
	in.open(fileNameX);
	double temp;
	int length = 0;
	while (in >> temp) {
		length++;
	}
	double* X = new double[length];
	double* Y = new double[length];

	// 模型训练预测
	X = readFile(fileNameX);
	Y = readFile(fileNameY);
	LinearRegression lr(X, Y, length);
	lr.train(alpha, iterations);
	y_predict = lr.predict(x_predict);
	cout << y_predict << endl;

	system("pause");
	return 0;
}
/*******************************************************************
*《周志华 机器学习》C++代码
*
* htfeng
* 2018.09.28
*
* 第三章:线性模型
* 主要写线性回归
*******************************************************************/
#include <iostream>
#include <fstream>
#include "LinearRegression.h"
#include "Utils.h"


using namespace std;

//初始化
LinearRegression::LinearRegression(double x[], double y[], int m) 
{
	this->x = x;
	this->y = y;
	this->m = m;
}

//梯度下降
double *LinearRegression::gradient_descent(double x[], double y[], double alpha, int iters, double *J, int m) 
{
	double *theta = new double[2];
	theta[0] = 1;
	theta[1] = 1;
	for (int i = 0; i < iters; i++) 
	{
		double *predictions = calculate_predictions(x, theta, m);
		double *diff = Utils::array_diff(predictions, y, m);
		double *error_x1 = diff;
		double *error_x2 = Utils::array_multiplication(diff, x, m);
		theta[0] = theta[0] - alpha * (1.0 / m) * Utils::array_sum(error_x1, m);
		theta[1] = theta[1] - alpha * (1.0 / m) * Utils::array_sum(error_x2, m);
		J[i] = compute_cost(x, y, theta, m);
	}
	return theta;
}

// 训练函数
void LinearRegression::train(double alpha, int iterations) {
	double *J = new double[iterations];//将J定义为一个包含了iterations个元素的数组
	this->theta = gradient_descent(x, y, alpha, iterations, J, m);  //m表示训练集的个数
	cout << "J = ";
	for (int i = 0; i < iterations; ++i) {
		cout << J[i] << " ";
	}
	cout << endl << "Theta: " << theta[0] << " " << theta[1] << endl;
}

//预测
double LinearRegression::predict(double x) {
	return h(x, theta);
}

//计算误差
double LinearRegression::compute_cost(double x[], double y[], double theta[], int m) {
	double *predictions = calculate_predictions(x, theta, m);
	double *diff = Utils::array_diff(predictions, y, m);
	double *sq_errors = Utils::array_pow(diff, m, 2);
	return (1.0 / (2 * m)) * Utils::array_sum(sq_errors, m);
}

//预测单个值
double LinearRegression::h(double x, double theta[]) {
	return theta[0] + theta[1] * x;
}

//预测
double *LinearRegression::calculate_predictions(double x[], double theta[], int m) {
	double * predictions = new double[m];
	for (int i = 0; i < m; i++) {
		predictions[i] = h(x[i], theta);
	}
	return predictions;
}

#ifndef ML_LINEARREGRESSION_H//如果这个宏没有被定义
#define ML_LINEARREGRESSION_H//则定义宏


class LinearRegression {
public:
	double *x;
	double *y;
	int m;
	double *theta;
	__declspec(dllexport) LinearRegression(double x[], double y[], int m);
	__declspec(dllexport) void train(double alpha, int iterations);
	__declspec(dllexport) double predict(double x);
private:
	//计算模型损失
	__declspec(dllexport) static double compute_cost(double x[], double y[], double theta[], int m);
	//计算单个预测值
	__declspec(dllexport) static double h(double x, double theta[]);
	//预测
	__declspec(dllexport) static double *calculate_predictions(double x[], double theta[], int m);
	//梯度下降
	__declspec(dllexport) static double *gradient_descent(double x[], double y[], double alpha, int iter, double *J, int m);
};

#endif

#ifndef __UTILS__
#define __UTILS__
#include<string>
#include<iostream>

using namespace std;


class Utils {
public:
	static double* array_diff(double predictions[], double y[], int m);
	static double* array_multiplication(double diff[], double x[], int m);
	static double* array_pow(double error[], int m, int n);
	static double array_sum(double error[], int m);
};

double* Utils::array_diff(double predictions[], double y[], int m) {
	double *diff = new double[m];
	for (int i = 0; i < m; i++) {
		diff[i] = predictions[i] - y[i];
	}

	return diff;
}

double* Utils::array_multiplication(double diff[], double x[], int m) {
	double *differror = new double[m];
	for (int i = 0; i < m; i++) {
		differror[i] = diff[i] * x[i];
	}

	return differror;
}

double Utils::array_sum(double error[], int m) {
	double sum = 0.0;
	for (int i = 0; i < m; i++) 
	{
		sum += error[i];
	}

	return sum;
}

double* Utils::array_pow(double error[], int m, int n) 
{
	double *sq_errors = new double[m];
	for (int i = 0; i < m; i++) 
	{
		sq_errors[i] = pow(error[i], n);
	}

	return sq_errors;
}
#endif

参考:https://github.com/fenghaotong/MachineLearningInCPlusPlus

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值