阅读本文需要的背景知识点:拉格朗日乘数法、一丢丢编程知识

一、引言

  前面学习了一种用回归的方式来做分类的算法——对数几率回归算法,下面再来学习另一种分类算法——线性判别分析算法1(Linear Discriminant Analysis Algorithm / LDA),该算法由罗纳德·艾尔默·费希尔在1936年提出,所以也被称为费希尔的线性鉴别方法(Fisher’s linear discriminant)

二、模型介绍

  先来看下图,假设有二分类的数据集,“+”表示正例,“-”表示反例。线性判别分析算法就是要设法找到一条直线,使得同一个类别的点在该直线上的投影尽可能的接近,同时不同分类的点在直线上的投影尽可能的远。该算法的主要思想总结来说就是要“类内小、类间大”,非常类似于在软件设计时说的“低耦合、高内聚”。

来源:《机器学习》-周志华

  当有新的样本点需要分类时,计算该点在直线上的投影,根据投影的位置来判断新样本点的分类。那么如何用数学公式来表示上述说法呢?

三、代价函数

  假设有样本数为 N 的数据集,XiX_iXi​表示第i个样本点的特征向量,yiy_iyi​表示第i个样本点的标签值,www 表示直线的权重系数。

样本点到直线的投影向量

(1)投影向量为样本点乘以与直线夹角的余弦值
(2)带入夹角余弦值的公式
(3)由上图可以看到,我们只需要关系该直线的斜率即可,也就是 www 的方向。不妨令w为单位向量,即∣w∣=1|w| = 1∣w∣=1,带入后整理可得
(4)可以看到(3)式中的第一项即为单位向量,后两项乘积为实数。投影的方向必然与 www 的方向相同,所以不妨将第一项用 www 向量代替
pi=Xicos⁡θ(1)=XiwTXi∣w∣∣Xi∣(2)=Xi∣Xi∣wTXi(3)=wTXiw(4)\begin{aligned} p_i &= X_i \cos \theta & (1)\\ &= X_i \frac{w^TX_i}{\mid w \mid \mid X_i \mid } & (2) \\ &= \frac{X_i}{\mid X_i \mid } w^TX_i & (3) \\ &= w^TX_iw & (4) \\ \end{aligned} pi​​=Xi​cosθ=Xi​∣w∣∣Xi​∣wTXi​​=∣Xi​∣Xi​​wTXi​=wTXi​w​(1)(2)(3)(4)​

均值向量与协方差矩阵

(1)样本为二分类,N1N_1N1​表示第一类样本数量,N2N_2N2​表示第二类样本数量
(2)第一类样本点投影的均值向量
(3)第一类样本点投影的协方差矩阵
(4)第二类样本点投影的均值向量
(5)第二类样本点投影的协方差矩阵
N=N1+N2(1)μp1=1N1∑i=1N1pi(2)σp1=1N1∑i=1N1(pi−μp1)(pi−μp1)T(3)μp2=1N2∑i=1N2pi(4)σp2=1N2∑i=1N2(pi−μp2)(pi−μp2)T(5)\begin{aligned} N &=N_{1}+N_{2} & (1)\\ \mu_{p_{1}} &=\frac{1}{N_{1}} \sum_{i=1}^{N_{1}} p_{i} & (2)\\ \sigma_{p_{1}} &=\frac{1}{N_{1}} \sum_{i=1}^{N_{1}}\left(p_{i}-\mu_{p_{1}}\right)\left(p_{i}-\mu_{p_{1}}\right)^{T} & (3)\\ \mu_{p_{2}} &=\frac{1}{N_{2}} \sum_{i=1}^{N_{2}} p_{i} & (4)\\ \sigma_{p_{2}} &=\frac{1}{N_{2}} \sum_{i=1}^{N_{2}}\left(p_{i}-\mu_{p_{2}}\right)\left(p_{i}-\mu_{p_{2}}\right)^{T} & (5) \end{aligned} Nμp1​​σp1​​μp2​​σp2​​​=N1​+N2​=N1​1​i=1∑N1​​pi​=N1​1​i=1∑N1​​(pi​−μp1​​)(pi​−μp1​​)T=N2​1​i=1∑N2​​pi​=N2​1​i=1∑N2​​(pi​−μp2​​)(pi​−μp2​​)T​(1)(2)(3)(4)(5)​

