C++实现logistic模型

使用C++实现logistic模型 

最近在上机器学习课程,刚学习了logistic模型,于是决定自己动手写一下。

 

一.类图

二.C++代码

Data.h文件

  1 #pragma once
  2 
  3 enum MyEnum
  4 {
  5     Error_Classification=-1,
  6     Fuzzy_classification,
  7     Correct_classification,
  8 };
  9 
 10 
 11 class Data
 12 {
 13 private:
 14     int X1;
 15     int X2;
 16     int sample_signal;//正样本or负样本
 17     MyEnum symbol = Error_Classification;//标记分类正确与否
 18     int  model_value; //记录模型值: w*x+b
 19     double probability_of_positive1=-1;
 20     double probability_of_negative1=-1;
 21 
 22 public:
 23     Data();
 24     Data(int x1, int x2, int sample_signal);
 25     ~Data();
 26 
 27 
 28     void set_x1(const int x1);
 29     void set_x2(const int x2);
 30     void set_sample_signal(const int sample_signal);
 31     void set_symbol(MyEnum symbol);
 32     void set_model_value(const int  model_value);
 33     void set_probability_of_positive(double positive1);
 34     void set_probability_of_negative(double negative1);
 35 
 36     int get_x1();
 37     int get_x2();
 38     int get_sample_signal();
 39     MyEnum get_symbol();
 40     int get_model_value();
 41     double get_probability_of_positive();
 42     double get_probability_of_negative();
 43 };
 44 
 45 
 46 
 47 inline Data::Data()
 48 {
 49 
 50 }
 51 
 52 Data::Data(int x1, int x2, int sample_signal)
 53 {
 54     this->X1 = x1;
 55     this->X2 = x2;
 56     this->sample_signal = sample_signal;
 57 
 58 }
 59 
 60 Data::~Data()
 61 {
 62 }
 63 
 64 
 65 
 66 inline void Data::set_x1(const int x1)
 67 {
 68     this->X1 = x1;
 69 }
 70 
 71 inline void Data::set_x2(const int x2)
 72 {
 73     this->X2 = x2;
 74 }
 75 
 76 
 77 inline void Data::set_sample_signal(const int sample_signal)
 78 {
 79     this->sample_signal = sample_signal;
 80 }
 81 
 82 
 83 inline void Data::set_symbol(MyEnum symbol)
 84 {
 85     this->symbol = symbol;
 86 }
 87 
 88 inline void Data::set_model_value(const int  model_value)
 89 {
 90     this->model_value = model_value;
 91 }
 92 
 93 inline void Data::set_probability_of_positive(double positive1)
 94 {
 95     this->probability_of_positive1 = positive1;
 96 }
 97 
 98 inline void Data::set_probability_of_negative(double negative1)
 99 {
100     this->probability_of_negative1 = negative1;
101 }
102 
103 
104 
105 inline int Data::get_x1()
106 {
107     return X1;
108 }
109 
110 inline int Data::get_x2()
111 {
112     return X2;
113 }
114 
115 inline int Data::get_sample_signal()
116 {
117     return sample_signal;
118 }
119 
120 
121 inline MyEnum Data::get_symbol()
122 {
123     return symbol;
124 }
125 
126 inline int Data::get_model_value()
127 {
128     return model_value;
129 }
130 
131 
132 inline double Data::get_probability_of_positive()
133 {
134     return  probability_of_positive1;
135 }
136 
137 inline double Data::get_probability_of_negative()
138 {
139     return  probability_of_negative1;
140 }

