基于weka手工实现逻辑斯谛回归(Logistic回归)

这篇具有很好参考价值的文章主要介绍了基于weka手工实现逻辑斯谛回归(Logistic回归)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、logistic回归模型

逻辑斯谛回归模型其实是一种分类模型,这里实现的是参考李航的《统计机器学习》以及周志华的《机器学习》两本教材来整理实现的。

假定我们的输入为 x x x x x x 可以是多个维度的,我们想要根据 x x x 去预测 y y y y ∈ { 0 , 1 } y\in \{0,1\} y{0,1}。逻辑斯谛的模型如下:

p ( Y = 1 ∣ x ) = e x p ( w ⋅ x ) 1 + e x p ( w ⋅ x ) (1) p(Y=1|x)=\frac{exp(w\cdot x)}{1+exp(w\cdot x)}\tag{1} p(Y=1∣x)=1+exp(wx)exp(wx)(1)

其中的参数 w w w就是我们要进行学习的,注意:它是包含了权重系数和偏置(bias)b的。在书写程序时,这样表示更加简洁。

二、极大似然法参数估计

参数 w w w是我们需要学习的,我们采用极大似然法估计模型参数。

设:

P ( Y = 1 ∣ x ) = π ( x ) , P ( Y = 0 ∣ x ) = 1 − π ( x ) (2) P(Y=1|x)=\pi(x),\quad P(Y=0|x)=1-\pi(x)\tag{2} P(Y=1∣x)=π(x),P(Y=0∣x)=1π(x)(2)

似然函数为:

∏ i = 1 N [ π ( x i ) ] y i [ 1 − π ( x i ) ] 1 − y i (3) \prod_{i=1}^N[\pi(x_i)]^{y_i}[1-\pi(x_i)]^{1-y_i} \tag{3} i=1N[π(xi)]yi[1π(xi)]1yi(3)

因为这种指数的形式不利于求导我们需要将它们转化为对数的形式,如下:

L ( w ) = ∑ i = 1 N [ y i l o g π ( x i ) + ( 1 − y i ) l o g ( 1 − π ( x i ) ) ] = ∑ i = 1 N [ y i l o g ( π ( x i ) 1 − π ( x i ) ) + l o g ( 1 − π ( x i ) ) ] = ∑ i = 1 N [ y i ( w ⋅ x i ) − l o g ( 1 + e x p ( w ⋅ x i ) ) ] (4) \begin{aligned} L(w)=&\sum_{i=1}^N[y_ilog\pi(x_i)+(1-y_i)log(1-\pi(x_i))] \\ =&\sum_{i=1}^N [y_ilog(\frac{\pi(x_i)}{1-\pi(x_i)})+log(1-\pi(x_i))]\\ =&\sum_{i=1}^{N}[y_i(w\cdot x_i)-log(1+exp(w\cdot x_i))] \end{aligned} \tag{4} L(w)===i=1N[yilogπ(xi)+(1yi)log(1π(xi))]i=1N[yilog(1π(xi)π(xi))+log(1π(xi))]i=1N[yi(wxi)log(1+exp(wxi))](4)

L ( w ) L(w) L(w)求极大值,得到 w w w的估计值。

三、梯度下降法求解似然函数

梯度下降法是求极小值的,而我们想要得到的是 L ( w ) L(w) L(w)的最大值,因此,我们取 L ( w ) L(w) L(w)的相反数,即:

arg min ⁡ w − L ( w ) (5) \argmin_{w}-L(w) \tag{5} wargminL(w)(5)

L ( w ) L(w) L(w)关于 w w w求导,如下:

( − L ( w ) ) ′ = − ∑ i = 1 N [ ( y i ⋅ x i ) − e x p ( w ⋅ x i ) 1 + e x p ( w ⋅ x ) ⋅ x i ] = − ∑ i = 1 N [ ( y i − e x p ( w ⋅ x i ) 1 + e x p ( w ⋅ x ) ) ⋅ x i ] = ∑ i = 1 N [ ( e x p ( w ⋅ x i ) 1 + e x p ( w ⋅ x ) − y i ) ⋅ x i ] (6) \begin{aligned} (-L(w))'=&-\sum_{i=1}^N[(y_i\cdot x_i)-\frac{exp(w\cdot x_i)}{1+exp(w\cdot x)}\cdot x_i]\\ =&-\sum_{i=1}^N[(y_i-\frac{exp(w\cdot x_i)}{1+exp(w\cdot x)})\cdot x_i]\\ =&\sum_{i=1}^N[(\frac{exp(w\cdot x_i)}{1+exp(w\cdot x)}-y_i)\cdot x_i] \end{aligned} \tag{6} (L(w))===i=1N[(yixi)1+exp(wx)exp(wxi)xi]i=1N[(yi1+exp(wx)exp(wxi))xi]i=1N[(1+exp(wx)exp(wxi)yi)xi](6)

然后我们就得到了参数 w w w的更新公式,如下:

w ′ = w − l r ⋅ ( − L ( w ) ′ ) = w − l r ⋅ ( ∑ i = 1 N [ ( e x p ( w ⋅ x i ) 1 + e x p ( w ⋅ x ) − y i ) ⋅ x i ] ) (7) \begin{aligned} w'=&w-lr\cdot(-L(w)')\\ =&w-lr\cdot(\sum_{i=1}^N[(\frac{exp(w\cdot x_i)}{1+exp(w\cdot x)}-y_i)\cdot x_i]) \end{aligned} \tag{7} w==wlr(L(w))wlr(i=1N[(1+exp(wx)exp(wxi)yi)xi])(7)

关于优化方法的选择,最开始是选择西瓜书上提供的牛顿法来实现的,牛顿法的好处是,可以获得较快的收敛速度,但是坏处是,当海森矩阵为奇异矩阵时,会出现无法求解的情况。

因此,可以采用拟牛顿法进行优化,在解决这个问题的同时,也可以很快的收敛。

但是,自己对拟牛顿法并不熟悉,而梯度下降法虽然收敛可能较慢,但是实现起来较为简单,因此这里采用了梯度下降法来优化似然函数。文章来源地址https://www.toymoban.com/news/detail-553021.html

四、基于weka的代码实现

package weka.classifiers.myf;

import weka.classifiers.Classifier;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.matrix.Matrix;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.NominalToBinary;
import weka.filters.unsupervised.attribute.Standardize;

import java.util.Arrays;

/**
 * @author YFMan
 * @Description 自定义的 Logistic 回归分类器
 * @Date 2023/6/13 11:02
 */
public class myLogistic extends Classifier {
    // 用于存储 线性回归 系数 的数组
    private double[] m_Coefficients;

    // 类别索引
    private int m_ClassIndex;

    // 牛顿法的迭代次数
    private int m_MaxIterations = 1000;

    // 属性数量
    private int m_numAttributes;

    // 系数数量
    private int m_numCoefficients;

    // 梯度下降步长
    private double m_lr = 1e-4;

    // 标准化数据的过滤器
    public static final int FILTER_STANDARDIZE = 1;

    // 用于标准化数据的过滤器
    protected Filter m_StandardizeFilter = null;

    // 用于将 normal 转为 binary 的过滤器
    protected Filter m_NormalToBinaryFilter = null;


