Lesson 4.1-4.2 逻辑回归模型构建与多分类学习方法逻辑回归参数估计
Lesson 4.1 逻辑回归模型构建与多分类学习方法
首先我们来讨论关于逻辑回归的基本原理,当然,在此过程中,我们也将进一步补充机器学习数学理论基础。
逻辑回归的基本原理,从整体上来划分可以分为两个部分,其一是关于模型方程的构建,也就是方程的基本形态,当然也包括模型的基本性质及其结果解读;其二则是模型参数求解,即在构建完模型之后如何利用数学工具求解最佳参数。而这两部分其实都可以从多个角度出发进行理解,基本划分情况如下
- 模型构建部分:可以从广义线性回归(Generalized liner model)+对数几率函数(logit function)角度理解,也可以从随机变量的逻辑斯蒂分布(logistic distribution)角度出发进行理解;
- 参数求解部分:可以借助极大似然估计(Maximum Likelihood Estimate)方法求解,可以借助KL离散度基本理论构建二分类交叉熵损失函数求解。
而无论这些基础理论难易程度如何,其对于此后的机器学习都是至关重要的,因此课上将先从简单角度出发,先构建对逻辑回归基本理论体系的完整认知,然后再补充更加复杂的理论体系,为后续其他算法的学习做铺垫。
本节我们将先讨论关于逻辑回归的模型构建部分,同时也将讨论模型结果解读和模型可解释性的相关内容,下一节我们将具体讨论关于模型参数求解的相关内容。
# 科学计算模块
import numpy as np
import pandas as pd# 绘图模块
import matplotlib as mpl
import matplotlib.pyplot as plt# 自定义模块
from ML_basic_function import *
一、广义线性模型(Generalized liner model)的基本定义
在Lesson3中我们曾谈到关于线性回归的局限性,这种局限性的根本由模型本身的简单线性结构(自变量加权求和预测因变量)导致的。如果说线性回归是在一个相对严格的条件下建立的简单模型,那么在后续实践应用过程中,人们根据实际情况的不同,在线性回归的基础上又衍生出了种类繁多的线性类模型。其中,有一类线性模型,是在线性回归基础上,在等号的左边或右边加上了一个函数,从而能够让模型更好的捕捉一般规律,此时该模型就被称为广义线性模型,该函数就被称为联系函数。
广义线性模型的提出初衷上还是为了解决非线性相关的预测问题,例如,现在有数据分布如下:
# 数据集特征
np.random.seed(24)
x = np.linspace(0, 4, 20).reshape(-1, 1)
x = np.concatenate((x, np.ones_like(x)), axis=1)
x
#array([[0. , 1. ],
# [0.21052632, 1. ],
# [0.42105263, 1. ],
# [0.63157895, 1. ],
# [0.84210526, 1. ],
# [1.05263158, 1. ],
# [1.26315789, 1. ],
# [1.47368421, 1. ],
# [1.68421053, 1. ],
# [1.89473684, 1. ],
# [2.10526316, 1. ],
# [2.31578947, 1. ],
# [2.52631579, 1. ],
# [2.73684211, 1. ],
# [2.94736842, 1. ],
# [3.15789474, 1. ],
# [3.36842105, 1. ],
# [3.57894737, 1. ],
# [3.78947368, 1. ],
# [4. , 1. ]])
# 数据集标签
y = np.exp(x[:, 0] + 1).reshape(-1, 1)
y
#array([[ 2.71828183],
# [ 3.35525011],
# [ 4.1414776 ],
# [ 5.11193983],
# [ 6.30980809],
# [ 7.78836987],
# [ 9.61339939],
# [ 11.86608357],
# [ 14.64663368],
# [ 18.07874325],
# [ 22.31509059],
# [ 27.54413077],
# [ 33.99847904],
# [ 41.96525883],
# [ 51.79887449],
# [ 63.93677707],
# [ 78.91892444],
# [ 97.41180148],
# [120.23806881],
# [148.4131591 ]])
此时x和y的真实关系为y=e(x+1)y=e^{(x+1)}y=e(x+1)但如果以线性方程来进行预测,即:
y=wT⋅x+by= w^T \cdot x + by=wT⋅x+b
当然,我们可以令w^=[w1,w2,...wd,b]T\hat w = [w_1,w_2,...w_d, b]^Tw^=[w1,w2,...wd,b]T,x^=[x1,x2,...xd,1]T\hat x = [x_1,x_2,...x_d, 1]^Tx^=[x1,x2,...xd,1]T,从而将上述方程改写为:
y=w^T⋅x^y= \hat w^T \cdot \hat xy=w^T⋅x^
则模型输出结果为:
np.linalg.lstsq(x, y, rcond=-1)[0]
#array([[ 30.44214742],
# [-22.37576724]])
即y=30.44x−22.38y=30.44x-22.38y=30.44x−22.38
则模型预测结果为:
yhat = x[:, 0] * 30.44 - 22.38
yhat
#array([-22.38 , -15.97157895, -9.56315789, -3.15473684,
# 3.25368421, 9.66210526, 16.07052632, 22.47894737,
# 28.88736842, 35.29578947, 41.70421053, 48.11263158,
# 54.52105263, 60.92947368, 67.33789474, 73.74631579,
# 80.15473684, 86.56315789, 92.97157895, 99.38 ])
# 观察模型预测和真实结果
plt.plot(x[:, 0], y, 'o')
plt.plot(x[:, 0], yhat, 'r-')
能够发现,线性模型预测结果和真实结果差距较大。但此时如果我们在等号右边加上以eee为底的指数运算,也就是将线性方程输出结果进行以eee为底的指数运算转换之后去预测y,即将方程改写为y=e(w^T⋅x^)y=e^{(\hat w^T \cdot \hat x)}y=e(w^T⋅x^)
等价于
lny=w^T⋅x^lny = \hat w^T \cdot \hat xlny=w^T⋅x^
即相当于是线性方程输出结果去预测yyy取以eee为底的对数运算之后的结果。
此时我们可以带入lnylnylny进行建模
np.linalg.lstsq(x, np.log(y), rcond=-1)[0]
#array([[1.],
# [1.]])
可得到方程lny=x+1lny=x+1lny=x+1等价于y=e(x+1)y=e^{(x+1)}y=e(x+1)即解出原方程。
通过上面的过程,我们不难发现,通过在模型左右两端加上某些函数,能够让线性模型也具备捕捉非线性规律的能力。而在上例中,这种捕捉非线性规律的本质,是在方程加入lnlnln对数函数之后,能够使得模型的输入空间(特征所在空间)到输出空间(标签所在空间)进行了非线性的函数映射。而这种连接线性方程左右两端、并且实际上能够拓展模型性能的函数,就被称为联系函数,而加入了联系函数的模型也被称为广义线性模型。广义线性模型的一般形式可表示如下:
g(y)=w^T⋅x^g(y)=\hat w^T \cdot \hat xg(y)=w^T⋅x^
等价于y=g−1(w^T⋅x^)y = g^{-1}(\hat w^T \cdot \hat x)y=g−1(w^T⋅x^)
其中g(⋅)g(·)g(⋅)为联系函数(link function),g−1(⋅)g^{-1}(·)g−1(⋅)为联系函数的反函数(如y=ex与ln(y)=xy=e^x与ln(y)=xy=ex与ln(y)=x)。而如上例中的情况,也就是当联系函数为自然底数的对数函数时,该模型也被称为对数线性模型(logit linear model)。
注:一般来说广义线性模型要求联系函数必须是单调可微函数。
从广义线性模型的角度出发,当联系函数为g(x)=xg(x)=xg(x)=x时,g(y)=y=w^T⋅x^g(y)=y=\hat w^T \cdot \hat xg(y)=y=w^T⋅x^,此时就退化成了线性模型。而能够通过联系函数拓展模型捕捉规律的范围,这也就是广义的由来。
二、对数几率模型与逻辑回归
逻辑回归也被称为对数几率回归。接下来,我们从广义线性模型角度理解逻辑回归。
1.对数几率模型(logit model)
- 几率(odd)与对数几率
几率不是概率,而是一个事件发生与不发生的概率的比值。假设某事件发生的概率为p,则该事件不发生的概率为1-p,该事件的几率为:
odd(p)=p1−podd(p)=\frac{p}{1-p}odd(p)=1−pp
在几率的基础上取(自然底数的)对数,则构成该事件的对数几率(logit):
logit(p)=lnp1−plogit(p) = ln\frac{p}{1-p}logit(p)=ln1−pp
注,logit的是log unit对数单元的简写,和中文中的“逻辑”一词并没有关系。对数几率模型也被称为对数单位模型(log unit model)。
- 对数几率模型
如果我们将对数几率看成是一个函数,并将其作为联系函数,即g(y)=lny1−yg(y)=ln\frac{y}{1-y}g(y)=ln1−yy,则该广义线性模型为:
g(y)=lny1−y=w^T⋅x^g(y)=ln\frac{y}{1-y}=\hat w^T \cdot \hat xg(y)=ln1−yy=w^T⋅x^
此时模型就被称为对数几率回归(logistic regression),也被称为逻辑回归。
国内很多学者认为,logistic regression一词和逻辑的含义相差甚远,将其译为逻辑回归并不妥当。课上不对逻辑回归和对数几率回归进行译名是否妥当的讨论。
数理统计分析方法构建逻辑回归时,基本假设要求变量y必须服从伯努利分布(Bernoulli)。
2.逻辑回归与Sigmoid函数
- 对数几率函数与Sigmoid函数
当然,更进一步的,如果我们希望将上述对数几率函数“反解”出来,也就是改写为y=f(x)y=f(x)y=f(x)形式,则可参照下述形式:
方程左右两端取自然底数:
y1−y=ew^T⋅x^\frac{y}{1-y}=e^{\hat w^T \cdot \hat x}1−yy=ew^T⋅x^
方程左右两端+1可得:
y+(1−y)1−y=11−y=ew^T⋅x^+1\frac{y+(1-y)}{1-y}=\frac{1}{1-y}=e^{\hat w^T \cdot \hat x}+11−yy+(1−y)=1−y1=ew^T⋅x^+1
方程左右两端取倒数可得:
1−y=1ew^T⋅x^+11-y=\frac{1}{e^{\hat w^T \cdot \hat x}+1}1−y=ew^T⋅x^+11
1-方程左右两端可得:
y=1−1ew^T⋅x^+1=ew^T⋅x^ew^T⋅x^+1=11+e−(w^T⋅x^)=g−1(w^T⋅x^)\begin{aligned} y &= 1-\frac{1}{e^{\hat w^T \cdot \hat x}+1}\\ &=\frac{e^{\hat w^T \cdot \hat x}}{e^{\hat w^T \cdot \hat x}+1} \\ &=\frac{1}{1+e^{-(\hat w^T \cdot \hat x)}} = g^{-1}(\hat w^T \cdot \hat x) \end{aligned}y=1−ew^T⋅x^+11=ew^T⋅x^+1ew^T⋅x^=1+e−(w^T⋅x^)1=g−1(w^T⋅x^)
因此,逻辑回归基本模型方程为:
y=11+e−(w^T⋅x^)y = \frac{1}{1+e^{-(\hat w^T \cdot \hat x)}}y=1+e−(w^T⋅x^)1
同时我们也能发现,对对数几率函数的反函数为:
f(x)=11+e−xf(x) = \frac{1}{1+e^{-x}}f(x)=1+e−x1
我们可以简单观察该函数的函数图像:
np.random.seed(24)
x = np.linspace(-10, 10, 100)
y = 1 / (1 + np.exp(-x))plt.plot(x, y)
能够看出该函数的图像近似S形,这种类似S形的函数,也被称为Sigmoid函数。
注:Sigmoid严格定义是指形如S型的函数,并不是特指某个函数,也就是说,从严格意义来讨论,函数f(x)=11+e−xf(x) = \frac{1}{1+e^{-x}}f(x)=1+e−x1只能被称为是Sigmoid函数的一种。但实际上,由于该函数是最著名且通用的Sigmoid函数,因此大多数时候,我们在说Sigmoid函数的时候,其实就是在指f(x)=11+e−xf(x) = \frac{1}{1+e^{-x}}f(x)=1+e−x1函数。后续课上对该概念不做区分,Sigmoid函数即指f(x)=11+e−xf(x) = \frac{1}{1+e^{-x}}f(x)=1+e−x1函数。
3.Sigmoid函数性质
- Sigmoid函数性质与一阶导函数
对于Sigmoid函数来说,函数是单调递增函数,并且自变量在实数域上取值时,因变量取值范围在(0,1)之间。并且当自变量取值小于0时,因变量取值小于0.5,当自变量取值大于0时,因变量取值大于0.5。
并且,我们简单查看Sigmoid导函数性质。
令:
Sigmoid(x)=11+e−xSigmoid(x) = \frac{1}{1+e^{-x}}Sigmoid(x)=1+e−x1
对其求导可得:
Sigmoid′(x)=(11+e−x)′=((1+e−x)−1)′=(−1)(1+e−x)−2⋅(e−x)′=(1+e−x)−2(e−x)=e−x(1+e−x)2=e−x+1−1(1+e−x)2=11+e−x−1(1+e−x)2=11+e−x(1−11+e−x)=Sigmoid(x)(1−Sigmoid(x))\begin{aligned} Sigmoid'(x) &= (\frac{1}{1+e^{-x}})' \\ &=((1+e^{-x})^{-1})' \\ &=(-1)(1+e^{-x})^{-2} \cdot (e^{-x})' \\ &=(1+e^{-x})^{-2}(e^{-x}) \\ &=\frac{e^{-x}}{(1+e^{-x})^{2}} \\ &=\frac{e^{-x}+1-1}{(1+e^{-x})^{2}} \\ &=\frac{1}{1+e^{-x}} - \frac{1}{(1+e^{-x})^2} \\ &=\frac{1}{1+e^{-x}}(1-\frac{1}{1+e^{-x}}) \\ &=Sigmoid(x)(1-Sigmoid(x)) \end{aligned}Sigmoid′(x)=(1+e−x1)′=((1+e−x)−1)′=(−1)(1+e−x)−2⋅(e−x)′=(1+e−x)−2(e−x)=(1+e−x)2e−x=(1+e−x)2e−x+1−1=1+e−x1−(1+e−x)21=1+e−x1(1−1+e−x1)=Sigmoid(x)(1−Sigmoid(x))
我们发现,Sigmoid函数的导函数可以简单的用Sigmoid函数本身来表示。接下来我们验证Sigmoid导函数特性,首先简单定义Sigmoid函数:
def sigmoid(x):return (1 / (1 + np.exp(-x)))
sigmoid(10)
#0.9999546021312976
据此可定义Sigmoid导函数的函数:
def sigmoid_deri(x):return (sigmoid(x)*(1-sigmoid(x)))
sigmoid_deri(10)
#4.5395807735907655e-05
进一步,我们可以绘制Sigmoid导函数图像:
plt.plot(x, sigmoid_deri(x))
我们发现,Sigmoid导函数在实数域上取值大于0,并且函数图像先递增后递减,并在0点取得最大值。据此我们也可以进一步讨论Sigmoid函数性质:
plt.plot(x, sigmoid(x))
由于导函数始终大于0,因此Sigmoid函数始终递增,并且导函数在0点取得最大值,因此Sigmoid在0点变化率最快,而在远离零点的点,Sigmoid导函数取值较小,因此该区间Sigmoid函数变化缓慢。该区间也被称为Sigmoid的饱和区间。
当然,如果从简单探索Sigmoid函数的二阶导函数,其实能够发现,x<0时二阶导函数取值大于0(一阶导函数递增),而x>0时二阶导函数小于0(一阶导函数递减)。因此0点其实也是sigmoid函数的拐点。
函数拐点指的是二阶导函数左右异号的点,从凹凸性来看就是函数凹凸性发生变化的点。
总结sigmoid函数性质如下:
三、逻辑回归模型输出结果与模型可解释性
从整体情况来看,逻辑回归在经过Sigmoid函数处理之后,是将线性方程输出结果压缩在了0-1之间,用该结果再来进行回归类的连续数值预测肯定是不合适的了。在实际模型应用过程中,逻辑回归主要应用于二分类问题的预测。
一般来说,我们会将二分类的类别用一个两个分类水平取值的离散变量来代表,两个分类水平分别为0和1。该离散变量也被称为0-1离散变量。
- 连续型输出结果转化为分类预测结果
对于逻辑回归输出的(0,1)之间的连续型数值,我们只需要确定一个“阈值”,就可以将其转化为二分类的类别判别结果。通常来说,这个阈值是0.5,即以0.5为界,调整模型输出结果:
ycla={0,y<0.51,y≥0.5y_{c l a}=\left\{\begin{array}{l} 0, y<0.5 \\ 1, y \geq 0.5 \end{array}\right. ycla={0,y<0.51,y≥0.5
其中,yclay_{cla}ycla为类别判别结果,而yyy为逻辑回归方程输出结果sigmoid(w^T⋅x^)sigmoid(\hat w^T \cdot \hat x)sigmoid(w^T⋅x^)。例如,有简单数据集如下:
由于只有一个自变量,因此可假设逻辑回归模型如下:
y=11+ex−1y = \frac{1}{1+e^{x-1}} y=1+ex−11
带入数据可进一步计算模型输出结果:
x = np.array([2, 0.5]).reshape(-1, 1)
sigmoid(1-x)
#array([[0.26894142],
# [0.62245933]])
据此,在阈值为0.5的情况下,模型会将第一条判别为0,第二条结果判别为1,上述过程代码实现如下:
yhat = sigmoid(1-x) # 模型预测结果
yhat
#array([[0.26894142],
# [0.62245933]])
ycla = np.zeros_like(yhat)
ycla # 类别判别结果
#array([[0.],
# [0.]])
thr = 0.5 # 设置阈值
yhat >= thr # 数组判别
#array([[False],
# [ True]])
ycla[yhat >= thr] = 1 # 布尔索引
ycla
#array([[0.],
# [1.]])
即:
当然,我们也可以将该过程封装为一个函数:
def logit_cla(yhat, thr=0.5):"""逻辑回归类别输出函数::param yhat: 模型输出结果:param thr:阈值:return ycla:类别判别结果"""ycla = np.zeros_like(yhat)ycla[yhat >= thr] = 1return ycla
测试函数性能:
logit_cla(yhat)
#array([[0.],
# [1.]])
关于阈值的选取与0\1分类的类别标记:阈值为人工设置的参数,在没有特殊其他要求下,一般取值为0.5。而关于类别的数值转化,即将哪一类设置为0哪一类设置为1,也完全可以由人工确定,一般来说,我们会将希望被判别或被识别的类设置为1,例如违约客户、确诊病例等。
- 逻辑回归输出结果(y)是否是概率
决定y是否是概率的核心因素,不是模型本身,而是建模流程。
逻辑斯蒂本身也有对应的概率分布,因此输入的自变量其实是可以视作随机变量的,但前提是需要满足一定的分布要求。如果逻辑回归的建模流程遵照数理统计方法的一般建模流程,即自变量的分布(或者转化之后的分布)满足一定要求(通过检验),则最终模型输出结果就是严格意义上的概率取值。而如果是遵照机器学习建模流程进行建模,在为对自变量进行假设检验下进行模型构建,则由于自变量分布不一定满足条件,因此输出结果不一定为严格意义上的概率。
而课上我们基本都采用机器学习建模流程进行逻辑回归的构建,因此对于模型输出结果y,其实并不一定是严格意义上的概率。不过在目前大多数使用场景中,由于大家希望能够用到模型本身的可解释性,因此还是会将模型结果解读为1发生的概率。尽管这并不是一个严谨的做法,但在机器学习整体的“实证”倾向下,只要业务方接受这种做法、并且能够一定程度指导业务,我们就可以将其解读为概率。 课上我们将逻辑回归输出结果看成近似概率值。
例如在上例中:
我们可以说,第一条样本预测为1的概率为0.27,相比属于类别1,第一条样本更大概率属于类别0;而第二条样本属于类别1的概率高达62%,因此第二条样本我们判别其属于类别1。
并且,根据逻辑回归方程:
y=11+e−(1−x)y = \frac{1}{1+e^{-(1-x)}} y=1+e−(1−x)1
可以进一步推导出:
lny1−y=1−xln\frac{y}{1-y} = 1-xln1−yy=1−x
可解读为x每增加1,样本属于1的概率的对数几率就减少1。(此处应是减少,请注意)
当然,类似的可解释性,也就是自变量变化对因变量变化的贡献程度的解读,对于线性回归同样适用。例如
Lesson 4.1-4.2 逻辑回归模型构建与多分类学习方法逻辑回归参数估计相关推荐
- keras构建前馈神经网络(feedforward neural network)进行回归模型构建和学习
keras构建前馈神经网络(feedforward neural network)进行回归模型构建和学习 我们不必在"回归"一词上费太多脑筋.英国著名统计学家弗朗西斯·高尔顿(Fr ...
- R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型、分类预测器(分类变量)被自动替换为一组虚拟编码变量、summary函数查看检查模型、使用table函数计算混淆矩阵评估分类模型性能
R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型(Logistic regression).分类预测器(分类变量)被自动替换为一组虚拟编码变量.summary函数查看检查模型.使用t ...
- 逻辑回归模型_联邦学习体系下——逻辑回归模型
联邦学习的体系我们在前期介绍过,这里我们简单回顾一下纵向联邦学习的定义:在两个数据集的用户重叠较多而用户特征重叠较少的情况下,将数据集按照纵向 (即特征维度)切分,并取出双方用户相同而用户特征不完全相 ...
- R语言回归模型构建、回归模型基本假设(正态性、线性、独立性、方差齐性)、回归模型诊断、car包诊断回归模型、特殊观察样本分析、数据变换、模型比较、特征筛选、交叉验证、预测变量相对重要度
R语言回归模型构建.回归模型基本假设(正态性.线性.独立性.方差齐性).回归模型诊断.car包诊断回归模型.特殊观察样本分析.数据变换.模型比较.特征筛选.交叉验证.预测变量相对重要度 目录
- R语言rpartb包树回归模型构建:基于前列腺prostate数据集
R语言rpartb包树回归模型构建:基于前列腺prostate数据集 决策树是一种机器学习的方法.决策树的生成算法有ID3, C4.5和C5.0等.决策树是一种树形结构,其中每个内部节点表示一个属性上 ...
- R语言rpartb包树回归模型构建:基于乳腺癌(breast cancer)数据集
R语言rpartb包树回归模型构建:基于乳腺癌(breast cancer)数据集 目录 R语言rpartb包树回归模型构建:基于乳腺癌(breast cancer)数据集
- R语言广义线性模型函数GLM、glm函数构建泊松回归模型(Poisson regression)、泊松回归模型系数解读、查看系数的乘法效应(Interpreting the model para)
R语言广义线性模型函数GLM.glm函数构建泊松回归模型(Poisson regression).泊松回归模型系数解读.查看系数的乘法效应(Interpreting the model paramet ...
- R语言glmnet拟合lasso回归模型实战:lasso回归模型的模型系数及可视化、lasso回归模型分类评估计算(混淆矩阵、accuracy、Deviance)
R语言glmnet拟合lasso回归模型实战:lasso回归模型的模型系数(lasso regression coefficients)及可视化.lasso回归模型分类评估计算(混淆矩阵.accura ...
- 门限回归模型的思想_Stata+R:门槛回归教程
来源 | 数量经济学综合整理 转载请联系 进行回归分析,一般需要研究系数的估计值是否稳定.很多经济变量都存在结构突变问题,使用普通回归的做法就是确定结构突变点,进行分段回归.这就像我们高中学习的分段函 ...
最新文章
- 下一个人才大缺口:量子计算研究人员
- 赤兔四足机器人的作用_腾讯 Robotics X 实验室四足移动机器人Jamoca首亮相,可挑战高难度梅花桩...
- XcodeGhost风波过后,苹果如何防范风险?
- 使用python+ffmpeg批量转换格式
- 声明式事务基于注解@Transactional的理解
- Gym 100090D Insomnia
- 安卓APP_ Fragment(3)—— Fragment的生命周期
- 【CSU - 1980 】不堪重负的树(树上区间dp)
- Notification使用详解之三:通过服务更新进度通知在Activity中监听服务进度
- Java语言所有异常类均继承自_要继承自定义异常类的继承方式必须使用 ( ) 关键字_学小易找答案...
- 常见iPhone设备尺寸及分辨率(持续更新)
- python从外部传入参数_Python学习杂记_8_从程序外部传参的办法sys.argv
- python给一列数据增加前缀_为Datafram的特定列添加前缀
- 基于Springboot实现英语在线学习系统
- word文档中如何将软回车替换为硬回车
- 解决Windows PowerShell 乱码
- Unity_EasyAR_AR大屏幕开发
- 数字温度计设计c语言,数字温度计的设计与制作
- nginx php .htaccess,Linux下nginx支持.htaccess文件实现伪静态的方法
- (自学)sklearn决策树基础知识|解决centos7.8 graphviz报错不能画图的问题
热门文章
- android view强制重绘_android view 相关方法 layout draw 布局 重绘 | 学步园
- tcp连接多久会自动断开_苹果M1 Mac用户报告蓝牙连接问题:外设经常会断开
- ios模拟器装ipa包_在iOS开发的时候如何在模拟器中安装APP
- C语言结构体通过 scanf初始化
- python 在Windows 下切换工作目录
- 149. Leetcode 1005. K 次取反后最大化的数组和 (贪心算法-基础题目)
- MAS 714总复习
- CMA-ES 算法初探
- 【新功能,新插件】-全新来袭,CSDN浏览器助手这一款无广告干净界面插件你值得拥有!
- 机器学习算法源码全解析(一)-带你深入理解随机森林(RandomForest)原理及如何防止 Dropout