Train_data文件

  1 #pragma once
  2 #include"Data.h"
  3 #include<vector>
  4 #include <algorithm>  
  5 
  6 using namespace std;
  7 
  8 class Train_data
  9 {
 10 private:
 11 
 12     vector<Data> data;
 13     double Empirical_risk_value;
 14     double Structural_risk_value_of_L2;
 15     double Structural_risk_value_of_L1;
 16     double Structural_risk_value_of_Elastic_Net;
 17     static Train_data* unique_instance;
 18     Train_data();
 19 
 20 public:
 21 
 22     int judge();
 23     ~Train_data();
 24     static Train_data* getinstance();
 25     vector<Data> & get_data();
 26     double get_Empirical_risk_value();
 27     double get_Structural_risk_value_of_L2();
 28     double get_Structural_risk_value_of_L1();
 29     double get_Structural_risk_value_of_Elastic_Net();
 30 
 31     void set_Empirical_risk_value(double);
 32     void set_Structural_risk_value_of_L2(double);
 33     void set_Structural_risk_value_of_L1(double);
 34     void set_Structural_risk_value_of_Elastic_Net(double);
 35 
 36 };
 37 
 38 
 39 
 40 
 41 Train_data* Train_data::unique_instance = nullptr;
 42 
 43 
 44 Train_data::Train_data()
 45 {
 46 }
 47 
 48 Train_data::~Train_data()
 49 {
 50 }
 51 
 52 
 53 inline Train_data* Train_data::getinstance()
 54 {
 55     if (unique_instance == nullptr)
 56     {
 57         unique_instance = new Train_data();
 58     }
 59     return unique_instance;
 60 }
 61 
 62 inline vector<Data> & Train_data::get_data()
 63 {
 64     return data;
 65 }
 66 
 67 inline double Train_data::get_Empirical_risk_value()
 68 {
 69     return this->Empirical_risk_value;
 70 }
 71 
 72 inline double Train_data::get_Structural_risk_value_of_L2()
 73 {
 74     return this->Structural_risk_value_of_L2;
 75 }
 76 
 77 inline double Train_data::get_Structural_risk_value_of_L1()
 78 {
 79     return this->Structural_risk_value_of_L1;
 80 }
 81 
 82 inline double Train_data::get_Structural_risk_value_of_Elastic_Net()
 83 {
 84     return this->Structural_risk_value_of_Elastic_Net;
 85 }
 86 
 87 
 88 inline void Train_data::set_Empirical_risk_value(double empirical)
 89 {
 90     this->Empirical_risk_value = empirical;
 91 }
 92 
 93 inline void Train_data::set_Structural_risk_value_of_L2(double structural_L2)
 94 {
 95     this->Structural_risk_value_of_L2 = structural_L2;
 96 }
 97 
 98 inline void Train_data::set_Structural_risk_value_of_L1(double structural_L1)
 99 {
100     this->Structural_risk_value_of_L1 = structural_L1;
101 }
102 
103 inline void Train_data::set_Structural_risk_value_of_Elastic_Net(double structural_Elastic_Net)
104 {
105     this->Structural_risk_value_of_Elastic_Net = structural_Elastic_Net;
106 }
107 
108 
109 inline int Train_data::judge()
110 {
111     int number = 0;
112     for (int i = 0; i < data.size(); i++)
113         if (data[i].get_symbol() == Correct_classification)
114             number++;
115     return number;
116 }

Model_parameter.h文件

  1 #pragma once
  2 class Model_parameter
  3 {
  4 public:
  5 
  6     Model_parameter();
  7     Model_parameter(int w1, int w2, int b, int n, int r);
  8     ~Model_parameter();
  9 
 10 
 11     int get_w1();
 12     int get_w2();
 13     int get_B();
 14     int get_n();
 15     int get_r();
 16     void set_w1(int w1);
 17     void set_w2(int w2);
 18     void set_B(int B);
 19     void set_n(int n);
 20     void set_r(int r);
 21 
 22 private:
 23 
 24     int W1;
 25     int W2;
 26     int B;
 27     int n;
 28     int r;
 29 
 30 };
 31 
 32 
 33 
 34 
 35 Model_parameter::Model_parameter()
 36 {
 37 }
 38 
 39 Model_parameter::Model_parameter(int w1, int w2, int b, int n, int r)
 40 {
 41     this->W1 = w1;
 42     this->W2 = w2;
 43     this->B = b;
 44     this->n = n;
 45     this->r = r;
 46 }
 47 
 48 Model_parameter::~Model_parameter()
 49 {
 50 }
 51 
 52 inline int Model_parameter::get_w1()
 53 {
 54     return this->W1;
 55 }
 56 
 57 inline int Model_parameter::get_w2()
 58 {
 59     return this->W2;
 60 }
 61 
 62 inline int Model_parameter::get_B()
 63 {
 64     return this->B;
 65 }
 66 
 67 inline int Model_parameter::get_n()
 68 {
 69     return this->n;
 70 }
 71 
 72 inline int Model_parameter::get_r()
 73 {
 74     return this->r;
 75 }
 76 
 77 
 78 
 79 inline void Model_parameter::set_w1(int w1)
 80 {
 81     this->W1 = w1;
 82 }
 83 
 84 inline void Model_parameter::set_w2(int w2)
 85 {
 86     this->W2 = w2;
 87 }
 88 
 89 inline void Model_parameter::set_B(int B)
 90 {
 91     this->B = B;
 92 }
 93 
 94 inline void Model_parameter::set_n(int n)
 95 {
 96     this->n = n;
 97 }
 98 
 99 inline void Model_parameter::set_r(int r)
