逻辑斯蒂回归 - 多项式回归_姬小野的博客-程序员秘密

技术标签: 机器学习之路  逻辑斯谛回归  logistic  机器学习  机器学习实战  

一、预期结果

训练一个基于逻辑斯蒂回归的机器学习模型,它能够训练出一条二次曲线,实现二分类问题。他不是线性的,而是多项式的。

二、实验步骤

1)生成数据

首先,我们预期得到的曲线是一个二次曲线,它的方程是这样的:
y = (x - 1)**2 - 1
那么我们根据这个曲线生成一些数据,上下被分为两个类别
得到大概这样一张二分类图
在这里插入图片描述
代码实现:

import numpy as np
import random
import matplotlib.pyplot as plt
plt.style.use("seaborn-whitegrid")

# 数据有三维:(x,y,类别)
def fun(x): # 提前建立的二次曲线
    y = (x - 1)**2 - 1
    return y

def getData():
    data = []
    for i in range(100):
        x = random.uniform(-3, 5)
    #     print(x)
        y = fun(x)
        alpha = random.uniform(-5, 5)
        data.append([x, y + alpha, 0 if alpha < 0 else 1])
    data = np.array(data)
    return data

def draw(xlabel, ylabel, label):
    index0 = np.argwhere(label == 0)  # 获取值为0的数据的索引
    index1 = np.argwhere(label == 1)
    plt.plot(xlabel[index0], ylabel[index0], 'o', color='black')
    plt.plot(xlabel[index1], ylabel[index1], 'x', color='red')
    xs = np.linspace(-4, 6, 1000)
    plt.plot(xs, fun(xs))
    plt.show()

def main():
    data = getData()
    xlabel, ylabel, label = data[:, 0], data[:, 1], data[:, 2]
    draw(xlabel, ylabel, label)

if __name__ == "__main__":
    main()

想到另一种生成数据的方式,给出随机点,然后根据曲线划分类别,而不是在曲线上下生成点。

data = []
for i in range(1000):
    x = random.uniform(-3, 5)
    y = random.uniform(-10, 15)
    data.append([x, y, 0 if fun(x) > y else 1])
data = np.array(data)

这样子的似乎看上去更加自然,不像上一个凑在曲线边上了。
在这里插入图片描述

2)算法实现

下面就开始我们的逻辑斯谛回归算法进行回归拟合。

几个关键词:
1、sigmoid函数
2、梯度上升法

算法步骤:

1、获取规格化数据(系数矩阵、标签)
2、梯度上升法拟合系数
3、画图,看看拟合的准不准

结果

如图所示,蓝色的曲线为我们拟合到的二次曲线,而红色则为我们先前假定的曲线 在数据点不算很多的情况下,曲线也能基本拟合。

得到的方程为:y = 1.001488x^2 - 1.872946x + - 0.295519 和实际的方程y = x^2 - 2x相差不是很多。
在这里插入图片描述

完整代码实现:

import numpy as np
import random
import matplotlib.pyplot as plt
plt.style.use("seaborn-whitegrid")

# 数据有三维:(x,y,类别)
def fun(x): # 提前建立的二次曲线
    y = (x - 1)**2 - 1
    return y

def getData():
    data = []
    for i in range(100):
        x = random.uniform(-3, 5)
        y = random.uniform(-10, 15)
        data.append([x, y, 0 if fun(x) > y else 1])
    data = np.array(data)
    return data

def draw(xlabel, ylabel, label):
    index0 = np.argwhere(label == 0)  # 获取值为0的数据的索引
    index1 = np.argwhere(label == 1)
    plt.plot(xlabel[index0], ylabel[index0], 'o', color='black')
    plt.plot(xlabel[index1], ylabel[index1], 'x', color='red')
    xs = np.linspace(-4, 6, 1000)
    plt.plot(xs, fun(xs))
    plt.show()
    return

def sigmoid(inX):
    return 1.0 / (1 + np.exp(-inX))

