逻辑回归是非常经典的分类算法,通过sigmoid非线性函数实现的二分类器,关于函数原型、分类算法原理可参考:
https://blog.csdn.net/u014258807/article/details/80616647
sigmoid函数定义为:
函数图形为:
其推导过程略,实现可参考github:https://github.com/codestorm04/Arma_ML 项目下的src/logistic/logistic_classifier.cc。
对应logistic_classifier.h 定义如下:
/*
* The entry of the module datasets
* compile with flags:
* author: Yuzhen Liu
* Date: 2019.3.24 11:59
*/
#ifndef LOGISTIC_CLASSIFIER_H
#define LOGISTIC_CLASSIFIER_H
#include
#include
#include
using namespace std;
using namespace arma;
// Implements a logistic binary classifier
class Logisitic_Classifier {
public:
Logisitic_Classifier();
// ~Logisitic_Classifier();
vec predict(mat x);
void train(mat x, vec y);
void initialize();
private:
rowvec w; // a row vector of weights
double b = 0; // bias
double lr = 0.5; // Learing rate
double delta_threshhold = 10;
int iteration = 50;
double _logistic(vec x);
double _logistic_derivative(vec x);
};
#endif // LOGISTIC_CLASSIFIER_H
logistic_classifier.cc 实现如下:
/*
* Mathmetics reference: https://blog.csdn.net/u014258807/article/details/80616647
* compile with flags: g++ logistic_classifier.cc -std=c++14 -o test -larmadillo
* author: Yuzhen Liu
* Date: 2019.3.24 11:59
*/
#include
// Implements here
Logisitic_Classifier::Logisitic_Classifier() {
// TODO: w
}
void Logisitic_Classifier::train(mat x, vec y) {
if (x.n_cols <= 0)
return;
w = rowvec(x.n_rows, fill::zeros);
for(int round =0; round < iteration; round++) {
rowvec delta_sum_w = rowvec(size(w), fill::zeros);
double delta_sum_b = 0;
for (int i = 0; i < x.n_cols; i++) {
delta_sum_b += y(i) - Logisitic_Classifier::_logistic(x.col(i));
delta_sum_w += delta_sum_b * (x.col(i)).t();
}
b += lr * as_scalar(delta_sum_b) / x.n_cols;
w += lr * delta_sum_w / x.n_cols;
// if (sum(delta_sum_w) >= delta_threshhold)
// break;
}
}
vec Logisitic_Classifier::predict(mat x) {
vec res = vec(x.n_cols);
for (int i = 0; i < x.n_cols; i++) {
res(i) = _logistic(x.col(i)) > 0.5 ? 1 : 0;
}
return res;
}
double Logisitic_Classifier::_logistic(vec x) {
return 1/(1 + exp(0 - as_scalar(w * x) - b));
}
调用方法如下example.cc:
*
* compile with flags: g++ test.cc softmax_classifier.cc ../datasets/datasets.cc -std=c++14 -larmadillo -I ../../include/
* author: Yuzhen Liu
* Date: 2019.3.29 10:55
*/
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace arma;
int main() {
Datasets dataset = Datasets("iris");
Logistic classifier testing
vec y = dataset.y.subvec(0, 99);
mat x = dataset.x.submat(0, 0, 3, 99);
Logisitic_Classifier lr_classifier = Logisitic_Classifier();
lr_classifier.train(x, y);
vec res = lr_classifier.predict(mat({{6.1, 2.9, 4.7, 1.4}, {5.1, 3.5, 1.4, 0.2}}).t());
res.print();
return 0;
}