100 {
101     this->r = r;
102 }

Logistic.h文件

 1 #pragma once
 2 #include<iostream>
 3 #include<string>
 4 #include"Model_parameter.h"
 5 #include"Data.h"
 6 #include"Train_data.h"
 7 using namespace std;
 8 
 9 class Logistic
10 {
11 private:
12     string  description;
13 
14 public:
15     Logistic();
16     ~Logistic();
17 
18     //ostream&  operator <<(ostream& ostr, const Perceptron& x);
19 
20 
21     string get_Description() {}
22     virtual void  caculate(int n) {};
23     virtual void  caculate() {};
24     virtual void display() {}
25     virtual void set_functional_margin(const int value, const int n) {}
26     virtual int* get_functional_margin() { return nullptr; }
27     virtual Model_parameter* get_Weight_and_bias_and_step() { return nullptr; }
28 
29 };
30 
31 
32 
33 Logistic::Logistic()
34 {
35     this->description = "This is a Logistic class";
36 }
37 
38 Logistic::~Logistic()
39 {
40 
41 
42 }

Logistic_entity.h文件

  1 #pragma once
  2 #include"Logistic.h"
  3 #include <cstdlib>
  4 
  5 class Logistic_entity : public  Logistic
  6 {
  7 private:
  8    Model_parameter *Weight_and_bias_and_step;
  9 
 10 public:
 11 
 12     Logistic_entity(int w1, int w2, int b, int n, int r);
 13     ~Logistic_entity();
 14 
 15     string get_Description();
 16     void caculate();
 17     void display();
 18     Model_parameter* get_Weight_and_bias_and_step();
 19 
 20    // friend void modify(Logistic *logit,int r);  //友元函数
 21 };
 22 
 23 //void modify(Logistic* logit, int r)
 24 //{
 25 //    logit->get_Weight_and_bias_and_step()->set_r(r);
 26 //}
 27 
 28 
 29 
 30 
 31 
 32 inline Logistic_entity::Logistic_entity(int w1, int w2, int b, int n, int r)
 33 {
 34     cout << "init" << endl;
 35     Weight_and_bias_and_step = new Model_parameter();
 36     Weight_and_bias_and_step->set_w1(w1);
 37     Weight_and_bias_and_step->set_w2(w2);
 38     Weight_and_bias_and_step->set_B(b);
 39     Weight_and_bias_and_step->set_n(n);
 40     Weight_and_bias_and_step->set_r(r);
 41  
 42     cout << Weight_and_bias_and_step->get_w1() << endl;
 43     cout << Weight_and_bias_and_step->get_w2() << endl;
 44     cout << Weight_and_bias_and_step->get_B() << endl;
 45     cout << Weight_and_bias_and_step->get_n() << endl;
 46     cout << Weight_and_bias_and_step->get_r() << endl;
 47 }
 48 
 49 
 50 Logistic_entity::~Logistic_entity()
 51 {
 52     delete  Weight_and_bias_and_step;
 53 }
 54 
 55 
 56 inline string Logistic_entity::get_Description()
 57 {
 58     return string();
 59 }
 60 
 61 
 62 inline void Logistic_entity::caculate()
 63 {
 64 
 65     Train_data* sample = Train_data::getinstance();
 66     for (int i = 0; i < sample->get_data().size(); i++)
 67         sample->get_data()[i].set_model_value((sample->get_data())[i].get_x1() * Weight_and_bias_and_step->get_w1() + (sample->get_data())[i].get_x2() * Weight_and_bias_and_step->get_w2() + Weight_and_bias_and_step->get_B());
 68 
 69     //if (temp >= 0)
 70     //    model_value = 1;
 71     //else
 72     //    model_value = -1;
 73 
 74 }
 75 
 76 
 77 inline Model_parameter* Logistic_entity::get_Weight_and_bias_and_step()
 78 {
 79     return Weight_and_bias_and_step;
 80 }
 81 
 82 
 83 
 84 
 85 
 86 inline void Logistic_entity::display()
 87 {
 88     //int j = 0;
 89    // Train_data* sample = Train_data::getinstance();
 90     cout << " print Weight_and_bias_and_step " << endl;
 91 
 92     cout << "W1: " << Weight_and_bias_and_step->get_w1() << endl;
 93     cout << "W2: " << Weight_and_bias_and_step->get_w2() << endl;
 94     cout << "B: " << Weight_and_bias_and_step->get_B() << endl;
 95     cout << "n: " << Weight_and_bias_and_step->get_n() << endl;
 96     cout << "r: " << Weight_and_bias_and_step->get_r() << endl;
 97 
 98 
 99 
100 }

