逻辑回归算法实现

news2024/11/17 23:39:22

目录

1.关于逻辑回归的原理解析和准备工作

2.关于激活函数

3.关于数据集

4.编写LogisticsRegression类

5.逻辑回归测试

6.结果


1.关于逻辑回归的原理解析和准备工作

逻辑回归原理相关内容,请参考博主的另一篇文章:机器学习(二)逻辑回归。在本文中的逻辑回归算法实现,不调用sklearn中的相关API,通过纯手写的方式,帮助学习理解逻辑回归的过程。

2.关于激活函数

本文采用Sigmoid函数作为激活函数(也叫逻辑斯谛函数),sigmoid的函数的公式如下:

sigmoid函数可以用于处理二分类问题,其函数图像如下:

import matplotlib.pyplot as plt
import numpy as np


class Sigmoid:
    @staticmethod    
    def sigmoid(matrix):
        return 1 / (1 + np.exp(-matrix))


if __name__ == "__main__":
    x = np.linspace(-10, 10, 100)    
    y = Sigmoid.sigmoid(x)    
    plt.plot(x, y, "b.", label="sigmoid")    
    plt.xlabel("x")    
    plt.ylabel("y")    
    plt.legend()    
    plt.grid()    
    plt.show()

3.关于数据集

本文采用sklearn中自带数据集iris,iris数据集数据分布状态如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

# 载入数据
iris = load_iris()
data = pd.DataFrame(data=iris.data, columns=iris.feature_names)
data["class"] = iris.target_names[iris["target"]]
x_axis = "petal length (cm)"
y_axis = "petal width (cm)"
for iris_type in iris.target_names:
    plt.scatter(data[x_axis][data["class"] == iris_type],           
                data[y_axis][data["class"] == iris_type],                
                label=iris_type)
plt.show()

4.编写LogisticsRegression类

import numpy as np
from scipy.optimize import minimize
from utils.features import pre_for_training
from utils.hypothesis.sigmoid import Sigmoid


