【机器学习笔记4】逻辑回归模型

2023-10-27

目录

什么是逻辑回归?

Sigmoid函数

决策边界

逻辑回归的损失函数

为什么平方误差模型不可行?

对数损失函数

单个样例损失:

整体损失函数

梯度下降算法

补充:F1-score评价指标

F1-Score简介

相关概念

F-Score

示例及代码:

问题描述:

数据预处理

特征缩放(Z-score标准化)

实现逻辑回归

sigmoid函数

损失函数

梯度计算函数(求偏导)

梯度迭代函数

训练数据集,绘制拟合决策边界

模型预测和评价

补充:现在将特征集扩大到所有

补充:使用sklearn完成逻辑回归


请确保你已学会了前几个线性回归的内容。之前涉及的相关概念在此文章不会再提及。

什么是逻辑回归?

逻辑回归是一种广义的线性回归模型,主要用于解决二分类问题。所谓二分类问题,就是比如判断一个邮件是否是垃圾邮件、根据某些特征判断肿瘤是否为恶性肿瘤等问题,我们可以将是/否表示为1/0。简单的二分类数据图如下:

(注:左图为只有一个特征的数据模拟图,右图为有两个特征的数据模拟图。)

以仅有一个特征的二分类(左图)为例,如果我们模拟传统线性回归f(x) = \vec w\cdot \vec x+b,并选择0.5作为阈值:当y \geq 0.5时我们认为它是种类1,当y<0.5时,我们认为它是种类0,那么可以得到以下图像:

 但是,当我们再加一些数据,它就会模拟成这样:

很明显能看出,这样的预测并不准确。

所以当对二分类问题进行回归分析时,采用传统的线性回归函数进行拟合并不是一个好的方案。于是我们将使用另一种函数——Sigmoid函数

Sigmoid函数

Sigmoid函数又称为Logistic函数(逻辑函数),Sigmoid函数输出值在(0,1)之间,而且可以解决离群点对拟合线性回归的影响,Sigmoid函数在诸多领域都有涉及,这里不再拓展。

Sigmoid函数表达式:g(z) = \frac{1}{1+e^{-z}}

函数图像:

现在使用sigmoid函数拟合上面的例子,当g(z)\geq 0.5时,我们认为它属于种类1,当g(z)<0.5时,我们认为它属于种类0,于是可以得到下面的图像:

(注:橙色的线为决策边界,后面会详细解释。)

很明显看出该函数拟合的很好。

决策边界

上面提到,我们使用sigmoid函数进行预测时,当g(z) \geq 0.5,我们认为是种类1,当g(z)<0.5时,我们认为是种类0。那么,什么时候g(z)等于0.5呢?观察sigmoid函数的图像,当z等于0时,g(z) = 0.5。所以我们令z = f_{\vec w,b}(\vec x) = \vec w\cdot\vec x+b,决策边界即f_{\vec w,b}(\vec x) = 0

以上述右图为例(即以有两个特征的二分类为例),决策边界最终求出的函数为f(x) = x_0+x_1 -3。当f(x) \geq 0,属于种类1;当f(x)<0.5,属于种类0。决策边界图像为:

可以看到决策边界将两个不同的种类分开了。

又比如,当f_{\vec w,b}(\vec x)为更复杂的多项式时,可以画出以下图像:

逻辑回归的损失函数

为什么平方误差模型不可行?

在之前的线性回归中,我们使用平方误差作为我们的代价函数(损失函数):

J(\vec w,b) = \frac 1 {2m}\sum_{i = 0}^{m-1}(\hat y^{(i)}-y^{(i)})^2 =\frac 1 {2m}\sum_{i = 0}^{m-1}(f_{\vec w,b}(\vec x^{(i)})-y^{(i)})^2

其中,(i)为样例序号。

那时f_{\vec w,b}(\vec x) = \vec w\cdot\vec x+b,平方误差代价函数可以平滑下降直到一个最低点。

下图是一元一次线性回归f(x) = wx+b的代价函数图像:

但是逻辑回归的函数为sigmoid(\vec w\cdot\vec x+b) = \frac{1}{1+e^{-z}},其中,z = \vec w\cdot\vec x+b

如果再使用平方误差作为代价函数,它的图像将会是凹凸不平的:

 这意味着梯度下降算法很可能无法找到最低点,会卡在某个极小值点。

 为了解决这个问题,我们将使用另一种模型作为我们的代价函数:

对数损失函数

为什么使用对数损失函数作为逻辑回归的损失函数而不使用其他函数?

使用对数损失函数作为逻辑回归的损失函数是由极大似然估计推导所得,这里不进行拓展。

单个样例损失:

L(\hat y,y) = \left\{ \begin{aligned} -log(\hat y) if\quad y = 1\\ -log(1-\hat y) if\quad y = 0\\ \end{aligned} \right.

其中,\hat y = g_{\vec w,b}(\vec x) = sigmoid(\vec w\cdot \vec x+b), \hat y \in (0,1)

解释一下含义:

当真实值为1时,图像为:

可以看出,在真实值y为1的情况下:当预测值\hat y接近1时,计算出的损失很小;而当\hat y接近0时,计算出的损失很大很大。换成人话,就是比如说某人真实情况是“很胖”,但是预测出的却是“很廋”,这时预测值和真实值的差距就很大很大。

同理,当真实值为0时,图像为:

 在真实值y为0的情况下:当预测值\hat y接近0时,计算出的损失很小;而当\hat y接近0时,计算出的损失很大很大。

化简L(\hat y,y),可得L(\hat y,y) = -y*log(\hat y)-(1-y)*log(1-\hat y)

整体损失函数

上式求和即可得:

公式:J(\vec w,b) = \frac 1 m \sum_{i=0}^{m-1}L(g_{\vec w,b}(\vec x),y)

让我们用这个新的代价函数模拟一下最开始左图的代价函数模型:

 现在这个图像很适合使用梯度下降算法来找到它的最低点。

梯度下降算法

步骤与线性回归相同,同时进行以下直到收敛:

w_j = w_j - a\frac{\partial J(\vec w,b)}{\partial w_j},\quad j = 0,1,...,n-1

b = b - a\frac{\partial J(\vec w,b)}{\partial b}

其中,

\frac{\partial J(\vec w,b)}{\partial w_j} = \frac{1}{m}\sum_{i=0}^{m-1}(g_{\vec w,b}(\vec x^{(i)})-y^{(i)})x_j^{(i)}

\frac{\partial J(\vec w,b)}{\partial b} = \frac{1}{m}\sum_{i=0}^{m-1}(g_{\vec w,b}(\vec x^{(i)})-y^{(i)})

这两个偏导求出来的公式和线性回归的几乎长得一样,但是并不代表他们一样。

这里g_{\vec w,b}(x) = sigmoid(\vec w\cdot \vec x+b)

求导过程请参考文章:逻辑回归梯度下降法

现在只需要利用该算法求得\vec w,b即可。 

关于多分类问题:

softmax多分类现已更新。


补充:F1-score评价指标

关于

混淆矩阵与F1-score详解现已更新。详细介绍请见文章:

【机器学习笔记15】多分类混淆矩阵、F1-score指标详解与代码实现(含数据)_Twilight Sparkle.的博客-CSDN博客

F1-Score简介

F1分数(F1 Score),是统计学中用来衡量二分类模型精确度的一种指标。它同时兼顾了分类模型的精确率和召回率。F1分数可以看作是模型精确率和召回率的一种加权平均,它的最大值是1,最小值是0。

相关概念

下面先介绍几个概念:

  • TP(rue Positive):正样本被判定为正样本

  • FP(False Positive):负样本被判定为正样本

  • TN(True Negative):负样本被判定为负样本

  • FN(False Negative):正样本被判定为负样本

精确度/查准率:指分类器预测为正例中正样本所占比重:

Precision = \frac {TP} {TP+FP}

召回率/查全率:指预测为正例占总正例比重:

Recall = \frac {TP}{TP+FN}

F-Score算法将同时使用以上两个公式,此外,介绍另一种常用的准确率概念:

准确率,指分类器判断正确的占总样本的比重:

Accuracy = \frac {TP+TN}{TP+TN+FP+FN}

F-Score

具体来源等等就不拓展了,有兴趣可以自查。

F-Score是可以综合考虑精确度(Precision)和召回率(Recall)的调和值,公式如下:

F Score = (1+\beta^2)*\frac{Precision*Recall}{\beta^2Precision+Recall}

\beta=1时,被称为F1-Score或F1-Measure。此时精确度和召回率权重相同。

当我们认为精确度更重要,调整\beta<1

当我们认为召回率更重要,调整\beta>1

示例及代码:

数据来源:Pumpkin Seeds Dataset | Kaggle

问题描述:

现在有两类南瓜种子(CERCEVELIK, URGUP_SIVRISI)以及它们的一些特征:

@ATTRIBUTE Area    INTEGER
@ATTRIBUTE Perimeter    REAL
@ATTRIBUTE Major_Axis_Length    REAL
@ATTRIBUTE Minor_Axis_Length    REAL
@ATTRIBUTE Convex_Area    INTEGER
@ATTRIBUTE Equiv_Diameter    REAL
@ATTRIBUTE Eccentricity    REAL
@ATTRIBUTE Solidity    REAL
@ATTRIBUTE Extent    REAL
@ATTRIBUTE Roundness    REAL
@ATTRIBUTE Aspect_Ration    REAL
@ATTRIBUTE Compactness    REAL

现在请根据已知数据集对这两类南瓜种子进行(逻辑回归)分类并判断准确率。

代码说明:会使用sklearn进行数据分割以及评价模型(F1-score),逻辑回归部分全部自主实现。

 所需要的包

import pandas as pd
import numpy as np
import math,copy
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

数据预处理

为了可视化,这里只选择其中两个特征作为特征集(Major_Axis_Length、Minor_Axis_Length)。

导入和提取数据、拆分训练集和数据集:

    # 导入数据
    data = pd.read_excel(r'.\Pumpkin_Seeds_Dataset\Pumpkin_Seeds_Dataset.xlsx',0)
    df = pd.DataFrame(data)

    # 转换数据
    color = []
    label = []
    for i in df['Class']:
        if i == 'Çerçevelik':
            label.append(0)
        elif i == 'Ürgüp Sivrisi':
            label.append(1)

    # 提取所需数据
    x_1 = np.array(df['Major_Axis_Length']).reshape(-1,1)
    x_2 = np.array(df['Minor_Axis_Length']).reshape(-1, 1)
    X_features = np.c_[x_1,x_2]
    Y_target = np.array(label)

    # 拆分训练集和测试集
    X_train,X_test,y_train,y_test = train_test_split(X_features,Y_target,train_size=0.5,random_state=45)

特征缩放(Z-score标准化)

注意:特征缩放一定要用对地方,应该在拆分完训练集和测试集后,仅对训练集使用,不应该把训练集和测试集放在一起标准化,对测试集的操作应该是在对训练集标准化后,使用通过训练集标准化时计算得到的平均值、方差等进行标准化。

这里使用Z-score标准化进行特征缩放。

# Z-score标准化
def Zscore(X):
    '''x是(m,n)的矩阵,m为样本个数,n为特征数目'''
    # 找每列(特征)均值
    mu = np.mean(X,axis=0)
    # 找每列(特征)标准差
    sigma = np.std(X,axis=0)
    X_norm = (X - mu) / sigma

    return X_norm,mu,sigma
    # 标准化特征集
    X_train,mu,sigma = Zscore(X_train)
    # 绘制训练集
    for i in y_train:
         if i == 1:
             color.append("blue")
         else:
             color.append("orange")
    plt.scatter(X_train[:,0],X_train[:,1],color = color)
    plt.xlabel('Major_Axis_Length')
    plt.ylabel('Minor_Axis_Length')
    plt.show()

 标准化后的训练集:

 注:橘色为Çerçevelik种类,蓝色为Ürgüp Sivrisi种类。

实现逻辑回归

sigmoid函数

公式:g(z) = \frac{1}{1+e^{-z}}

def sigmoid(z):
    '''

    :param z: 标量
    :return: 标量
    '''
    g = 1 / (1 + np.exp(-z))
    return g

损失函数

公式:J(\vec w,b) = \frac 1 m \sum_{i=0}^{m-1}L(g_{\vec w,b}(\vec x),y)

# 逻辑回归损失函数
def compute_cost_logistic(X, y, w, b):
    '''

    :param X: 特征集,矩阵
    :param y: 目标值,列表
    :param w: 向量
    :param b: 标量
    :return: 对数损失值,标量
    '''

    m = X.shape[0]
    cost = 0.0
    for i in range(m):
        z_i = np.dot(X[i],w)+b
        g_wb_i = sigmoid(z_i)
        cost += -y[i]*np.log(g_wb_i) - (1-y[i])*np.log(1-g_wb_i)
    cost = cost/m
    return cost

梯度计算函数(求偏导)

公式:

\frac{\partial J(\vec w,b)}{\partial w_j} = \frac{1}{m}\sum_{i=0}^{m-1}(g_{\vec w,b}(\vec x^{(i)})-y^{(i)})x_j^{(i)}

\frac{\partial J(\vec w,b)}{\partial b} = \frac{1}{m}\sum_{i=0}^{m-1}(g_{\vec w,b}(\vec x^{(i)})-y^{(i)})

其中,g_{\vec w,b}(x) = sigmoid(\vec w\cdot \vec x+b)

def compute_gradient_logistic(X, y, w, b):
    '''

    :param X: 特征集,矩阵
    :param y: 目标值,列表
    :param w: 向量
    :param b: 标量
    :return:
        dj_dw: 对数损失函数对向量w的偏导
        dj_db: 对数损失函数对b的偏导
    '''
    m,n = X.shape
    dj_dw = np.zeros((n,))
    dj_db = 0.0

    for i in range(m):
        g_wb_x = sigmoid(np.dot(X[i],w)+b)
        dj_db = dj_db + g_wb_x - y[i]
        for j in range(n):
            dj_dw[j] = dj_dw[j] + (g_wb_x - y[i])*X[i,j]
    dj_dw = dj_dw/m
    dj_db = dj_db/m

    return dj_dw,dj_db

梯度迭代函数

公式:重复以下直到收敛

w_j = w_j - a\frac{\partial J(\vec w,b)}{\partial w_j},\quad j = 0,1,...,n-1

b = b - a\frac{\partial J(\vec w,b)}{\partial b}

def logistic_regression(X_train,y_train,alpha,num_iters):
    '''

    :param X_train: 特征集,矩阵
    :param y_train: 目标值,列表
    :param alpha: 学习率,标量
    :param num_iters: 训练次数,标量
    :return:
        w: 训练得出的w,向量
        b: 训练得出的b,标量
    '''
    m,n = X_train.shape
    init_w = np.zeros((n,)) # n个特征,所以w有n个
    init_b = 0
    w = copy.deepcopy(init_w)
    b = init_b
    for i in range(num_iters):
        if i%100 == 0:
            print(i)
        dj_dw,dj_db = compute_gradient_logistic(X_train,y_train,w,b)
        w = w - alpha*dj_dw
        b = b - alpha*dj_db

    return w,b

训练数据集,绘制拟合决策边界

    model_w,model_b = logistic_regression(X_train,y_train,alpha=0.4,num_iters=10000)
    x_line = np.c_[np.arange(-4,4,0.1).reshape(-1,1),np.arange(-4,4,0.1).reshape(-1,1)]
    print(model_w)
    y_line = np.dot(x_line,model_w)+model_b

    plt.plot(x_line,y_line,label = 'Predicted Value')
    plt.show()

这是当训练次数为10000时得出的决策边界:

模型预测和评价

算出\vec w,b后,代入sigmoid(\vec w\cdot\vec x+b),阈值为0.5。大于等于0.5为1类,小于0.5为0类。

注意预测之前要先将特征测试集标准化。

这里使用F1-Score(F1分数)进行评价。

# 模型预测
def  model_predict(X,w,b):
    '''

    :param X: 测试集
    :param w: 向量
    :param b: 标量
    :return: 预测值(列表)
    '''
    y = []
    for i in X:
        if sigmoid(np.dot(i,w)+b) >= 0.5:
            y.append(1)
        else:
            y.append(0)
    return y

    # 模型预测
    X_test = (X_test - mu) / sigma
    y_predict = model_predict(X_test,model_w,model_b)
    f1_score = f1_score(y_test,y_predict,average='binary')
    print(f"F1分数为:{round(f1_score,2)}")

 结果:

补充:现在将特征集扩大到所有

直接上结果:

稍微比原来准确了一丢丢。

补充:使用sklearn完成逻辑回归

前面讲了一大堆,实际上sklearn几行代码搞定~

泪目

还是刚才那个数据(扩大到所有特征后的),直接上代码!

import pandas as pd
import numpy as np
import math,copy
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler

data = pd.read_excel(r'.\Pumpkin_Seeds_Dataset\Pumpkin_Seeds_Dataset.xlsx', 0)
df = pd.DataFrame(data)
label = []
for i in df['Class']:
    if i == 'Çerçevelik':
        label.append(0)
    elif i == 'Ürgüp Sivrisi':
        label.append(1)

X_features_bk = np.array(df)
X_features = X_features_bk[:,:-1]
X_features = np.float32(X_features)
Y_target = np.array(label)

# 拆分训练集和测试集
X_train,X_test,y_train,y_test = train_test_split(X_features,Y_target,train_size=0.5,random_state=45)

# 使用sklearn进行Z-score标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)  # 标准化训练集X

# 绘制训练集
color = []
for i in y_train:
    if i == 1:
        color.append("blue")
    else:
        color.append("orange")
plt.scatter(X_train[:, 2], X_train[:, 3], color=color)
plt.xlabel('Major_Axis_Length')
plt.ylabel('Minor_Axis_Length')
plt.show()

# 训练逻辑回归模型
lr_model = LogisticRegression()
lr_model.fit(X_train,y_train)

# 标准化测试集x
# 只有训练集才fit_transform,测试集是transform,原因上面自己写代码的时候说过了
X_test = scaler.transform(X_test)
# 预测
y_pred = lr_model.predict(X_test)
# F1-Score评估
f1_score = f1_score(y_test,y_pred,average='binary')
print(f"F1分数为:{round(f1_score,2)}")

 中间我们拿出之前那两列来画了下图,这个图是同样的随机种子,采用sklearn的Z-score标准化后得出的图像:

对比我们之前自己处理的数据,只能说,完全一致好吧。

然后来看看结果:

甚至比我们自己写的差了这么一丢丢。导致这个的原因是它的学习率和训练次数和我们选的不一样,不过计算速度比我们快很多,我估计它训练次数选的比较少。如果我们调整自己的参数,也可以达到同样的效果!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【机器学习笔记4】逻辑回归模型 的相关文章

随机推荐

  • 如何减少项目在Corona和V-Ray中的3ds Max渲染时间?

    相信在大多 3D 项目里 渲染是最耗费时间的部分 它不仅是建模和纹理化 3D 场景的过程 而是需要利用硬件来完成任务 我们在配备独立GPU和带有2到4个强大内核的CPU的中档计算机上 可以将3ds Max中创建和处理的项目轻松渲染完成 因为
  • kvm故障-虚拟机通过镜像创建虚后无法加载eth0网卡,显示网卡为ens3

    虚拟机通过镜像创建虚后无法加载eth0网卡 显示网卡为ens3 一 首先创建eth0网卡文件配置好 cd etc sysconfig network scripts TYPE Ethernet PROXY METHOD none BROWS
  • [MATLAB]使用for循环来寻求斐波那契(Fibonacci)数列中第一个大于10000的元素

    问题描述 斐波那契数列是这样一个数列 1 1 2 3 5 8 13 21 第n个数是第 n 1 个数和第 n 2 个数的和 f 1 1 for k 1 100 f k 2 f k f k 1 if f k gt 10000 break en
  • 【Boost C++ 库】托管共享内存详解

    文章目录 1 托管共享内存 Managed Shared Memory 1 1 使用托管共享内存 1 2 在托管共享内存中创建数组 1 3 删除共享内存中的对象 1 4 对托管共享内存的原子访问 传送门 gt gt AutoSAR入门和实战
  • (二)Qt下多线程实现多个海康工业相机内触发采集回调取流显示

    系列文章目录 提示 这里是该系列文章的所有文章的目录 第一章 一 Qt下实现多个海康工业相机内触发采集回调取流显示 第二章 二 Qt下多线程实现多个海康工业相机内触发采集回调取流显示 文章目录 系列文章目录 前言 一 创建线程类 二 关联线
  • 【备忘录】英译汉接口

    import requests import random import json from hashlib import md5 Set your own appid appkey appid 2xxx appkey kxxx For l
  • 数字电路-二进制转BCD码

    BCD码实际上就是将原本的十进制数的每一位用一个4位二进制数表示 每一位0 9 二进制4位能够表达的数字范围是0 15 由此可见BCD码的一段与普通四位二进制来表示十进制位有6的进制差 所以这就是二进制转化为BCD码的关键所在 下面来讲讲主
  • TP5 一对多关联查询

    A表 car 购物车 goodid 商品ID sizeid 规格ID B表 commondity 商品表 id 对应goodid 商品名称 title C表 size 规格表 id对应sizeid 规格名称 text 在购物车页面 我们需要
  • CMake 编译时出现错误 coffe转换到 COFF 期间失败: 文件无效或损坏

    转 https blog csdn net feiyang2010jin article details 46576463 C Windows Microsoft NET Framework v4 0 30319 D Program Fil
  • 如何修复d3dcompiler_47.dll缺失?多种解决方法分享

    在使用Windows操作系统的过程中 有时候会遇到d3dcompiler 47 dll缺失的情况 这个问题可能会导致某些应用程序无法正常运行 因此需要及时解决 本文将介绍如何修复d3dcompiler 47 dll缺失的问题 一 什么是d3
  • 服务器怎么用u盘传文件进去_本机向windows服务器传输文件的三种方法

    闲来无事 在腾讯云上申请了一个免费的服务器 想将自己写的网页发布到服务器上 服务器的申请很简单 百度搜索 腾讯云 然后新人第一次注册能申请到免费一个月的云主机 虽然配置不怎么高 但是还是能用的 这是我申请到一个云主机 那么如何将我们本机的文
  • 关于在宸曜科技7160gc上的ubuntu16.04系统下计算资源浪费问题

    1 如果使用核显来显示会占用cpu的资源 即使此时hdmi的线插在显卡上 此时会影响使用cpu来执行程序的效率 最直接体现的是程序的数据发送频率会降低很多 2 如何确定是否是cpu显示还是显卡显示了 需要通过system setting里面
  • 南科大于仕琪团队招聘研究助理教授,博士后

    南方科技大学于仕琪副教授团队招聘研究助理教授 博士后 博士生和硕士生 团队特色 专注步态识别方向十余年 在步态识别方向具有较高的影响力 研究助理教授 研究方向 步态识别 行人视频合成 图像和视频中的人体建模 视频中人的行为分析及相关 要求
  • 分布式系统架构——CAP理论

    1 什么是CAP 在分布式系统中 任何存储系统 有状态服务 都会涉及到CAP定理 Consistency 一致性 简称C 在同一时刻所有节点是具有同样的数据副本 每个节点的数据要保证实时同步 Availability 可用性 简称A 对于一
  • Ubuntu14.04 :By not providing "FindEigen3.cmake" in CMAKE_MODULE_PATH

    Ubuntu14 04 By not providing FindEigen3 cmake in CMAKE MODULE PATH 今天下载了hector slam的源码想要跑一下 结果编译不能通过 并且一直出现如下错误 烦得一逼 研究了
  • 兼容性测试真实案例-餐饮APP

    兼容性测试真实案例 某餐饮APP 项目背景 APP是以电商加直播为载体 供应链为核心 辅以短视频和直播内容分销带货 以及积分商城体系 本项目主要对APP的商品列表及商品采购流程及涉及页面 针对不同品牌 操作系统 分辨率的机型 验证APP是否
  • jenkins和jdk安装教程(安装支持jdk8的最新版本)

    1 安装版本查看 Jenkins稳定版 2 进入清华镜像 下载对应版本的rpm包 清华镜像 3 已rpm安装过Jenkins 现在先卸载 1 卸载 rpm e jenkins 2 检查是否卸载成功 rpm ql jenkins 3 彻底删除
  • (大集合)AI工具和用法汇总—集合的集合

    AI 工具和用法汇总 汇集整理 by Staok 瞰百 源于相关资料在我这慢慢越积累越多 到了不得不梳理的程度 文中有许多内容作者还没有亲自尝试 所以很多内容只是罗列 但信息大源都已给出 授人以渔 欢迎 PR 补充细节内容 比如 好的教程
  • HTML+CSS简单复习

    目录 什么是HTML CSS VSCode编辑器 HTML基本结构和属性 HTML初始代码 HTML注释 标题与段落 文本修饰标签 图片标签 路径的引入 链接标签 锚点 特殊字符 列表标签 表格标签 表单标签 div和span CSS基础语
  • 【机器学习笔记4】逻辑回归模型

    目录 什么是逻辑回归 Sigmoid函数 决策边界 逻辑回归的损失函数 为什么平方误差模型不可行 对数损失函数 单个样例损失 整体损失函数 梯度下降算法 补充 F1 score评价指标 F1 Score简介 相关概念 F Score 示例及