Suan_fa.h文件

 1 #pragma once
 2 #include"Logistic.h"
 3 #include<math.h>
 4 class Suan_fa : public Logistic
 5 {
 6 private:
 7 
 8 public:
 9     Suan_fa();
10     ~Suan_fa();
11 };
12 
13 Suan_fa::Suan_fa()
14 {
15 }
16 
17 Suan_fa::~Suan_fa()
18 {
19 }

Function.h文件

 1 #pragma once
 2 #include"Suan_fa.h"
 3 
 4 
 5 class Function : public Suan_fa
 6 {
 7 private:
 8     Logistic* logistic;
 9 public:
10     Function(Logistic* entity);
11     ~Function();
12 
13     void  caculate(int n);
14     void  display();
15 };
16 
17 
18 
19 Function::Function(Logistic* entity)
20 {
21     this->logistic = entity;
22 }
23 
24 Function::~Function()
25 {
26 
27 }
28 
29 inline void Function::caculate(int n)
30 {
31     double positive;
32     double negative;
33     double r;
34     cout << " print origin samples " << endl;
35     cout << " number= "<<n << endl;
36     
37     Train_data* sample = Train_data::getinstance();
38     logistic->caculate();
39     r = logistic->get_Weight_and_bias_and_step()->get_r();
40 
41     cout << " x1= " <<sample->get_data()[n].get_x1() << endl;
42     cout << " x2= " <<sample->get_data()[n].get_x2() << endl; 
43 
44     cout << " model_value= " << sample->get_data()[n].get_model_value() << endl;
45     positive = 1 / (1 + exp(-sample->get_data()[n].get_model_value() / r));
46     negative = exp(-sample->get_data()[n].get_model_value() / r) / (1 + exp(-sample->get_data()[n].get_model_value() / r));
47     cout << " positive= " << positive << endl;
48     cout << " negative= " << negative << endl;
49     sample->get_data()[n].set_probability_of_positive(positive);
50     sample->get_data()[n].set_probability_of_negative(negative);
51     if (positive > negative)
52     {
53         if (sample->get_data()[n].get_sample_signal() == 1)
54             sample->get_data()[n].set_symbol(Correct_classification);
55         else
56             sample->get_data()[n].set_symbol(Error_Classification);
57     }
58     if (positive <= negative)
59     {
60         if (sample->get_data()[n].get_sample_signal() == -1)
61             sample->get_data()[n].set_symbol(Correct_classification);
62         else
63             sample->get_data()[n].set_symbol(Error_Classification);
64     }
65 
66 }
67 
68 
69 inline void Function::display()
70 {
71     logistic->display();
72   
73 }

