机器学习算法——逻辑回归(logistic regression)(原理与实现)

基本概念

逻辑回归是一种广义的线性回归,常用于数据挖掘,疾病自动诊断,经济预测等领域。例如,探讨引发疾病的危险因素,并根据危险因素预测疾病发生的概率等。对于一个回归问题,给定的d个属性描述x=(x1;x2;x3;...;xd)所形成的的

                                                                             f(x)=\omega ^{T}x+b

那么我们实际上是去估计这里的 \omega 和 b.

对于逻辑回归来说, 自变量既可以是连续的,也可以是分类的。多重线性回归直接的目标函数是包含了f(x)的最小二乘表达式,而logistic回归则是通过一个隐状态 p=\Gamma (f(x)),根据 p 和 1-p的大小决定因变量的值。

其中如果\Gamma(*)如果是对数几率函数则为logistic回归,如果是多项式函数就是多项式回归。

logistic回归的因变量可以是二分类的,也可以是多分类的,但是二分类的logistic回归用的更多。

一般来说,logistic回归的损失函数和阶跃响应函数很像,我们称为sigmode函数或者是对数几率函数,这个函数在神经网络的权值更新中也用的比较多,即

                                                                            \Gamma =\frac{1}{1+e^{-y}}

其中,y=f(x)。函数图像如下:

Logistic回归模型的适用条件

1 因变量为二分类的分类变量或某事件的发生率,并且是数值型变量。但是需要注意,重复计数现象指标不适用于Logistic回归。

2 残差和因变量都要服从二项分布。二项分布对应的是分类变量,所以不是正态分布,进而不是用最小二乘法,而是最大似然法来解决方程估计和检验问题。

3 自变量和Logistic概率是线性关系

4 各观测对象间相互独立。

实现问题

从实现语言上讲,matlab可以用回归函数包,python实现也比较多

楼主最近偏爱java,写个java实现吧。

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

 class Instance { //read data format
    public int label;
    public int[] x;

    public Instance(int label, int[] x) {
        this.label = label;
        this.x = x;
    }

    public int getLabel() {
        return label;
    }

    public int[] getX() {
        return x;
    }
}


public class Logistic {

    /** the learning rate */
    private double rate;

    /** the weight to learn */
    private double[] weights;

    /** the number of iterations */
    private int ITERATIONS = 3000;

    public Logistic(int n) {
        this.rate = 0.0001;
        weights = new double[n];
    }

    private double sigmoid(double z) {
        return 1 / (1 + Math.exp(-z));
    }

    public void train(List<Instance> instances) {
        for (int n=0; n<ITERATIONS; n++) {
            double lik = 0.0;
            for (int i=0; i<instances.size(); i++) {
                int[] x = instances.get(i).getX();
                double predicted = classify(x);
                int label = instances.get(i).getLabel();
                for (int j=0; j<weights.length; j++) {
                    weights[j] = weights[j] + rate * (label - predicted) * x[j];
                }
                // not necessary for learning
                lik += label * Math.log(classify(x)) + (1-label) * Math.log(1- classify(x));
            }
            System.out.println("iteration: " + n + " " + Arrays.toString(weights) + " mle: " + lik);
        }
    }

    private double classify(int[] x) {
        double logit = .0;
        for (int i=0; i<weights.length;i++)  {
            logit += weights[i] * x[i];
        }
        return sigmoid(logit);
    }


    
}

实现的机制很简单,大家代码应该也容易看的懂吧。

最后想说逻辑回归看似是个回归问题,实际则是一个分类问题。

猜你喜欢

转载自blog.csdn.net/xieedun9158/article/details/81623727