代价函数

  我们知道样本点的协方差可以用于衡量两个变量的总体误差,那么可以使用协方差的大小来表示类内。而样本点的均值点可以用来表示相对位置,那么可以使用均值点来表示类间。我们的目标是让投影的“类内小、类间大”,那么可以写出对应的代价函数如下:
Cost⁡(w)=(wTμp1−wTμp2)2wTσp1w+wTσp2w\operatorname{Cost}(w)=\frac{\left(w^{T} \mu_{p_{1}}-w^{T} \mu_{p_{2}}\right)^{2}}{w^{T} \sigma_{p_{1}} w+w^{T} \sigma_{p_{2}} w} Cost(w)=wTσp1​​w+wTσp2​​w(wTμp1​​−wTμp2​​)2​

  分子为均值向量大小之差的平方,该值越大代表类间越大。分母为两类样本点的协方差之和,该值越小代表类内越小,我们的目标就是求使得该代价函数最大时的w:
w=argmax⁡w((wTμp1−wTμp2)2wTσp1w+wTσp2w)w=\underset{w}{\operatorname{argmax}}\left(\frac{\left(w^{T} \mu_{p_{1}}-w^{T} \mu_{p_{2}}\right)^{2}}{w^{T} \sigma_{p_{1}} w+w^{T} \sigma_{p_{2}} w}\right) w=wargmax​(wTσp1​​w+wTσp2​​w(wTμp1​​−wTμp2​​)2​)

  我们先来看下代价函数分子的部分:
(1)将投影的均值向量带入分子中
(2)可以将公共的 www 的转置与www 提出来,观察后可以写成两类样本点的均值向量之差
(3)中间两项为实数可以提到前面,www 为单位向量,与自己相乘为1
(4)将平方写成向量乘积的形式
(wTμp1−wTμp2)2=(wT(1N1∑i=1N1wTXiw)−wT(1N2∑i=1N2wTXiw))2(1)=(wT(wT(μ1−μ2)w))2(2)=(wT(μ1−μ2))2(3)=wT(μ1−μ2)(μ1−μ2)Tw(4)\begin{aligned} \left(w^{T} \mu_{p_{1}}-w^{T} \mu_{p_{2}}\right)^{2} &=\left(w^{T}\left(\frac{1}{N_{1}} \sum_{i=1}^{N_{1}} w^{T} X_{i} w\right)-w^{T}\left(\frac{1}{N_{2}} \sum_{i=1}^{N_{2}} w^{T} X_{i} w\right)\right)^{2} & (1)\\ &=\left(w^{T}\left(w^{T}\left(\mu_{1}-\mu_{2}\right) w\right)\right)^{2} & (2) \\ &=\left(w^{T}\left(\mu_{1}-\mu_{2}\right)\right)^{2} & (3) \\ &=w^{T}\left(\mu_{1}-\mu_{2}\right)\left(\mu_{1}-\mu_{2}\right)^{T} w & (4) \end{aligned} (wTμp1​​−wTμp2​​)2​=(wT(N1​1​i=1∑N1​​wTXi​w)−wT(N2​1​i=1∑N2​​wTXi​w))2=(wT(wT(μ1​−μ2​)w))2=(wT(μ1​−μ2​))2=wT(μ1​−μ2​)(μ1​−μ2​)Tw​(1)(2)(3)(4)​

  再来看下其中一类的协方差矩阵的部分:
(1)协方差矩阵的定义
(2)带入投影向量与投影的均值向量
(3)可以将公共的 www 的转置与 www 提出来,中间改写成样本点向量与样本点均值向量之差
(4)展开后一项的转置,将实数部分写到前面
(5)将两个实数相乘写成向量的乘法并将公共的 www 的转置与 www 提出来
(6)观察中括号中的部分,可以写成样本点的协方差矩阵的形式
σp1=1N1∑i=1N1(pi−μp1)(pi−μp1)T(1)=1N1∑i=1N1(wTXiw−1N1∑j=1N1wTXjw)(wTXiw−1N1∑j=1N1wTXjw)T(2)=1N1∑i=1N1(wT(Xi−μ1)w)(wT(Xi−μ1)w)T(3)=1N1∑i=1N1(wT(Xi−μ1))(wT(Xi−μ1))wwT(4)=(wT(1N1∑i=1N1(Xi−μ1)(Xi−μ1)T)w)wwT(5)=wTσ1wwwT(6)\begin{aligned} \sigma_{p_{1}} &=\frac{1}{N_{1}} \sum_{i=1}^{N_{1}}\left(p_{i}-\mu_{p_{1}}\right)\left(p_{i}-\mu_{p_{1}}\right)^{T} & (1)\\ &=\frac{1}{N_{1}} \sum_{i=1}^{N_{1}}\left(w^{T} X_{i} w-\frac{1}{N_{1}} \sum_{j=1}^{N_{1}} w^{T} X_{j} w\right)\left(w^{T} X_{i} w-\frac{1}{N_{1}} \sum_{j=1}^{N_{1}} w^{T} X_{j} w\right)^{T} & (2) \\ &=\frac{1}{N_{1}} \sum_{i=1}^{N_{1}}\left(w^{T}\left(X_{i}-\mu_{1}\right) w\right)\left(w^{T}\left(X_{i}-\mu_{1}\right) w\right)^{T} & (3) \\ &=\frac{1}{N_{1}} \sum_{i=1}^{N_{1}}\left(w^{T}\left(X_{i}-\mu_{1}\right)\right)\left(w^{T}\left(X_{i}-\mu_{1}\right)\right) w w^{T} & (4)\\ &=\left(w^{T}\left(\frac{1}{N_{1}} \sum_{i=1}^{N_{1}}\left(X_{i}-\mu_{1}\right)\left(X_{i}-\mu_{1}\right)^{T}\right) w\right) w w^{T} & (5)\\ &=w^{T} \sigma_{1} w w w^{T} & (6) \end{aligned} σp1​​​=N1​1​i=1∑N1​​(pi​−μp1​​)(pi​−μp1​​)T=N1​1​i=1∑N1​​(wTXi​w−N1​1​j=1∑N1​​wTXj​w)(wTXi​w−N1​1​j=1∑N1​​wTXj​w)T=N1​1​i=1∑N1​​(wT(Xi​−μ1​)w)(wT(Xi​−μ1​)w)T=N1​1​i=1∑N1​​(wT(Xi​−μ1​))(wT(Xi​−μ1​))wwT=(wT(N1​1​i=1∑N1​​(Xi​−μ1​)(Xi​−μ1​)T)w)wwT=wTσ1​wwwT​(1)(2)(3)(4)(5)(6)​

  代价函数的分母部分:
(1)带入上式中协方差矩阵
(2)将实数部分提到前面,后面 www 为单位向量,与自己相乘为 1
(3)化简可得
(4)提出公共部分
wTσp1w+wTσp2w=wT(wTσ1wwwT)w+wT(wTσ2wwwT)w(1)=wTσ1w(wTw)(wTw)+wTσ2w(wTw)(wTw)(2)=wTσ1w+wTσ2w(3)=wT(σ1+σ2)w(4)\begin{aligned} w^{T} \sigma_{p_{1}} w+w^{T} \sigma_{p_{2}} w &=w^{T}\left(w^{T} \sigma_{1} w w w^{T}\right) w+w^{T}\left(w^{T} \sigma_{2} w w w^{T}\right) w & (1)\\ &=w^{T} \sigma_{1} w\left(w^{T} w\right)\left(w^{T} w\right)+w^{T} \sigma_{2} w\left(w^{T} w\right)\left(w^{T} w\right) & (2)\\ &=w^{T} \sigma_{1} w+w^{T} \sigma_{2} w & (3)\\ &=w^{T}\left(\sigma_{1}+\sigma_{2}\right) w & (4) \end{aligned} wTσp1​​w+wTσp2​​w​=wT(wTσ1​wwwT)w+wT(wTσ2​wwwT)w=wTσ1​w(wTw)(wTw)+wTσ2​w(wTw)(wTw)=wTσ1​w+wTσ2​w=wT(σ1​+σ2​)w​(1)(2)(3)(4)​

  代价函数:
(1)代价函数的定义
(2)带入上面推出的分子分母部分
(3)使用 SbS_bSb​、SwS_wSw​ 来代替中间部分,得到新的代价函数
(4)其中 SbS_bSb​ 被称为"类间散度矩阵"(between-class scatter matrix)
(5)其中 SwS_wSw​ 被称为"类内散度矩阵"(within-class scatter matrix)
Cost⁡(w)=(wTμp1−wTμp2)2wTσp1w+wTσp2w(1)=wT(μ1−μ2)(μ1−μ2)TwwT(σ1+σ2)w(2)=wTSbwwTSww(3)Sb=(μ1−μ2)(μ1−μ2)T(4)Sw=σ1+σ2(5)\begin{aligned} \operatorname{Cost}(w) &=\frac{\left(w^{T} \mu_{p_{1}}-w^{T} \mu_{p_{2}}\right)^{2}}{w^{T} \sigma_{p_{1}} w+w^{T} \sigma_{p_{2}} w} & (1)\\ &=\frac{w^{T}\left(\mu_{1}-\mu_{2}\right)\left(\mu_{1}-\mu_{2}\right)^{T} w}{w^{T}\left(\sigma_{1}+\sigma_{2}\right) w} & (2)\\ &=\frac{w^{T} S_{b} w}{w^{T} S_{w} w} & (3) \\ S_{b} &=\left(\mu_{1}-\mu_{2}\right)\left(\mu_{1}-\mu_{2}\right)^{T} & (4)\\ S_{w} &=\sigma_{1}+\sigma_{2} & (5) \end{aligned} Cost(w)Sb​Sw​​=wTσp1​​w+wTσp2​​w(wTμp1​​−wTμp2​​)2​=wT(σ1​+σ2​)wwT(μ1​−μ2​)(μ1​−μ2​)Tw​=wTSw​wwTSb​w​=(μ1​−μ2​)(μ1​−μ2​)T=σ1​+σ2​​(1)(2)(3)(4)(5)​

代价函数最优化

(1)代价函数的新形式,为 SbS_bSb​ 与 SwS_wSw​ 的"广义瑞利商2(generalized Rayleigh quotient)"
(2)可以看到代价函数分子分母都是 www 的二次项,所以代价函数与 www 的长度无关,即缩放 www 不影响代价函数,不妨令分母为 1。可以将问题转化为当分母为 1 时,求分子前面加一个负号的最小值。
(3)可以运用拉格朗日乘数法3,引入一个新的变量 λλλ,可以将(2)式改写成新的形式
(4)对(3)式求偏导并令其等于零向量
(5)观察后发现 SbwS_bwSb​w 的方向恒为两类样本点的均值向量之差的方向,不妨令其为 λλλ 倍的两类样本点的均值向量之差
(6)这样就可以求出了 www 的方向

Cost⁡(w)=wTSbwwTSww(1)⇒min⁡w−wTSbws.t.wTSww=1(2)L(w,λ)=−wTSbw+λ(wTSww−1)(3)∂L(w,λ)∂w=−2Sbw+2λSww=0(4)Sbw=λ(μ1−μ2)(5)w=Sw−1(μ1−μ2)(6)\begin{aligned} \operatorname{Cost}(w) &=\frac{w^{T} S_{b} w}{w^{T} S_{w} w} & (1)\\ \Rightarrow & \begin{aligned} \min _{w} \quad-w^{T} S_{b} w \\ s . t . \quad w^{T} S_{w} w=1 \end{aligned} & (2)\\ L(w, \lambda) &= -w^{T} S_{b} w+\lambda\left(w^{T} S_{w} w-1\right) & (3)\\ \frac{\partial L(w, \lambda)}{\partial w} &= -2 S_{b} w+2 \lambda S_{w} w=0 & (4)\\ S_{b} w &=\lambda\left(\mu_{1}-\mu_{2}\right) & (5)\\ w &=S_{w}^{-1}\left(\mu_{1}-\mu_{2}\right) & (6) \end{aligned} Cost(w)⇒L(w,λ)∂w∂L(w,λ)​Sb​ww​=wTSw​wwTSb​w​wmin​−wTSb​ws.t.wTSw​w=1​=−wTSb​w+λ(wTSw​w−1)=−2Sb​w+2λSw​w=0=λ(μ1​−μ2​)=Sw−1​(μ1​−μ2​)​(1)(2)(3)(4)(5)(6)​

