当前位置:   article > 正文

一元线性回归计算·Cpp实现_c++写一元线性回归

c++写一元线性回归

一、直接上代码!

  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <cmath>
  5. class LinearRegression
  6. {
  7. private:
  8. int k;
  9. double* data_a;
  10. double* data_b;
  11. double x_average;
  12. bool x_average_mark;
  13. double y_average;
  14. bool y_average_mark;
  15. double xy_average;
  16. bool xy_average_mark;
  17. double xx_average;
  18. bool xx_average_mark;
  19. double yy_average;
  20. bool yy_average_mark;
  21. double a;
  22. bool a_mark;
  23. double b;
  24. bool b_mark;
  25. double r;
  26. bool r_mark;
  27. double u_a;
  28. bool u_a_mark;
  29. double u_b;
  30. bool u_b_mark;
  31. double u_c;
  32. bool u_c_mark;
  33. double u_d;
  34. bool u_d_mark;
  35. void cal_x_average();
  36. void cal_y_average();
  37. void cal_xy_average();
  38. void cal_xx_average();
  39. void cal_yy_average();
  40. void pri_cal_u_a();
  41. void pri_cal_u_b();
  42. void pri_cal_u_c();
  43. void pri_cal_u_d();
  44. public:
  45. LinearRegression(int p_k);
  46. ~LinearRegression();
  47. bool accuire_data(std::string& file_name);
  48. void reverse_data(std::string choice="a");
  49. double cal_a();
  50. double cal_b();
  51. double cal_r();
  52. double cal_u_a();
  53. double cal_u_b();
  54. double cal_u_c();
  55. double cal_u_d();
  56. };
  57. int main(int argc,char** argv)
  58. {
  59. //本程序有两个参数,第一个参数为k,第二个参数为数据文件(txt格式)
  60. if (argc!=3)
  61. return 1;
  62. std::string length_string=(std::string)argv[1];
  63. std::string name_string=(std::string)argv[2];
  64. //创建一个自定义的LinearRegression类的对象实例example
  65. LinearRegression example(std::stoi(length_string));
  66. //获取数据,调用accuire_data方法
  67. example.accuire_data(name_string);
  68. //将因变量组的所有元素取倒数
  69. //这个函数用于自变量或因变量组的所有元素取倒数
  70. //参数为"a",则对自变量组取倒数;参数为"b",则对因变量组取倒数。
  71. //如果不需要取倒数,直接注释这一行即可。
  72. //example.reverse_data("b");
  73. //调用cal_a方法计算a
  74. std::cout<<"a:"<<example.cal_a()<<std::endl;
  75. //调用cal_b方法计算b
  76. std::cout<<"b:"<<example.cal_b()<<std::endl;
  77. //调用cal_r方法计算r
  78. std::cout<<"r:"<<example.cal_r()<<std::endl;
  79. //调用cal_u_a方法计算a的A类不确定度
  80. std::cout<<"u_a(a):"<<example.cal_u_a()<<std::endl;
  81. //调用cal_u_b方法计算b的A类不确定度
  82. std::cout<<"u_a(b):"<<example.cal_u_b()<<std::endl;
  83. //调用cal_u_c方法计算a的B类不确定度
  84. std::cout<<"u_b(a):"<<example.cal_u_c()<<std::endl;
  85. //调用cal_u_d方法计算b的B类不确定度
  86. std::cout<<"u_b(b):"<<example.cal_u_d()<<std::endl;
  87. //以上7个方法均可以单独使用。
  88. //我已经把可能存在的问题解决了!
  89. }
  90. LinearRegression::LinearRegression(int p_k)
  91. {
  92. k=p_k;
  93. data_a=new double [k];
  94. data_b=new double [k];
  95. x_average_mark=false;
  96. y_average_mark=false;
  97. xy_average_mark=false;
  98. xx_average_mark=false;
  99. yy_average_mark=false;
  100. a_mark=false;
  101. b_mark=false;
  102. r_mark=false;
  103. u_a_mark=false;
  104. u_b_mark=false;
  105. u_c_mark=false;
  106. u_d_mark=false;
  107. }
  108. LinearRegression::~LinearRegression()
  109. {
  110. delete [] data_a;
  111. delete [] data_b;
  112. }
  113. bool LinearRegression::accuire_data(std::string& file_name)
  114. {
  115. using namespace std;
  116. ifstream file(file_name);
  117. string double_string;
  118. char ch;
  119. int j;
  120. if (file.is_open())
  121. {
  122. for (int i=0;i<k;i++)
  123. {
  124. j=0;
  125. double_string="";
  126. while(1)
  127. {
  128. ch=file.get();
  129. if (ch>='0'&&ch<='9'||ch=='.')
  130. double_string[j++]=ch;
  131. else
  132. break;
  133. }
  134. data_a[i]=std::stod(double_string);
  135. }
  136. for (int i=0;i<k;i++)
  137. {
  138. j=0;
  139. double_string="";
  140. while(1)
  141. {
  142. ch=file.get();
  143. if (ch>='0'&&ch<='9'||ch=='.')
  144. double_string[j++]=ch;
  145. else
  146. break;
  147. }
  148. data_b[i]=std::stod(double_string);
  149. }
  150. return true;
  151. }
  152. else
  153. {
  154. return false;
  155. }
  156. }
  157. void LinearRegression::reverse_data(std::string choice)
  158. {
  159. if (choice=="a")
  160. for (int i=0;i<k;i++)
  161. data_a[i]=1/data_a[i];
  162. else if (choice=="b")
  163. for (int i=0;i<k;i++)
  164. data_b[i]=1/data_b[i];
  165. }
  166. void LinearRegression::cal_x_average()
  167. {
  168. if (x_average_mark==false)
  169. {
  170. double sum=0;
  171. for (int i=0;i<k;i++)
  172. sum+=data_a[i];
  173. x_average=sum/k;
  174. x_average_mark=true;
  175. }
  176. }
  177. void LinearRegression::cal_y_average()
  178. {
  179. if (y_average_mark==false)
  180. {
  181. double sum=0;
  182. for (int i=0;i<k;i++)
  183. sum+=data_b[i];
  184. y_average=sum/k;
  185. y_average_mark=true;
  186. }
  187. }
  188. void LinearRegression::cal_xy_average()
  189. {
  190. if (xy_average_mark==false)
  191. {
  192. double sum=0;
  193. for (int i=0;i<k;i++)
  194. sum+=data_a[i]*data_b[i];
  195. xy_average=sum/k;
  196. xy_average_mark=true;
  197. }
  198. }
  199. void LinearRegression::cal_xx_average()
  200. {
  201. if (xx_average_mark==false)
  202. {
  203. double sum=0;
  204. for (int i=0;i<k;i++)
  205. sum+=data_a[i]*data_a[i];
  206. xx_average=sum/k;
  207. xx_average_mark=true;
  208. }
  209. }
  210. void LinearRegression::cal_yy_average()
  211. {
  212. if (yy_average_mark==false)
  213. {
  214. double sum=0;
  215. for (int i=0;i<k;i++)
  216. sum+=data_b[i]*data_b[i];
  217. yy_average=sum/k;
  218. yy_average_mark=true;
  219. }
  220. }
  221. double LinearRegression::cal_a()
  222. {
  223. if (a_mark==false)
  224. {
  225. this->cal_y_average();
  226. this->cal_x_average();
  227. this->cal_b();
  228. a=y_average-b*x_average;
  229. a_mark=true;
  230. }
  231. return a;
  232. }
  233. double LinearRegression::cal_b()
  234. {
  235. if (b_mark==false)
  236. {
  237. this->cal_x_average();
  238. this->cal_y_average();
  239. this->cal_xy_average();
  240. this->cal_xx_average();
  241. b=(x_average*y_average-xy_average)/(x_average*x_average-xx_average);
  242. b_mark=true;
  243. }
  244. return b;
  245. }
  246. double LinearRegression::cal_r()
  247. {
  248. if (r_mark==false)
  249. {
  250. this->cal_x_average();
  251. this->cal_y_average();
  252. this->cal_xy_average();
  253. this->cal_xx_average();
  254. this->cal_yy_average();
  255. r=(xy_average-x_average*y_average)/sqrt((xx_average-x_average*x_average)*(yy_average-y_average*y_average));
  256. r_mark=true;
  257. }
  258. return r;
  259. }
  260. void LinearRegression::pri_cal_u_b()
  261. {
  262. if (u_b_mark==false)
  263. {
  264. u_b=b*sqrt((1/(r*r)-1)/(k-2));
  265. u_b_mark=true;
  266. }
  267. }
  268. void LinearRegression::pri_cal_u_a()
  269. {
  270. this->pri_cal_u_b();
  271. if (u_a_mark==false)
  272. {
  273. u_a=sqrt(xx_average)*u_b;
  274. u_a_mark=true;
  275. }
  276. }
  277. void LinearRegression::pri_cal_u_c()
  278. {
  279. this->pri_cal_u_d();
  280. if (u_c_mark==false)
  281. {
  282. u_c=sqrt(xx_average)*u_d;
  283. u_c_mark=true;
  284. }
  285. }
  286. void LinearRegression::pri_cal_u_d()
  287. {
  288. if (u_d_mark==false)
  289. {
  290. double u_b_y;
  291. std::cout<<"Please input the type B evaluation of uncertainty of dependent variable --- y:"<<std::endl;
  292. std::cout<<"(Attention! Do not forget the confidence coefficient)"<<std::endl;
  293. std::cin>>u_b_y;
  294. u_d=u_b_y*sqrt(1/(k*(xx_average-x_average*x_average)));
  295. u_d_mark=true;
  296. }
  297. }
  298. double LinearRegression::cal_u_a()
  299. {
  300. this->pri_cal_u_a();
  301. return u_a;
  302. }
  303. double LinearRegression::cal_u_b()
  304. {
  305. this->pri_cal_u_b();
  306. return u_b;
  307. }
  308. double LinearRegression::cal_u_c()
  309. {
  310. this->pri_cal_u_c();
  311. return u_c;
  312. }
  313. double LinearRegression::cal_u_d()
  314. {
  315. this->pri_cal_u_d();
  316. return u_d;
  317. }