def gradAscent(dataMatIn, classLabels):
    dataMatrix = np.mat(dataMatIn).transpose()
    labelMat = np.mat(classLabels).transpose()
    m, n = np.shape(dataMatrix)
    alpha = 0.0001
    maxCycles = 5000
    weights = np.ones((n, 1))
    # print(np.shape(dataMatrix)) # 100, 4
    # print(np.shape(weights)) # 4, 1
    for k in range(maxCycles):
        h = sigmoid(dataMatrix*weights)
        error = (labelMat - h) # 100, 1
        weights = weights + alpha * dataMatrix.transpose() * error
    return weights

def fun_model(weights, x):
    return (-weights[0]*x*x-weights[1]*x) / weights[2]

def drawModel(weight, xlabel, ylabel, label): # 绘制模型训练出来的图
    xs = np.linspace(-4, 6, 1000)
    index0 = np.argwhere(label == 0)  # 获取值为0的数据的索引
    index1 = np.argwhere(label == 1)
    plt.plot(xlabel[index0], ylabel[index0], 'o', color='black')
    plt.plot(xlabel[index1], ylabel[index1], 'x', color='red')
    plt.plot(xs, fun_model(weight, xs), color='blue') # 蓝色为训练出来的曲线
    plt.plot(xs, fun(xs), color='red') # 红色为假定的曲线
    plt.show()
    return

def getEquation(weight): # 根据权重得到方程
    x1 = -weight[0]/weight[2]
    x2 = -weight[1]/weight[2]
    x3 = -weight[3]/weight[2]
    equation = "y = %fx^2 %s %fx + %s %f"%(x1, '+' if x2 >= 0 else '-', abs(x2), '+' if x3 >= 0 else '-', abs(x3))
    return equation

def main():
    data = getData()
    xlabel, ylabel, label = data[:, 0], data[:, 1], data[:, 2]
    # draw(xlabel, ylabel, label) # 绘制图形
    xx = data[:, 0] ** 2
    one = np.ones(len(xx))
    new = np.array([xx, xlabel, ylabel, one])
    weights = gradAscent(new, label)
    weights = np.asarray(weights)  # np.matrix类型真的是有大坑
    # print(weights[0][0][0])
    weight = []
    for each in weights:
        weight.append(each[0])
    drawModel(weight, xlabel, ylabel, label)
    equation = getEquation(weight)
    print(equation)

if __name__ == "__main__":
    main()
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wjh2622075127/article/details/90230990

智能推荐

Erlang语言学习入门_weixin_34184158的博客-程序员秘密

近期研究RabbitMQ,发现它是基于Erlang实现的,于是对Erlang这么语言发生了兴趣,官网地址 http://www.erlang.org/ ,去下载一个最新的版本,我下载的是5.9.1版本,Windows版本R15B01 Windows Binary File (90.7 MB) ,   下载后一路解压安装即可,不用单独做什么设置,Erlang语言就可以使用了,然后就可以开始使用它里面...

Hadoop在yarn上运行mr程序以及历史服务器的配置_hadoop yarn缺少mr配置__东极的博客-程序员秘密

yarn上运行mr程序配置yarn-env.sh配置yarn-site.xml &amp;amp;amp;lt;!-- reducer获取数据的方式 --&amp;amp;amp;gt;&amp;amp;amp;lt;property&amp;amp;amp;gt; &amp;amp;amp;lt;name&amp;amp;amp;gt;yarn.nodemanager.aux-services&amp;amp;amp;lt;/name&amp;amp;amp;gt; &amp;

C语言矩阵运算_c语言matrix.h_可爱的喵大人的博客-程序员秘密