    /*
     * @Author YFMan
     * @Description 采用牛顿法来训练 logistic 回归模型
     * @Date 2023/5/9 22:08
     * @Param [data] 训练数据
     * @return void
     **/
    public void buildClassifier(Instances data) throws Exception {
        // 设置类别索引
        m_ClassIndex = data.classIndex();

        // 设置属性数量
        m_numAttributes = data.numAttributes();

        // 系数数量 = 输入属性数量 + 1(截距参数b)
        m_numCoefficients = m_numAttributes;

        // 初始化 系数数组
        m_Coefficients = new double[m_numCoefficients];
        Arrays.fill(m_Coefficients, 0);

        // 将输入数据进行标准化
        m_StandardizeFilter = new Standardize();
        m_StandardizeFilter.setInputFormat(data);
        data = Filter.useFilter(data, m_StandardizeFilter);

        // 将类别属性转为二值属性
        m_NormalToBinaryFilter = new NominalToBinary();
        m_NormalToBinaryFilter.setInputFormat(data);
        data = Filter.useFilter(data, m_NormalToBinaryFilter);

        // 梯度下降法
        for(int curPerformIteration = 0; curPerformIteration < m_MaxIterations;curPerformIteration++){

            double[] deltaM_Coefficients = new double[m_numCoefficients];
            // 计算 l(w) 的一阶导数
            for(int i = 0;i<data.numInstances();i++){

                double yi = data.instance(i).value(m_ClassIndex);
                double wxi = 0;
                int column = 0;
                for(int j=0;j<m_numAttributes;j++){
                    if(j!=m_ClassIndex){
                        wxi += m_Coefficients[column] * data.instance(i).value(j);
                        column++;
                    }
                }
                // 加上截距参数 b
                wxi += m_Coefficients[column];
                double pi1 = Math.exp(wxi) / (1 + Math.exp(wxi));
                for(int k=0;k<m_numCoefficients - 1;k++){
                    deltaM_Coefficients[k] += m_lr * (pi1 - yi) * data.instance(i).value(k);
                }
                // 这里计算 bias b 对应的更新量
                deltaM_Coefficients[m_numCoefficients - 1] += m_lr * (pi1 - yi);
            }

            // 进行参数更新
            for(int k=0;k<m_numCoefficients;k++){
                m_Coefficients[k] -= deltaM_Coefficients[k];
            }

            // 如果参数更新量小于阈值,则停止迭代
            double delta = 0;
            for(int k=0;k<m_numCoefficients;k++){
                delta += deltaM_Coefficients[k] * deltaM_Coefficients[k];
            }
            if(delta < 1e-6){
                break;
            }

        }
    }


    /*
     * @Author YFMan
     * @Description // 分类实例
     * @Date 2023/6/16 11:17
     * @Param [instance]
     * @return double[]
     **/
    public double[] distributionForInstance(Instance instance) throws Exception {

        // 将输入数据进行标准化
        m_StandardizeFilter.input(instance);
        instance = m_StandardizeFilter.output();

        // 将输入属性二值化
        m_NormalToBinaryFilter.input(instance);
        instance = m_NormalToBinaryFilter.output();

        double[] result = new double[2];
        result[0] = 0;
        result[1] = 0;
        int column = 0;
        for(int i=0;i<m_numAttributes;i++){
            if(m_ClassIndex != i){
                result[0] += instance.value(i) * m_Coefficients[column];
                column++;
            }
        }
        result[0] += m_Coefficients[column];
        result[0] = 1 / (1 + Math.exp(result[0]));

        result[1] = 1 - result[0];

        return result;
    }

    /*
     * @Author YFMan
     * @Description 主函数 生成一个线性回归函数预测器
     * @Date 2023/5/9 22:35
     * @Param [argv]
     * @return void
     **/
    public static void main(String[] argv) {
        runClassifier(new myLogistic(), argv);
    }
}

