今天没事学习c++,试着用c++实现了一个简单的逻辑回归。
因为重在学习c++语法和逻辑回归的具体实现细节,因此没有用到向量化矩阵化等操作,而是老老实实用遍历一步一步求解梯度。
代码具体实现了梯度下降、随梯度下降、批梯度下降三种学习算法。
本文仅包含代码实现部分,逻辑回归的理论可以参考:
http://blog.youkuaiyun.com/abcjennifer/article/details/7716281
代码包括两个头文件和一个cpp文件:
logisticregression.h
#ifndef _LOGISTICREGRESSION_H_
#define _LOGISTICREGRESSION_H_
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <assert.h>
struct DataSet {
int numData;
int numFeature;
std::vector<std::vector<float> > features;
std::vector<int> labels;
};
class LogisticRegression {
public:
LogisticRegression(int max_iter, float learn_rate, float tol);
~LogisticRegression();
DataSet loadData(std::string filename);
void initWeights(int length);
std::vector<float> oneSampleGrident(std::vector<float> feature, int label);
void train(DataSet* dataset, std::string gdType);
std::vector<float> getWeight();
int predict(std::vector<float> feature);
float predict_proba(std::vector<float> feature);
float score(DataSet* dataset);
private:
int maxIter_;
float learnRate_;
float tol_;
std::vector<float> weights;
};
#endif
common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
namespace common {
std::vector<std::string> Split(std::string line, char flag) {
std::vector<std::string> ret;
size_t start = 0;
size_t index = line.find_first_of(flag, start);
while (index != std::string::npos) {
ret.push_back(line.substr(start, index));
start = index + 1;
index = line.find_first_of(flag, start);
}
ret.push_back(line.substr(start, index));
return ret;
}
float Sigmoid(