美文网首页
逻辑回归例子

逻辑回归例子

作者: leon0514 | 来源:发表于2022-07-12 09:37 被阅读0次

交叉熵推导过程

交叉熵数损失推导 - 简书 (jianshu.com)

代码

datasets.h

#ifndef DATASETS_H__
#define DATASETS_H__
#include <iostream>
#include <vector>

namespace Data
{
   struct Item
   {
       double area;
       double distance;
       int   label;    
   };
   class datasets
   {
   public:
   datasets(std::string data_path): m_data_path(data_path) 
   {
       m_mean.area = 0;
       m_mean.distance = 0;
       m_mean.label = 0;
       m_stdval.area = 0;
       m_stdval.distance = 0;
       m_stdval.label = 0;
   }
   void load_data();
   void preprocess(Item& item);
   inline std::vector<Item> get_data() const { return m_data; }
   inline Item get_mean()              const { return m_mean; }
   inline Item get_std()               const { return m_stdval; }
   
   private:
   void compute_std_mean();
   void normalization();
   
   private:
   std::string m_data_path;
   std::vector<Item> m_data;
   Item m_mean;
   Item m_stdval;
   };

   std::ostream& operator<<(std::ostream& os, datasets dt);
}
#endif

dataset.cpp

#include "datasets.h"
#include <fstream>
#include <cmath>
using namespace std;

namespace Data
{
    void datasets::datasets::load_data()
    {
        fstream ifile(datasets::m_data_path, ios::binary | ios::in); 
        string line;                                                              
        getline(ifile, line);
        while(getline(ifile, line))
        {
            int p0 = line.find(",");
            int p1 = line.find(",", p0 + 1);
            Item item;
            item.area     = atof(line.substr(0, p0).c_str());
            item.distance = atof(line.substr(p0+1, p1).c_str());
            item.label    = atof(line.substr(p1+1).c_str());
            m_data.emplace_back(item);
        }
        compute_std_mean();
        normalization();
    }

    void datasets::compute_std_mean()
    {
        for(auto& item : m_data)
        {
            m_mean.area  += item.area;
            m_mean.distance += item.distance;
        }
        m_mean.area  /= m_data.size();
        m_mean.distance /= m_data.size();

        for(auto& item : m_data)
        {
            m_stdval.area  += std::pow(item.area - m_mean.area, 2.0f);
            m_stdval.distance += std::pow(item.distance - m_mean.distance, 2.0f);;
        }
        m_stdval.area  = std::sqrt(m_stdval.area / m_data.size());
        m_stdval.distance = std::sqrt(m_stdval.distance / m_data.size());
    }

    void datasets::normalization()
    {
        /* 对数据进行减去均值除以标准差,使得均值为0,标准差为1 */
        for(auto& item : m_data)
        {
            item.area     = (item.area - m_mean.area) / m_stdval.area;
            item.distance = (item.distance - m_mean.distance) / m_stdval.distance;
        }
    }

    void datasets::preprocess(Item& item)
    {
        item.area     = (item.area - m_mean.area) / m_stdval.area;
        item.distance = (item.distance - m_mean.distance) / m_stdval.distance;
    }
    
    ostream& operator<<(ostream& os, datasets dt)
    {
        os << "-----datasets params-----" << endl;
        os << "area mean:"                << dt.get_mean().area     << endl
           << "area stdv:"                << dt.get_std().area      << endl
           << "dist mean:"            << dt.get_mean().distance << endl
           << "dist stdv:"            << dt.get_std().distance  << endl;
        return os;
    }
}

model.h

#ifndef MODEL_H__
#define MODEL_H__
#include "datasets.h"
#include <cmath>
#include <iostream>

namespace Model
{
    class model
    {
    public:
        model() : 
            m_loss(0), 
            m_k_distance(0.1), 
            m_k_area(0.1), 
            m_bias(0),
            m_delta_k_distance(0),
            m_delta_k_area(0),
            m_delta_bias(0),
                    m_lr(0.1)
            {}
        double operator()(Data::Item item);
        void back_forward(double p, Data::Item item);
        double predict();
        void step();
        void zero_grad();

        inline double get_m_k_distance() const { return m_k_distance; }
        inline double get_m_k_area() const { return m_k_area; }
        inline double get_m_bias() const { return m_bias; }
        inline double get_m_loss() const { return m_loss; }
    private:
        double forward(Data::Item item);
        inline double sigmoid(double x) const 
        {
            double eps = 1e-5;
            double p = x > 0 ?  1.0 / (1 + std::exp(-x)) :  std::exp(x) / (1 + std::exp(x));
            // 防止计算log时溢出
            p = std::max(std::min(p, 1 - eps), eps);
            return p;
        }
         
    private:
        double m_lr;

        double m_loss;
            
        double m_k_distance;
        double m_k_area;
        double m_bias;