到了这里,关于基于weka手工实现逻辑斯谛回归(Logistic回归)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机器学习11:逻辑回归-Logistic Regression

    目录 1.计算概率 2.损失和正则化 2.1 逻辑回归的损失函数 2.2 逻辑回归中的正则化 3.参考文献

    2024年02月11日
    浏览(59)
  • 基于weka手工实现KNN

    K最近邻(K-Nearest Neighbors,简称KNN)算法是一种常用的基于实例的监督学习算法。它可以用于分类和回归问题,并且是一种非常直观和简单的机器学习算法。 KNN算法的基本思想是:对于一个新的样本数据,在训练数据集中找到与其最接近的K个邻居,然后根据这K个邻居的标签

    2024年02月13日
    浏览(49)
  • 基于weka平台手工实现朴素贝叶斯分类

    B事件发生后,A事件发生的概率可以如下表示: p ( A ∣ B ) = p ( A ∩ B ) P ( B ) (1) p(A|B)=frac{p(Acap B)}{P(B)}tag{1} p ( A ∣ B ) = P ( B ) p ( A ∩ B ) ​ ( 1 ) A事件发生后,B事件发生的概率可以如下表示: p ( B ∣ A ) = p ( A ∩ B ) P ( A ) (2) p(B|A)=frac{p(Acap B)}{P(A)}tag{2} p ( B ∣ A ) = P ( A ) p

    2024年02月13日
    浏览(46)
  • 基于weka手工实现多层感知机(BPNet)

    单层感知机,就是只有一层神经元,它的模型结构如下 1 : 对于权重 w w w 的更新,我们采用如下公式: w i = w i + Δ w i Δ w i = η ( y − y ^ ) x i (1) w_i=w_i+Delta w_i \\\\ Delta w_i=eta(y-hat{y})x_itag{1} w i ​ = w i ​ + Δ w i ​ Δ w i ​ = η ( y − y ^ ​ ) x i ​ ( 1 ) 其中, y y y 为标签, y

    2024年02月17日
    浏览(50)
  • 基于weka手工实现ID3决策树

    相比于logistic回归、BP网络、支持向量机等基于超平面的方法,决策树更像一种算法,里面的数学原理并不是很多,较好理解。 决策树就是一个不断地属性选择、属性划分地过程,直到满足某一情况就停止划分。 当前样本全部属于同一类别了(信息增益为0); 已经是空叶子

    2024年02月14日
    浏览(47)
  • 基于weka手工实现K-means

    K均值聚类(K-means clustering)是一种常见的无监督学习算法,用于将数据集中的样本划分为K个不同的类别或簇。它通过最小化样本点与所属簇中心点之间的距离来确定最佳的簇划分。 K均值聚类的基本思想如下: 随机选择K个初始聚类中心(质心)。 对于每个样本,计算其与各

    2024年02月13日
    浏览(36)
  • 吴恩达老师《机器学习》课后习题2之逻辑回归(logistic_regression)

    用于解决输出标签y为0或1的二元分类问题 判断邮件是否属于垃圾邮件? 银行卡交易是否属于诈骗? 肿瘤是否为良性? 等等。 案例:根据学生的两门学生成绩,建立一个逻辑回归模型,预测该学生是否会被大学录取 数据集:ex2data1.txt python实现逻辑回归, 目标:建立分类器(求

    2024年02月09日
    浏览(46)
  • Logistic回归(逻辑回归)及python代码实现

    在模式识别问题中,所关心的量是分类,比如是否会患有某种疾病,这时就不能用简单的线性回归来完成这个问题了。为了解决次问题,我们引入了非线性激活函数 g : R D → ( 0 , 1 ) g:{mathbb R}^Dto(0,1) g : R D → ( 0 , 1 ) 来预测类别标签的后验概率 p ( y = 1 ∣ x ) p(y=1|bf x) p ( y =

    2024年02月07日
    浏览(40)
  • sklearn实现逻辑回归(Logistic Regression)

    💥 项目专栏:sklearn实现经典机器学习算法(附代码+原理介绍) 🌟 哈喽,亲爱的小伙伴们,你们知道吗?最近我们的粉丝群里有好多小可爱私信问我一些关于决策树、逻辑回归等机器学习的超级有趣的问题呢!🌈 为了让大家更轻松地理解,我决定开一个超可爱的专栏,叫做

    2024年02月21日
    浏览(49)
  • Python实现逻辑回归(Logistic Regression)

    💥 项目专栏:【Python实现经典机器学习算法】附代码+原理介绍 👑 最近粉丝群中很多朋友私信咨询一些决策树、逻辑回归等机器学习相关的编程问题,为了能更清晰的说明,所以建立了本专栏 专门记录基于原生Python实现一些入门必学的机器学习算法 ,帮助广大零基础用户

    2024年02月01日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包