这是一个用C语言编写的矩阵运算头文件,话不多说,上代码matrix.h/** * File name: matrix.h * Author: Tiancai Xu * Version: 1.0 * Data: 2021-10-29 * Copyright: 2021.10, Tiancai Xu * This file defines the matrix and its basic operations * This file is for study or reference o

JS的同步和异步、微任务和宏任务_Yunruohan的博客-程序员秘密

1.为什么JS是单线程的js是运行于浏览器的脚本语言,因其经常涉及操作dom,如果是多线程的,如果一个线程修改dom,另一个线程删除dom,那么浏览器就不知道该先执行哪个操作,所以js执行的时候会按照一个任务一个任务来执行,那么任务是怎么排列的呢2.为什么JS的任务要分类为同步任务和异步任务试想一下,如果js的任务都是同步的,那么遇到定时器、网络请求等这类型需要延时执行回调函数的任务会发生什么?页面会像瘫痪一下暂停下来等待这些需要需要时间的代码执行完毕,基于此,又引入了异步任务,每个异步任务都必

UE4初探——从外部导入图片_ue4 导入图片_一点也不会写代码的博客-程序员秘密

文章目录版本一、UE4处理图片方式二、具体步骤创建C++类的函数库(1).h文件(2).cpp方法实现(3)完整方法代码参考文献版本UE4.26一、UE4处理图片方式在UE4中,引擎本身提供了ImagerWrapper 作为所有图片类型的抽象层来处理图片。导入图片具体步骤为:读取文件压缩后的数据CompressedData.方法为FFileHelper::LoadFileToArray(TArray&lt;uint8&gt; &amp;result, const char* filenam

运筹学与计算机知识,计算机、数学、运筹学等领域的36个重要算法_Linda-Tse的博客-程序员秘密

2.波束搜索波束搜索是一种搜索算法,它是最佳优先搜索的优化。与最佳优先搜索一样,它使用启发式函数来评估它检查的每个节点的承诺。然而,波束搜索仅展开每个深度处的前m个最有希望的节点,其中m是固定数量,即波束宽度。3.二分搜索通过排除每一步中的一半数据来查找线性阵列中特定值的技术。4.分支定界用于寻找各种优化问题的最优解的一般算法方法,尤其是在离散和组合优化中。5.Buchberger算法在计算代数几...

随便推点

[原题复现+审计][BJDCTF2020]Mark loves cat($$导致的变量覆盖问题)_笑花大王的博客-程序员秘密

简介原题复现:https://gitee.com/xiaohua1998/BJDCTF2020_January考察知识点:$$导致的变量覆盖问题线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题$$导致的变量覆盖问题$$导致的变量覆盖问题在CTF代码审计题目中经常在foreach中出现,如...

vue使用element-ui的el-upload上传图片至服务器,服务端使用的是node.js对接受的图片进行处理_el-upload nodejs_初入编域的博客-程序员秘密

使用vue的element-ui中的el-upload上传图片至node服务端,服务端接受图片并返回图片链接至前端。

python读取excel中指定区域的两列数据,每列生成一个数组_又可乐的博客-程序员秘密

你可以使用pandas库来读取Excel文件。首先,你需要安装pandas库,使用以下命令:pipinstall pandas然后,你可以使用以下代码读取Excel文件中的指定区域的两列数据:import pandas as pd# 读取Excel文件df = pd.read_excel('文件名.xlsx', sheet_name='工作表名')# 读取指定区域的两列数据col...

Python实现企业微信发送图片_杨鑫newlfe的博客-程序员秘密

# -*-coding:utf-8 -*-__author__ = 'yangxin_ryan'import requests, jsonimport urllib3urllib3.disable_warnings()"""Python实现企业微信上传临时素材以及发送图片备注:上传时图片的名字最好序列化为数字或英文,中文图片的名字不支持图片上传"""class Wechat...

ListView源码分析_JieQiong1的博客-程序员秘密

1.概述本文是阅读 http://www.cnblogs.com/qiengo/p/3628235.html http://blog.csdn.net/iispring/article/details/50967445 http://blog.csdn.net/guolin_blog/article/details/44996879 http://www.jianshu.com/p/9c6

理解js中的constructor 和prototype_kkhk04的博客-程序员秘密

在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要。我们在定义函数的时候,函数定义的时候函数本身就会默认有一个prototype的属性,而我们如果用new 运算符来生成一个对象的时候就没有prototype属性。我们来看一个例子,来说明这个:function a(c){

推荐文章

热门文章

相关标签