        double m_delta_k_distance;
        double m_delta_k_area;
        double m_delta_bias;
    };

    std::ostream& operator<<(std::ostream &os, model md);
}

model.cpp

#include "model.h"
using namespace std;

namespace Model
{
    double model::operator()(Data::Item item)
    {
        return forward(item);
    }

    double model::forward(Data::Item item)
    {
        double predict = m_k_distance * item.distance + m_k_area * item.area + m_bias;
        predict = sigmoid(predict);
        return predict;
    }

    void model::back_forward(double p, Data::Item item)
    {
    // 逻辑回归交叉熵损失
        m_loss += -(item.label * log(p) + (1 - item.label)*log(1 - p));
        m_delta_k_distance += item.distance*(p - item.label);
        m_delta_k_area     += item.area*(p - item.label);
        m_delta_bias       += p - item.label;
    }

    void model::step()
    {
        m_k_distance -= m_lr * m_delta_k_distance;
        m_k_area     -= m_lr * m_delta_k_area;
        m_bias       -= m_lr * m_delta_bias;       
    }

    void model::zero_grad()
    {
        m_delta_k_distance = 0;
        m_delta_k_area     = 0;
        m_delta_bias       = 0;
        m_loss             = 0;
    }

    ostream& operator<<(ostream& os, model md)
    {
         os << "-----params-----" << endl;
         os << "m_k_distance:"    << md.get_m_k_distance() << endl
            << "m_k_area:"        << md.get_m_k_area()     << endl
            << "m_bias:"             << md.get_m_bias()       << endl;
        return os;
    }
}

main.cpp

#include "datasets.h"
#include "model.h"
#include <vector>
using namespace std;

int main()
{
    Data::datasets dt("./shanghai.csv");
    dt.load_data();
    vector<Data::Item> datas = dt.get_data();
    Model::model md;
    md.zero_grad();
    for (int i = 0; i < 1000; i++)
    {
        for (auto& item : datas)
        {
            double predict = md(item);
            md.back_forward(predict, item);
        }
        md.step();
        if (i % 100 == 0)
        {
            cout << "Iter:" << i << ", loss:" << md.get_m_loss() << endl;
        }
        md.zero_grad();
    }
    cout << dt << endl;
    cout << md << endl;

    cout << "----predict-----" << endl;
    Data::Item test{100,2000,0};
    cout << "area     is :" << test.area     << endl;
    cout << "distance is :" << test.distance << endl;

    dt.preprocess(test);
    double predict = md(test);
    if (predict > 0.5)
    {
        cout << "happy" << endl;
    }
    else
    {
        cout << "not happy" << endl;
    }
    return 0;
}

相关文章

  • 逻辑回归例子

    交叉熵推导过程 交叉熵数损失推导 - 简书 (jianshu.com)[https://www.jianshu.c...

  • 逻辑回归原理及spark例子

    之前在乐视网的时候组内有同事的挖掘工作用到逻辑回归,最近利用零散时间看了下逻辑回归的原理。主要参考了https:/...

  • CDA题目

    大纲: 应用情境例子:客户价值评估(线性回归)、贷款违约识别(逻辑回归)、不同班级的成绩差异(方差分析)、根据用户...

  • 机器学习day7-逻辑回归问题

    逻辑回归 逻辑回归,是最常见最基础的模型。 逻辑回归与线性回归 逻辑回归处理的是分类问题,线性回归处理回归问题。两...

  • ML03-逻辑回归(下部分)

    本文主题-逻辑回归(下部分):逻辑回归的应用背景逻辑回归的数学基础逻辑回归的模型与推导逻辑回归算法推导梯度下降算法...

  • ML02-逻辑回归(上部分)

    本文主题-逻辑回归(上部分):逻辑回归的应用背景逻辑回归的数学基础逻辑回归的模型与推导逻辑回归算法推导梯度下降算法...

  • tensorflow 4. 逻辑回归-mnist和softmax

    这里有一个例子演示使用softmax算法对mnist数据集做逻辑回归训练。代码在这里这里的例子与temsorflo...

  • 逻辑回归模型

    1.逻辑回归介绍2.机器学习中的逻辑回归3.逻辑回归面试总结4.逻辑回归算法原理推导5.逻辑回归(logistic...

  • Task 01|基于逻辑回归的分类预测

    知识背景 关于逻辑回归的几个问题 逻辑回归相比线性回归,有何异同? 逻辑回归和线性回归最大的不同点是逻辑回归解决的...

  • 11. 分类算法-逻辑回归

    逻辑回归 逻辑回归是解决二分类问题的利器 逻辑回归公式 sklearn逻辑回归的API sklearn.linea...

网友评论

      本文标题:逻辑回归例子

      本文链接:https://www.haomeiwen.com/subject/jnvnbrtx.html