Optimize.h文件

 1 #pragma once
 2 #include"Suan_fa.h"
 3 
 4 class Optimize :public Suan_fa
 5 {
 6 private:
 7     Logistic* logistic;
 8 public:
 9     Optimize(Logistic* entity);
10     ~Optimize();
11 
12     void  caculate(int n);
13     void  display();
14 };
15 
16 
17 
18 Optimize::Optimize(Logistic* entity)
19 {
20     this->logistic = entity;
21 }
22 
23 Optimize::~Optimize()
24 {
25 }
26 
27 
28 inline void Optimize::caculate(int n)
29 {
30     cout << " print functional_margin " << endl;
31     Train_data* sample = Train_data::getinstance();
32     if (sample->get_data()[n].get_symbol() == Error_Classification)
33     {
34         logistic->get_Weight_and_bias_and_step()->set_w1(logistic->get_Weight_and_bias_and_step()->get_w1() + logistic->get_Weight_and_bias_and_step()->get_n() * (sample->get_data())[n].get_sample_signal() * (sample->get_data())[n].get_x1());
35         logistic->get_Weight_and_bias_and_step()->set_w2(logistic->get_Weight_and_bias_and_step()->get_w2() + logistic->get_Weight_and_bias_and_step()->get_n() * (sample->get_data())[n].get_sample_signal() * (sample->get_data())[n].get_x2());
36         logistic->get_Weight_and_bias_and_step()->set_B(logistic->get_Weight_and_bias_and_step()->get_B() + logistic->get_Weight_and_bias_and_step()->get_n() * (sample->get_data())[n].get_sample_signal());
37     }
38 
39 }
40 
41 
42 
43 inline void Optimize::display()
44 {
45     logistic->display();
46 }

Analytic_Function.h文件

 1 #pragma once
 2 #include"Suan_fa.h"
 3 #include"Logistic_entity.h"
 4 
 5 class Analytic_Function: public Suan_fa
 6 {
 7 public:
 8     Analytic_Function(Logistic *entity);
 9     ~Analytic_Function();
10     void reinstall(int r);
11 private:
12     Logistic* logistic;
13 };
14 
15 
16 Analytic_Function::Analytic_Function(Logistic* entity)
17 {
18     this->logistic = entity;
19 }
20 
21 Analytic_Function::~Analytic_Function()
22 {
23 }
24 
25 inline void Analytic_Function::reinstall(int r)
26 {
27     modify(logistic,r);
28 }

Risk_function.h文件

 1 #pragma once
 2 #include"Suan_fa.h"
 3 
 4 class Risk_function: public Suan_fa
 5 {
 6 public:
 7     Risk_function();
 8     ~Risk_function();
 9 
10 private:
11 
12 };
13 
14 
15 Risk_function::Risk_function()
16 {
17 }
18 
19 Risk_function::~Risk_function()
20 {
21 }

Empirical_risk_function.h文件

 1 #pragma once
 2 #include"Risk_function.h"
 3 
 4 class Empirical_risk_function: public Risk_function
 5 {
 6 public:
 7     Empirical_risk_function(Logistic *entity);
 8     ~Empirical_risk_function();
 9     string get_Description();
10     void  caculate( );
11     void  display();
12 
13 private:
14     string  description;
15     Logistic *logistic;
16 };
17 
18 
19 
20 Empirical_risk_function::Empirical_risk_function(Logistic* entity)
21 {
22     this->logistic = entity;
23     this->description = "This is a Risk_function class.";
24 }
25 
26 Empirical_risk_function::~Empirical_risk_function()
27 {
28 }
29 
30 inline string Empirical_risk_function::get_Description()
31 {
32     return this->description;
33 }
34 
35 inline void Empirical_risk_function::caculate()
36 {
37     int N = 0;
38     double total = 0;
39     double r = 0.0;
40     Train_data* sample = Train_data::getinstance();
41     r = logistic->get_Weight_and_bias_and_step()->get_r();
42     N = sample->get_data().size();
43     for (int i = 0; i < N; i++)
44     {
45         total += log10(1 + exp(-sample->get_data()[i].get_sample_signal() * (sample->get_data()[i].get_model_value() / r))) / log10(2);
46     }
47     sample->set_Empirical_risk_value(total / N);
48 }
49 
50 inline void Empirical_risk_function::display()
51 {
52 }