四、算法步骤

  线性判别分析的核心思想在前面也介绍过——“类内小、类间大”,按照最后求得的公式直接计算即可。
(1)分别计算每一类的均值向量
(2)分别计算每一类的协方差矩阵
(3)计算每类协方差矩阵之和的逆矩阵,可以使用 SVD 矩阵分解来简化求逆的复杂度
(4)带入公式求出权重系数 www
  求新样本的分类时,只需判断新样本点离哪一个分类的均值向量更近,则新样本就是哪个分类,如下所示:
k=argmin⁡k∣wTx−wTμk∣k=\underset{k}{\operatorname{argmin}}\left|w^{T} x-w^{T} \mu_{k}\right| k=kargmin​∣∣​wTx−wTμk​∣∣​

五、代码实现

使用 Python 实现线性判别分析(LDA):

def lda(X, y):"""线性判别分析(LDA)args:X - 训练数据集y - 目标标签值return:w - 权重系数"""# 标签值y_classes = np.unique(y)# 第一类c1 = X[y==y_classes[0]][:]# 第二类c2 = X[y==y_classes[1]][:]# 第一类均值向量mu1 = np.mean(c1, axis=0)# 第二类均值向量mu2 = np.mean(c2, axis=0)sigma1 = c1 - mu1# 第一类协方差矩阵sigma1 = sigma1.T.dot(sigma1) / c1.shape[0]sigma2 = c2 - mu2# 第二类协方差矩阵sigma2 = sigma2.T.dot(sigma2) / c2.shape[0]# 求权重系数return np.linalg.pinv(sigma1 + sigma2).dot(mu1 - mu2), mu1, mu2def discriminant(X, w, mu1, mu2):"""判别新样本点args:X - 训练数据集w - 权重系数mu1 - 第一类均值向量mu2 - 第二类均值向量return:分类结果"""a = np.abs(X.dot(w) - mu1.dot(w))b = np.abs(X.dot(w) - mu2.dot(w))return np.argmin(np.array([a, b]), axis=0)

六、第三方库实现

scikit-learn4 实现线性判别分析:

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis# 初始化线性判别分析器
lda = LinearDiscriminantAnalysis()
# 拟合线性模型
lda.fit(X, y)
# 权重系数
w = lda.coef_
# 截距
b = lda.intercept_

  如果你使用 sklearn 提供的线性判别分析的方法,会发现求解出来的结果与上面自己实现的结果不同,这是因为 sklearn 使用的是另一种方法,并有没使用广义瑞利商的形式,而是从概率分布的角度来做分类,后面一节再来介绍该方法。

七、示例演示

  下图展示了存在二种分类时的演示数据,其中红色表示标签值为 0 的样本、蓝色表示标签值为 1 的样本:

  下图为拟合数据的结果,其中浅红色表示拟合后根据权重系数计算出预测值为 0 的部分,浅蓝色表示拟合后根据权重系数计算出预测值为 1 的部分:

八、思维导图

九、参考文献

  1. https://en.wikipedia.org/wiki/Linear_discriminant_analysis
  2. https://en.wikipedia.org/wiki/Rayleigh_quotient
  3. https://en.wikipedia.org/wiki/Lagrange_multiplier
  4. https://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html

完整演示请点击这里

注:本文力求准确并通俗易懂,但由于笔者也是初学者,水平有限,如文中存在错误或遗漏之处,恳请读者通过留言的方式批评指正

本文首发于——AI导图,欢迎关注