class LogisticRegression:
    def __init__(self,
                     data,                 
                     labels,                 
                     polynomial_degree=0,                 
                     sinusoid_degree=0,                 
                     normalize_data=True):
        """               
        对数据预处理,获取所有特征个数,初始化参数矩阵               
        :param data: 训练特征集               
        :param labels: 训练目标值               
        :param polynomial_degree: 特征变换               
        :param sinusoid_degree: 特征变换               
        :param normalize_data: 标准化数据处理               
        """        
        (data_processed, features_mean, features_deviation) = \
            pre_for_training.prepare(data=data, 
                                        polynomial_degree=polynomial_degree, 
                                        sinusoid_degree=sinusoid_degree, 
                                        normalize_data=normalize_data)        
        self.data = data_processed
        self.labels = labels
        self.unique_lables = np.unique(self.labels)        
        self.features_mean = features_mean
        self.features_deviation = features_deviation
        self.polynomial_degree = polynomial_degree
        self.sinusoid_degree = sinusoid_degree
        self.normalize_data = normalize_data

        num_unique_labels = np.unique(self.labels).shape[0]        
        num_features = self.data.shape[1]        
        self.theta = np.zeros((num_unique_labels, num_features)) 
        
        
    def train(self, max_iterations=1000):
        loss_histories = []        
        num_features = self.data.shape[1]        
        for label_index, unique_label in enumerate(self.unique_lables):
            current_init_theta = np.copy(self.theta[label_index].reshape(num_features, 1))            
            current_labels = (self.labels == unique_label).astype(float)            
            (                
            current_theta,                
            loss_history
            ) = LogisticRegression.gradient_descent(data=self.data,                                                    
                                                    labels=current_labels,                     
                                                    current_init_theta=current_init_theta,      
                                                    max_iterations=max_iterations)            
            self.theta[label_index] = current_theta.T
            loss_histories.append(loss_history)        
            return self.theta, loss_histories


    @staticmethod    
    def gradient_descent(data, labels, current_init_theta, max_iterations):
        loss_history = []        
        num_features = data.shape[1]        
        result = minimize(            
        fun=lambda current_theta:
            LogisticRegression.loss_function(data=data,                                             
                                                labels=labels,                                             
                                                theta=current_theta.reshape(num_features, 1)),            
                                                x0=current_init_theta.reshape(num_features, ),            
            method="CG",            
            jac=lambda current_theta:
            LogisticRegression.gradient_step(data=data,                                             
                                                labels=labels,                       
                                                theta=current_theta.reshape(num_features, 1)),            
            callback=lambda current_theta:
            loss_history.append(LogisticRegression.loss_function(data=data,                                                                 
                                                                labels=labels,   
                                                                theta=current_theta.reshape(num_features, 1)),  
            options={"maxiter": max_iterations}        
            )        
            if not result.success:
                raise ArithmeticError(f"[Cannot minimize loss function],msg:{result.message},res:{result.x}") 
            optimized_theta = result.x.reshape(num_features, 1)        
            return optimized_theta, loss_history


    @staticmethod    
    def loss_function(data, labels, theta):
        num_examples = data.shape[0]        
        predictions = LogisticRegression.hypothesis(data, theta)        
        y_is_set_loss = np.dot(labels[labels == 1].T, np.log(predictions[labels == 1]))        
        y_is_not_set_loss = np.dot(1 - labels[labels == 0].T, np.log(1 - predictions[labels == 0]))        
        loss = (-1 / num_examples) * (y_is_set_loss + y_is_not_set_loss)        
        return loss


    @staticmethod    
    def gradient_step(data, labels, theta):
        num_examples = data.shape[0]        
        predictions = LogisticRegression.hypothesis(data, theta)        
        label_diff = predictions - labels
        gradients = (1 / num_examples) * np.dot(data.T, label_diff)        
        return gradients.T.flatten()   
        
        
    @staticmethod    
    def hypothesis(data, theta):
        predictions = Sigmoid.sigmoid(np.dot(data, theta))        
        return predictions


    def predict(self, data):
        num_examples = data.shape[0]        
        (            
        data_processed, 
        features_mean, 
        features_deviation
        ) = pre_for_training.prepare(data=data,                                     
                                        polynomial_degree=self.polynomial_degree,        
                                        sinusoid_degree=self.sinusoid_degree,      
                                        normalize_data=self.normalize_data)      
                                          
        prob = LogisticRegression.hypothesis(data_processed, self.theta.T)        
        max_prb_index = np.argmax(prob, axis=1)        
        class_prediction = np.empty(max_prb_index.shape, dtype=object)        
        for index, label in enumerate(self.unique_lables):
            class_prediction[max_prb_index == index] = label
        return class_prediction.reshape((num_examples, 1))
        

5.逻辑回归测试

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from logistic_regression import logical_regression
from sklearn.datasets import load_iris

# 载入数据
iris = load_iris()
data = pd.DataFrame(data=iris.data, columns=iris.feature_names)
data["class"] = iris.target_names[iris["target"]]
x_axis = "petal length (cm)"
y_axis = "petal width (cm)"
for iris_type in iris.target_names:
    plt.scatter(data[x_axis][data["class"] == iris_type],                
                data[y_axis][data["class"] == iris_type],                
                label=iris_type)
plt.show()


num_examples = data.shape[0]
x_train = data[[x_axis, y_axis]].values.reshape(num_examples, 2)
y_train = data["class"].values.reshape(num_examples, 1)

max_iterations = 1000
polynomial_degree = 0
sinusoid_degree = 0

logi_reg = logical_regression.LogisticRegression(data=x_train, 
                                                    labels=y_train, 
                                                    polynomial_degree=polynomial_degree, 
                                                    sinusoid_degree=sinusoid_degree, 
                                                    normalize_data=False)  # 不标准化
                                                        
thetas, loss_histories = logi_reg.train(max_iterations=max_iterations)
plt.plot(range(len(loss_histories[0])), loss_histories[0], label=logi_reg.unique_lables[0])
plt.plot(range(len(loss_histories[1])), loss_histories[1], label=logi_reg.unique_lables[1])
plt.plot(range(len(loss_histories[2])), loss_histories[2], label=logi_reg.unique_lables[2])
plt.show()
y_train_predictions = logi_reg.predict(x_train)
precision = np.sum((y_train_predictions == y_train) / y_train.shape[0]) * 100
print("precision:", precision)


x_min = np.min(x_train[:, 0])
x_max = np.max(x_train[:, 0])
y_min = np.min(x_train[:, 1])
y_max = np.max(x_train[:, 1])

samples = 150
X = np.linspace(x_min, x_max, samples)
Y = np.linspace(y_min, y_max, samples)

Z_SETOSA = np.zeros((samples, samples))
Z_VERSICOLOR = np.zeros((samples, samples))
Z_VIRGINICA = np.zeros((samples, samples))

predictions = np.zeros((samples, samples))

for x_index, x in enumerate(X):
    for y_index, y in enumerate(Y):
        data = np.array([[x, y]])        
        prediction = logi_reg.predict(data=data)[0][0]        
        if prediction == "setosa":
            Z_SETOSA[x_index][y_index] = 1        
        elif prediction == "versicolor":
            Z_VERSICOLOR[x_index][y_index] = 1        
        elif prediction == "virginica":
            Z_VIRGINICA[x_index][y_index] = 1


for iris_type in ["setosa", "versicolor", "virginica"]:
    plt.scatter( 
                x_train[(y_train == iris_type).flatten(), 0],        
                x_train[(y_train == iris_type).flatten(), 1],        
                label=iris_type
                )

plt.contour(X, Y, Z_SETOSA)
plt.contour(X, Y, Z_VERSICOLOR)
plt.contour(X, Y, Z_VIRGINICA)
plt.show()

6.结果

通过测试,可得到分类的准确率,如下:

预测的损失,如下:

分类的边界线,如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/696009.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

菜鸟重磅推出多款科技新品,“工业大脑”PLC国产化获突破

“决策参谋”供应链计划、“工业大脑”PLC、“智能制造”科技解决方案……6月28日,在2023全球智慧物流峰会上,菜鸟自研的一批新产品、新方案正式曝光。菜鸟物流科技深耕制造业的成绩单也在峰会期间公布,华晨宝马等一批头部汽车企业已与其展开…

六种提高自己工作效率的方法!

为什么同样的时间,同样的都在休息都在玩,而别人工作却在玩的同时已经完成了一大半了。究竟是怎么做到的呢? 不仅仅是因为别人的工作效率高,而是因为他们会巧用工具。 那么你肯定想知道,这款工具是什么样的呢&#xf…

hutool工具类实现excel上传 支持03和07

一直感觉excel表的导入有很多代码,写一次忘一次,类太多,要知道怎么获取Workbook、Sheet、Cell、row等等,这么多类不可能一直记的住,都是写过之后保存,使用的时候拿出来改改,更烦人的是针对offic…

Vue Router replace 编程式导航 缓存路由组件

6.9.路由跳转的 replace 方法 作用&#xff1a;控制路由跳转时操作浏览器历史记录的模式浏览器的历史记录有两种写入方式&#xff1a;push和replace push是追加历史记录replace是替换当前记录&#xff0c;路由跳转时候默认为push方式 开启replace模式 <router-link :replac…

松翰单片机keil环境芯片包

松翰单片机keil环境芯片包&#xff08;SN8F5700系列&#xff09;&#xff1a;安装时与Keil安装位置相同可以直接使用。 安装后依次点击可查看芯片包具体型号&#xff1a; 芯片包下载链接&#xff1a;阿里云盘分享https://www.aliyundrive.com/s/TnHchMhYeh1

Baumer工业相机堡盟工业相机如何通过BGAPISDK进行定序器编程:根据每次触发信号移动感兴趣区域(C++)

Baumer工业相机堡盟工业相机如何通过BGAPISDK进行定序器编程:根据每次触发信号移动感兴趣区域&#xff08;C&#xff09; Baumer工业相机Baumer工业相机BGAPISDK和定序器编程的技术背景Baumer工业相机通过BGAPISDK进行定序器编程功能1.引用合适的类文件2.Baumer工业相机通过BGA…

laravel+vue共用一个域名,使用目录区分接口和项目的nginx配置

1、打包好的项目&#xff1a; 首先将打包好的项目放置public下&#xff0c;如下图 2、nginx配置文件 不带注释的伪静态&#xff08;推荐&#xff09; 备注&#xff1a;若在 location /admin 中的 admin 后面不加 “斜杠/”&#xff0c;则会出现访问 /admin-user 路由&#x…

Oracle Net Services 配置:LISTENER:没有为主机 VM-16-7-centos 返回有效的 IP 地址

问题描述&#xff1a; [rootVM-16-7-centos oracle]# /etc/init.d/oracledb_ORCLCDB-21c configure Configuring Oracle Database ORCLCDB. 准备执行数据库操作 已完成 8% 复制数据库文件 已完成 31% 已完成 100% [FATAL] 正在对命令行参数进行语法分析: 参数"silent&quo…

CLIP论文详细解析

论文链接&#xff1a;Learning Transferable Visual Models From Natural Language Supervision&#xff08;通过自然语言处理的监督信号&#xff0c;学习可迁移的视觉模型&#xff09;. 代码链接&#xff1a;CLIP. CLIP 摘要1.引言2.方法3.实验4.与人对比实验5.数据集去重6.L…

汽车远程启动程序APP的设计与实现(源码+文档+报告+任务书)

以 CAN (Controller Local Network&#xff0c;简称 CAN&#xff09;为基础的车辆遥控起动技术&#xff0c;通过将车辆的 PBD接口与车辆的 CAN总线相连&#xff0c;并与相应的控制系统相连&#xff0c;实现对车辆遥控启动。 此系统主要使用了Java、Android Studio、 MySQL数据…

Visual studio(VS)运行障碍指北

文章目录 VS: ....Microsoft.CppCommon.targets: error MSB6006: “CL.exe”已退出-VS2017许可证过期VS下Visual Assist X番茄插件安装失败子工程引用&#xff08;无法解析的外部符号&#xff09;无法打开.ui文件&#xff08;qt&#xff09;VS中qt子工程无法加载 VS: …Microso…

云原生应用交付平台 Orbit 主要功能与核心能力

GitOps GitOps 于 2017 年首创&#xff0c;是一种管理由 Kubernetes 提供支持的云原生系统的现代方式。它利用策略即代码方法来定义和管理现代应用程序堆栈的每一层——基础设施、网络、应用程序代码和 GitOps 管道本身。Orbit 基于 GitOps 方法理念提供以下能力&#xff1a; …

Revit中用楼板创建散水和批量成板

​一、Revit中用楼板创建散水 在Revit中用楼板来创建散水&#xff0c;散水&#xff1a;散水是指房屋外墙四周的勒脚处(室外地坪上)用片石砌筑或用混凝土浇筑的有一定坡度的散水坡。散水的作用是迅速排走勒脚附近的雨水&#xff0c;避免雨水冲刷或渗透到地基&#xff0c;防止基础…

三、云尚办公-角色管理前端

云尚办公系统&#xff1a;角色管理前端 B站直达【为尚硅谷点赞】: https://www.bilibili.com/video/BV1Ya411S7aT 本博文以课程相关为主发布&#xff0c;并且融入了自己的一些看法以及对学习过程中遇见的问题给出相关的解决方法。一起学习一起进步&#xff01;&#xff01;&am…

2023-06-27-mimics,slicer软件将.nii.gz转为.ply格式

文章目录 一、前言二、步骤2.1.slicer将.nii.gz格式转为.dcm格式2.1.1导入.nii.gz文件2.1.2.可视化渲染2.1.3.新建一个segmentation2.1.4.添加到segmenation2.1.5.导出为.dcm文件 2.2.Mimics将.dicom导为.ply格式2.2.1.加载.dicom文件2.2.2.调thresholding2.2.3.calculate2.2.4…

基于低代码平台搭建工单系统

一、如何搭建一套工单系统&#xff1f; 本人尝试搭建一个内容部门与其他部门需求对接所使用的应用&#xff0c;有点像内容团队的“临时工单”&#xff0c;来解决目前协同办公软件分工颗粒度过大、跨部门临时需求得不到重视、执行者无法了解任务优先级、领导不好把控进度等问题。…

oracle 过滤字段中的中文,不再洋不洋土不土

目录 前言&#xff1a; 一、知己知彼 1.1业务场景 1.2错误案例 二、思路整理 2.1存储长度与字符串长度比较 三、还有没有其他思路 3.1ascii表查找法 3.2正式案例 四、总结 前言&#xff1a; 随着数字化建设的不断深入&#xff0c;企业越来越注重&#xff0c;企业数据治理&am…

滨海高新区管委会副主任崔同湘一行莅临GBASE南大通用调研

GBASE生态发展部总经理武小钢热情引导崔同湘主任一行参观企业展厅&#xff0c;详细介绍了GBASE专注国产数据库领域二十年的发展历程&#xff0c;汇报公司在研发创新、市场应用、生态建设等方面的成果&#xff0c;崔副主任对GBASE近年来在数据库细分行业的发展和取得的重要成果表…

(二十一)数据符号化——矢量数据符号化①

数据符号化——矢量数据符号化 符号化有两个含义:在地图设计工作中&#xff0c;地图数据的符号化是指利用符号将连续的数据进行分类分级、概括化、抽象化的过程。而在数字地图转换为模拟地图过程中&#xff0c;地图数据的符号化指的是将已处理好的矢量地图数据恢复成连续图形&…

数值优化简介

数值优化这个名字来源于一本书&#xff0c;名为《Numerical Optimization》。 Numerical Optimization这两个单词传递了两个知识领域的概念&#xff1a; Optimization指的是数学概念上的优化&#xff0c;即求最优解&#xff0c;也可以理解为求函数的最小值的解&#xff1b; Num…