使用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 }