使用EasyX体验一元线性模型

使用方法

在这里插入图片描述

代码实现

#include <easyx.h>			// 引用图形库头文件
#include <conio.h>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<iostream>
void initWindow(void);
void getRealPoint(float* Point);
//定义坐标系表达大小
float x_range = 1.5;
float y_range = 1.5;
class ml_Point {
public:
	float _x, _y;
	float x, y;
	ml_Point(float c_x, float c_y) {
		_x = c_x;
		_y = c_y;
		float point[2] = {_x,_y};
		getRealPoint(point);
		this->x = point[0];
		this->y = point[1];
	}
};
void initWindow(void) {
	initgraph(600, 600, EW_SHOWCONSOLE);
	setbkcolor(RGB(255, 255, 255));
	cleardevice();
	setlinecolor(RGB(0, 0, 0));
	line(10, 50, 10, 550);//y轴
	line(10, 550, 590, 550);//x轴
	setfillcolor(RGB(125, 125, 125));
	//坐标系x轴上画点
	for (int x = 10; x <= 590; x += 10) {
		solidcircle(x, 550, 2);
	}
	//坐标系y轴画点
	for (int y = 50; y <= 550; y += 10) {
		solidcircle(10, y, 2);
	}
	srand(time(0));
}
void getRealPoint(float* Point) {
	//计算坐标系单位与图形坐标系的比例
	float x_step = 580.0 / x_range;
	float y_step = 500.0 / y_range;
	//计算在窗口坐标系的坐标
	//计算跳跃值
	float x_step_value = x_step * Point[0];
	float y_step_value = y_step * Point[1];
	//坐标系[0,0]开始换算
	float x_window = 10 + x_step_value;
	float y_window = 550 - y_step_value;
	Point[0] = x_window;
	Point[1] = y_window;
}
void getRandomRGB(unsigned char* rgb) {
	//srand(time(0));
	rgb[0] = rand() % (256 - 0) + 0;;
	rgb[1] = rand() % (256 - 0) + 0;;
	rgb[2] = rand() % (256 - 0) + 0;;
}
void getRandomPoint(float* point_random) {
	point_random[0] = rand() % (500 - 0) + 0;//随机生成x
	point_random[1] = rand() % (500 - 0) + 0;//随机生成y
}
bool drawPoint(float x, float y,unsigned char *rgb) {
	if (x < 10 || x>590) {
		return 0;
	}
	if (y < 50 || y>550) {
		return 0;
	}
	setfillcolor(RGB(0, 0, 0));
	solidcircle(x, y, 5);
	return 1;
}
float getMin(std::vector<float>&x_data) {
	float x_min = x_data[0];
	for (size_t i = 0; i < x_data.size(); i++) {
		if (x_min > x_data[i]) {
			x_min = x_data[i];
		}
	}
	return x_min;
}
float getMax(std::vector<float>& x_data) {
	float x_max = x_data[0];
	for (size_t i = 0; i < x_data.size(); i++) {
		if (x_max < x_data[i]) {
			x_max = x_data[i];
		}
	}
	return x_max;
}
float getAvg(std::vector<float>& x_data) {
	float x_sum = 0;
	for (size_t i = 0; i < x_data.size(); i++) {
		x_sum += x_data[i];
	}
	return x_sum / x_data.size();
}

int main()
{
	initWindow();
	//体验y=wx+b线性模型
	std::vector<float>x_data;
	std::vector<float>y_data;
	//输入样本数量
	size_t sample_size = 0;
	std::cin>>sample_size;
	if (sample_size <= 0) {
		return 0;
	}
	//输入样本
	for (size_t i = 0; i < sample_size; i++) {
		float x, y;
		std::cout << "x y:";
		std::cin >> x;
		std::cin >> y;
		x_data.push_back(x);
		y_data.push_back(y);
	}
	//数据归一化	使用min-max标准化
	/*
	求min 与 max
	xi=(xi-min)/(max-min)
	*/
	//x_data归一化
	float x_min = getMin(x_data);
	float x_max = getMax(x_data);
	for (size_t i = 0; i < x_data.size(); i++) {
		x_data[i] = (x_data[i] - x_min) / (x_max - x_min);
	}
	//y_data归一化
	float y_min = getMin(y_data);
	float y_max = getMax(y_data);
	for (size_t i = 0; i < y_data.size(); i++) {
		y_data[i] = (y_data[i] - y_min) / (y_max - y_min);
	}
	//输出x_data与y_data
	std::cout << "x_data:[";
	for (size_t i = 0; i < x_data.size(); i++) {
		std::cout << x_data[i];
		if (i < x_data.size() - 1)
			std::cout << ",";
		else
			std::cout << "]\n";
	}
	std::cout << "y_data:[";
	for (size_t i = 0; i < y_data.size(); i++) {
		std::cout << y_data[i];
		if (i < y_data.size() - 1)
			std::cout << ",";
		else
			std::cout << "]\n";
	}
	//画点
	for (size_t i = 0; i < x_data.size(); i++) {
		ml_Point point(x_data[i],y_data[i]);
		unsigned char rgb[3];
		getRandomRGB(rgb);
		if (!drawPoint(point.x, point.y, rgb)) {
			break;
		}
	}
	//最小二乘法
	/*
	X=(x1,x2,...,xm)^T
	Xd=(x1-x_avg,x2-x_avg,...)^T
	Y=(y1,y2,y3...)^T
	Yd=(y1-y_avg,...)^T
	w=(Xd^T*Yd)/(Xd^TXd)
	b=(1/m)*累加(yi-wxi)
	*/
	float XdT_Yd = 0;
	float XdT_Xd = 0;
	std::vector<float>Xd;
	std::vector<float>Yd;
	for (size_t i = 0; i < x_data.size(); i++) {
		Xd.push_back(x_data[i]-getAvg(x_data));
	}
	for (size_t i = 0; i < y_data.size(); i++) {
		Yd.push_back(y_data[i] - getAvg(y_data));
	}
	XdT_Yd = 0;
	for (size_t i = 0; i < Xd.size(); i++) {
		XdT_Yd += Xd[i] * Yd[i];
	}
	XdT_Xd = 0;
	for (size_t i = 0; i < Xd.size(); i++) {
		XdT_Xd += Xd[i] * Xd[i];
	}
	float w = XdT_Yd / XdT_Xd;
	std::cout << "\nw:" << w << std::endl;
	//求b
	float sum = 0;
	for (size_t i = 0; i < x_data.size(); i++) {
		sum += y_data[i] - w * x_data[i];
	}
	float b = sum / x_data.size();
	std::cout << "b:" << b << std::endl;
	//画函数 x*x+x
	for (float x = 0; x < 1.5; x+=0.01) {
		ml_Point point(x, w*x+b);
		unsigned char rgb[3];
		getRandomRGB(rgb);
		if (!drawPoint(point.x, point.y, rgb)) {
			break;
		}
		Sleep(1);
	}
	_getch();				
	closegraph();			
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高万禄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值