Structtural_risk_function.h文件

 1 #pragma once
 2 #include"Risk_function.h"
 3 
 4 class Structural_risk_function: public Risk_function
 5 {
 6 public:
 7     Structural_risk_function (Logistic* entity);
 8     ~Structural_risk_function ();
 9     void  caculate();
10     void  display();
11 private:
12     Logistic* logistic;
13     string  description;
14     int L2_norm;   //正则化项L2
15     int L1_norm;   //正则化项L1
16     int Elastic_Net;   //正则化项Elastic_Net
17     double normalizing_factor=1;   //正则化因子
18     double p = 0.6;   //弹性网因子
19 };
20 
21 
22 
23 
24 
25 Structural_risk_function::Structural_risk_function(Logistic* entity)
26 {
27     this->logistic = entity;
28     this->description = "This is a Structural_risk_function class.";
29 }
30 
31 Structural_risk_function ::~Structural_risk_function()
32 {
33 }
34 
35 inline void Structural_risk_function::caculate()
36 {
37     int total_L2 = 0, total_L1 = 0, total_Elastic_Net = 0;
38 
39     Train_data* sample = Train_data::getinstance();
40     total_L2 += pow((logistic->get_Weight_and_bias_and_step()->get_w1()), 2);
41     total_L2 += pow((logistic->get_Weight_and_bias_and_step()->get_w2()), 2);
42     L2_norm = total_L2;
43     sample->set_Structural_risk_value_of_L2(sample->get_Empirical_risk_value() + normalizing_factor * total_L2);
44 
45 
46     total_L1 += fabs(logistic->get_Weight_and_bias_and_step()->get_w1());
47     total_L1 += fabs(logistic->get_Weight_and_bias_and_step()->get_w2());
48     L1_norm = total_L1;
49     sample->set_Structural_risk_value_of_L1(sample->get_Empirical_risk_value() + normalizing_factor * total_L1);
50 
51     Elastic_Net = p * L1_norm + (1 - p) * L2_norm;
52     sample->set_Structural_risk_value_of_Elastic_Net(sample->get_Empirical_risk_value() + normalizing_factor * Elastic_Net);
53 }
54 
55 inline void Structural_risk_function::display()
56 {
57 }

main.cpp文件

 1  1 #include"Function.h"
 2  2 #include"Optimize.h"
 3  3 #include"Logistic_entity.h"
 4  4 
 5  5 
 6  6 
 7  7 int main()
 8  8 {
 9  9     int loop_number = 1;
10 10     int number = 0;                 
11 11     Train_data* samples = Train_data::getinstance();
12 12     Logistic * Entity = new Logistic_entity(0,0,0,1,1);
13 13     samples->get_data().push_back(Data(3,3,1));
14 14     samples->get_data().push_back(Data(4,3,1));
15 15     samples->get_data().push_back(Data(1,1,-1));
16 16     cout << "13123124" << endl;
17 17     cout << samples->judge() << endl;
18 18     cout << samples->get_data().size() << endl;
19 19     cout << "----------------------start-------------------------"<< endl;
20 20     cout << "-----------------------------------------------"<< endl;
21 21 
22 22     while (samples->judge() != samples->get_data().size())
23 23     {
24 24         cout <<"judge:"<< samples->judge() << endl;
25 25         cout <<"number:"<< number << endl;
26 26         cout << samples->get_data()[number].get_probability_of_positive() << endl;
27 27         cout << samples->get_data()[number].get_probability_of_negative() << endl;
28 28         cout << samples->get_data()[number].get_symbol() << endl;
29 29         cout <<"------1111111111111111111111111111-----------------------" << endl;
30 30         Function entity(Entity);
31 31         entity.caculate(number);
32 32         entity.display();
33 33         cout << samples->get_data()[number].get_probability_of_positive() << endl;
34 34         cout << samples->get_data()[number].get_probability_of_negative() << endl;
35 35         cout << samples->get_data()[number].get_symbol() << endl;
36 36 
37 37         cout << "------2222222222222222222222222-----------------------" << endl;
38 38         Optimize optimize(Entity);
39 39         optimize.caculate(number);
40 40         cout << " print the Weight_and_bias_and_step after optimize " << endl;
41 41         optimize.display();
42 42 
43 43         cout << "-------333333333333333333333333----------------------" << endl;
44 44         loop_number++;
45 45         if (number == (samples->get_data().size()-1))
46 46             number = number % (samples->get_data().size()-1);
47 47         else
48 48             number++;
49 49     }
50 50 
51 51     return 0;
52 52 }

原文地址:https://www.cnblogs.com/liweikuan/p/14696592.html