二、使用注意事项

1、基本使用方法

复制上面这个代码段到新的cpp文件后编译。

2、C++11标准

由于调用了string库中的std::stod()函数,所以需要以C++11标准对此cpp文件进行编译。

具体方法可以参考:
DEV c++中添加c++11编译环境_devcpp支持c11_中国“名猿”的博客-CSDN博客

3、数据文件

该程序运行依赖数据文件(txt格式), 把数据文件和cpp原文件放在一个文件夹里!

并且,数据文件需要按如下方式处理:
 

假设数据量为k,则需要输入2k组double型数据。数据与数据之间用任意单个空格符/换行符分割!

4、运行参数

本程序有两个参数,第一个参数为k,第二个参数为数据文件(txt格式)。运行参数可以如下输入:

5 test.txt

 其中前者为数据量,后者为数据文件名称。

具体如何添加运行参数,可以参考下面这一篇文章:
关于devc++中程序运行参数的输入问题_如何用dev运行命令行参数_yupl的博客-CSDN博客

又或者,你可以直接用控制台!

5、类方法

一共包含了9个公有类方法。其中第一个方法必须是accuire_data,用于获取数据;第二个方法可以选择按照自身需求对数据取倒数(也可以不执行!看你的需要!)

其他7个方法可以按照任意顺序调用。

三、写在后面

所有的函数和变量都被封装在了LinearRegression类中。欢迎各位大神继承这个类编写更多功能,也欢迎直接大刀阔斧地改写这个类!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/683675
推荐阅读
相关标签
  

闽ICP备14008679号