机器学习算法系列(十)-线性判别分析算法(一)(Linear Discriminant Analysis Algorithm)相关推荐

  1. 邻域线性判别《Neighborhood linear discriminant analysis》

    模式识别与机器学习老师留了作业说是让找一篇线性判别的论文,所以就记录一下论文(<Neighborhood linear discriminant analysis>)吧,虽然只是一些翻译. ...

  2. 小议费雪线性判别(Fisher Linear Discriminant Analysis)

    fisher 判决方式是监督学习,在新样本加入之前,已经有了原样本. 原样本是训练集,训练的目的是要分类,也就是要找到分类线.一刀砍成两半! 当样本集确定的时候,分类的关键就在于如何砍下这一刀! 若以 ...

  3. ML:基于自定义数据集利用Logistic、梯度下降算法GD、LoR逻辑回归、Perceptron感知器、SVM支持向量机、LDA线性判别分析算法进行二分类预测(决策边界可视化)

    ML:基于自定义数据集利用Logistic.梯度下降算法GD.LoR逻辑回归.Perceptron感知器.支持向量机(SVM_Linear.SVM_Rbf).LDA线性判别分析算法进行二分类预测(决策 ...

  4. R语言分类算法之线性判别分析(Linear Discriminant Analysis)

    1.线性判别原理解析 基本思想是"投影",即高纬度空间的点向低纬度空间投影,从而简化问题的处理.在原坐标系下,空间中的点可能很难被分开,如图8-1,当类别Ⅰ和类别Ⅱ中的样本点都投影 ...

  5. 机器学习中的数学-线性判别分析(LDA), 主成分分析(PCA)

    转:http://www.cnblogs.com/LeftNotEasy/archive/2011/01/08/lda-and-pca-machine-learning.html 版权声明: 本文由L ...

  6. 算法系列(二):贪心算法--Huffman编码

    算法系列(二):贪心算法--Huffman编码 一.分析 问题描述: 哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法.其压缩率通常在20%-90%之间.哈夫曼编码算法使用字符在文件中出现的频率 ...

  7. 机器学习降维算法二:LDA(Linear Discriminant Analysis)

    Linear Discriminant Analysis (也有叫做Fisher Linear Discriminant)是一种有监督的(supervised)线性降维算法.与PCA保持数据信息不同, ...

  8. 西瓜书+实战+吴恩达机器学习(五)监督学习之线性判别分析 Linear Discriminant Analysis

    文章目录 0. 前言 1. 线性判别分析参数求解方法 如果这篇文章对你有一点小小的帮助,请给个关注,点个赞喔,我会非常开心的~ 0. 前言 线性判别分析LDA的思想非常朴素:给定数据集,设法将样例投影 ...

  9. 数据结构与算法:十大排序算法之归并排序

    数据结构与算法:十大排序算法之归并排序 package TopTenSortingAlgorithms;/*** 归并排序:Java** @author skywang* @date 2014/03/ ...

最新文章

  1. 【OpenCV】将单通道的Mat对象转换为三通道的Mat
  2. 配件都包括什么_婚礼婚庆服务都包括什么
  3. 网络编程懒人入门(二):快速理解网络通信协议(下篇)
  4. 闪退没由报错_秉承工匠精神,3步定位飞桨报错原因,你也来试试?
  5. BZOJ 3991: [SDOI2015]寻宝游戏
  6. 【JavaScript】Document对象学习
  7. python爬虫京东中文乱码_python3爬虫中文乱码之请求头‘Accept-Encoding’:br 的问题...
  8. 善用佳软:如何使用Beyond Compare比对class文件
  9. Linux 字体库复制安装
  10. mysql手册06_触发器
  11. MAC(多路访问控制)协议
  12. docker 启动 redis cluster,使用出现CLUSTERDOWN Hash slot not served(redis cluster重新分配slot)
  13. png怎么转ico图标?一招教你如何图片转格式
  14. 计算机感染病毒后 一定不能清除的措施是,货物周转量比上年同期下降最多的是()。...
  15. ppt背景图片怎么设置?6步教你快速搞定!
  16. TCP粘包以及UDP丢包问题
  17. 沈从文写给张兆和的情书
  18. 修改linux系统的root用户密码,linux系统下修改root用户密码
  19. 弯管机编程软件电脑版_奥信编程电脑版
  20. css 文字不规则排版,CSS3文字排版

热门文章

  1. JavaScript资源大全中文版(Awesome最新版)
  2. 干掉微信小程序的繁琐取值和赋值方式,提高开发效率
  3. 如何设计一个速率限制器(令牌桶/漏桶/固定窗口/滑动窗口)
  4. 配送微信商城html模板,微信商城html模板源码
  5. 量化投资从0开始系列 ---- 12. 上期所日统计数据
  6. biee java_转:BIEE11g 集成开源CAS实现SSO
  7. 物联通服务器提示授权文件,管家婆物联通,手机上查看应收应付数据
  8. 论文阅读 Vision GNN: An Image is Worth Graph of Nodes
  9. 高级程序员装逼指南,是高级哦!
  10. 操作系统_05_调度算法(个人总结)