标签:
标签(空格分隔): 监督学习
@author : duanxxnj@163.com
@time : 2016-07-11
所谓分类器,一般是将输入空间
在讲分类器的时候,肯定会遇到判别式函数这个概念。分类器会为每个类别分配一个判别函数,根据判别函数来判断一个新的样本是否是这个类别的。比如,假设有
在一般的分类器中,判别式函数
判别式函数
在判别式函数
以Logistics Regression为例,假设面对的是一个二分类问题,在Logistics Regression中,是定义类别的后验概率为:
这里,使用一个单调的变换函数,logit 函数:
所以Logistics Regression的决策面就是:
凡是分类算法,必定有决策面,而这些分类算法所不同的是:决策面是线性的还是非线性的;以及如果得到这个决策面。
在分类器的理论中,贝叶斯分类器是最优的分类器,而为了得到最优的分类器,我们就需要知道类别的后验概率
这里假设
由于
各种算法的不同,基本上都是来至于对类条件概率密度函数的不同,这一点在研究分类算法的时候,一定要铭记在心。
前面已经说过了LDA假设
这里,特征
在前面提到过,一个线性分类器,在判别式函数
可以看出,其决策面是一个平面。
根据上面的式子,也可以很容易得到LDA的决策函数是:
其中的参数都是从数据中估计出来的:
二次判别函数假设
其对应的判别函数为:
下面这份代码是LDA和QDA的测试代码:
# -*- coding: utf-8 -*-
"""
@author: duanxxnj@163.com
@time: 2015-07-09_16-01
线性判别式分析示例代码
"""
print __doc__
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
##########################################################
# 颜色设置
cmap = colors.LinearSegmentedColormap(
‘red_blue_classes‘,
{
‘red‘: [(0, 1, 1), (1, 0.7, 0.7)],
‘green‘: [(0, 0.7, 0.7), (1, 0.7, 0.7)],
‘blue‘: [(0, 0.7, 0.7), (1, 1, 1)]
}
)
plt.cm.register_cmap(cmap=cmap)
###########################################################
# 生成数据
def dataset_fixed_cov():
‘‘‘产生两个拥有相同方差的高斯样本集合‘‘‘
n, dim = 300, 2 # 样本数目为300,特征维度为2
np.random.seed(0)
c = np.array([[0, -0.23], [0.83, 0.23]]) #高斯分布的方差
X = np.r_[np.dot(np.random.randn(n, dim), c),
np.dot(np.random.randn(n, dim), c) + np.array([1, 1])]
y = np.hstack((np.zeros(n), np.ones(n)))
return X, y
def dataset_cov():
‘‘‘产生两个拥有不同的方差的高斯样本集合‘‘‘
n, dim = 300, 2
np.random.seed(0)
c = np.array([[0.1, -1.0], [2.5, 0.7]]) * 2.0
X = np.r_[np.dot(np.random.randn(n, dim), c),
np.dot(np.random.randn(n, dim), c.T) + np.array([1, 4])]
y = np.hstack((np.zeros(n), np.ones(n)))
return X, y
#########################################################################
# 绘图函数
def plot_data(lda, X, y, y_pred, fig_index):
splot = plt.subplot(2, 2, fig_index)
if fig_index == 1:
plt.title(‘Linear Discriminant Analysis‘)
plt.ylabel(‘Data with fixed covariance‘)
elif fig_index == 2:
plt.title(‘Quadratic Discriminant Analysis‘)
elif fig_index == 3:
plt.ylabel(‘Data with varying covariances‘)
tp = (y == y_pred) #正样本中,分类正确的数目
tp0, tp1 = tp[y == 0], tp[y == 1]
X0 , X1 = X[y == 0], X[y == 1]
X0_tp, X0_fp = X0[tp0], X0[~tp0]
X1_tp, X1_fp = X1[tp1], X1[~tp1]
# 类别0分类正确的点和分类错误的点
plt.plot(X0_tp[:, 0], X0_tp[:, 1], ‘o‘, color=‘red‘)
plt.plot(X0_fp[:, 0], X0_fp[:, 1], ‘.‘, color=‘#990000‘)
# 类别1分类正确的点和分类错误的点
plt.plot(X1_tp[:, 0], X1_tp[:, 1], ‘o‘, color=‘blue‘)
plt.plot(X1_fp[:, 0], X1_fp[:, 1], ‘.‘, color=‘#000099‘)
# 类别0和类别1的区域
nx, ny = 200, 100
x_min, x_max = plt.xlim()
y_min, y_max = plt.ylim()
xx, yy = np.meshgrid(np.linspace(x_min, x_max, nx),
np.linspace(y_min, y_max, ny))
# 求出LDA的概率分布
z = lda.predict_proba(np.c_[xx.ravel(), yy.ravel()])
z = z[:, 1].reshape(xx.shape)
plt.pcolormesh(xx, yy, z,
cmap=‘red_blue_classes‘,
norm=colors.Normalize(0., 1.))
# 这里的等高线,就是对应的决策面
# LDA的决策面是直线,而QDA的决策面是二次曲线
# 注意图中右下角那张图,途中的决策面是双曲线
# 为了更清楚的看出其为双曲线,可以去掉后面两行代码的注释
plt.contour(xx, yy, z, [0.5], linewidths=2., colors=‘k‘)
#plt.contour(xx, yy, z, [0.4, 0.6], linewidths=2., colors=‘g‘)
#plt.contour(xx, yy, z, [0.3, 0.7], linewidths=2., colors=‘b‘)
# 类别0和类别1的中心点
plt.plot(lda.means_[0][0], lda.means_[0][1],
‘o‘, color=‘k‘, markersize=10)
plt.plot(lda.means_[1][0], lda.means_[1][2],
‘o‘, color=‘k‘, markersize=10)
for i, (X, y) in enumerate([dataset_fixed_cov(), dataset_cov()]):
print i
# 线性判别式分析
lda = LinearDiscriminantAnalysis(solver=‘svd‘, store_covariance=True)
y_pred = lda.fit(X, y).predict(X)
splot = plot_data(lda, X, y, y_pred, fig_index=2 * i + 1)
plt.axis(‘tight‘)
# 二次判别分析
qda = QuadraticDiscriminantAnalysis(store_covariances=True)
y_pred = qda.fit(X, y).predict(X)
splot = plot_data(qda, X, y, y_pred, fig_index= 2 * i + 2)
plt.axis(‘tight‘)
plt.show()
上面两幅图的数据是均值不同,方差相同的数据分布,LDA和QDA都得到一个线性的决策面。下面两幅图是均值和方差都不一样的数据分布,LDA得到一个线性决策面,但是QDA得到的决策面试一个双曲面,注意这里是一个双曲面,并不是两条直线。为了更好的看出其为双曲面,可以将代码中有两行等高线的代码注释去掉,就可以清晰的看出其决策面是双曲线了。
上面从贝叶斯公式出发,得到了线性判别分析的公式,这里从另外一个角度来看线性判别分析,也就是常说的Fisher判别式。其实Fisher判别式就是线性判别分析(LDA),只是在讨论Fisher判别式的时候,更侧重于LDA的数据降维的能力。
在应用统计学方法解决模式识别、机器学习中的问题的时候,有一个问题总是会出现:维数问题。很多在低维空间里可以解析或者计算的算法,在高维空间里面往往行不通,因此,数据降维就成了处理实际问题中的关键。
单纯的从数学角度考虑,将
线性判别分析的基本思想,是将高维的模式样本投影到最佳鉴别矢量空间,以达到抽取分类信息和压缩特征空间维数的效果,投影后保证模式样本在新的子空间有最大的类间距离和最小的类内距离,即模式在该空间中有最佳的可分离性,因此,它是一种有效的特征抽取方法。
在上面关于线性判别分析的说明中提到,投影后的样本在新的空间需要有最大的类间距离和最小的类内距离。那么,什么是类间距离?什么又是类内距离?线性判别分析又是如何在最大化类间距离的同时最小化类内距离?回答完了这三个问题,就基本上能对线性判别分析有一个基本的了解了。
对于线性分类器,有一种观点就是将线性分类器看成是一个降维的操作。这里首先考虑二分类的问题,假设输入向量
此时在
毫无疑问,上面的这种投影操作,会损失大量的样本信息,同时在投影的直线上,可能会使得各个类别的数据相互重叠,无法分别开来。但无论怎样,通过调整
每一类的数据都像是一个云团,存在各自的分布,那么如何定义两个类之间的距离呢?这里可以先考虑两个类
用两个均值
当两个类分别通过
这里
对上面的式子,使用拉格朗日乘子法:
对
这个结果也是显然的,使用类的均值作为类间距离,要在投影的时候最大化类间距离,自然要让投影线和
但是,单纯最大化类间距离真的就可以让投影后类之间的重叠最少吗?看下面这幅图。这幅图是从PRML上截取下来的,这幅图左边就是单纯的最大化类间距离,所以左图中
很显然相对于右图而言,单纯的最大化类间距离无法让投影后类的重叠最小,那么Fisher线性判别式到底又做了什么才能到到这个效果呢?这就是下面要讲的:最小化类内距离。
对于一个存在一定的分布的类而言,我们用来定义这个类的类内距离,最常用的,就是方差(variance),方差所表示的,就是数据的离散程度。一个类
这里
在很多网上的博客以及中文的教材中,讨论到类内距离的时候,都是说这个是类的散度矩阵,其实这个就是数据的方差,用散度矩阵这个名字,只是为了让这个理论显得特别的高深的感觉,千万不用被忽悠了。
我们可以定义,投影后,总的类内方差为:投影后,各自类内方差的总和:
上面已经介绍了类间距离,也就是类的均值的差;类内距离,也就是类内的方差。Fisher线性判别式的基本思想就是要最大化类间距离,同时最小化类内距离。这里就定义一个比值:
将这个比值最大化,就可以达到最大化类间距离的同时,最小化类内距离了。
对于原始的数据而言,其类内方差可以写为:
投影后的类内方差为:
这里定义原始数据的类内总方差为:
那么投影后的类内总方差为:
投影后,类间距离也可以写成相似的形式:
这里定义:
那么,投影后的类间距离可以写成为:
这样,就是可以把Fisher判别式的判别准则重写为下面这个形式:
其中:
上面这个式子对
这样,我们就可以得到将投影后的类间距离最大化,同时投影后的类内距离最小化的之间
当然,这个问题是一个多对一的问题,从理论上讲,在很多训练样本的情况下,这个方法不仅不能让最小误差率降低,甚至会在一定程度上提高误差率。然而,我们总还是愿意为了得到在一维中操作的方便性,而想要的牺牲一些理论上的分类效果。
此时,最后剩下的问题就是如何在投影后,求解阈值,来进行分类了。阈值点,就是在一维空间中,可以将两类分开的那个点的位置,这个问题相对来说非常的简单,这里不予讨论。
这里有一种特殊情况,就是当数据的条件概率分布函数
其中:
计算Fisher判别准则下最佳的
w 的计算复杂度主要是计算Sw ,和它的逆,所带来的,所以其复杂度为O(D2n)
从上面的推导可以看出,Fisher判别式就是线性判别分析(LDA),只是在讨论Fisher判别式的时候,更侧重于LDA的数据降维的能力。
# -*- coding: utf-8 -*-
"""
@author: duanxxnj@163.com
@time: 2015-07-11_16-17
线性判别式分析数据降维示例
"""
print __doc__
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
# 读取iris数据,
# 这个数据的特征维度为4维
# 样本的类别有三中
iris = datasets.load_iris()
X = iris.data
y = iris.target
target_names = iris.target_names
# 将数据的特征维度降为一维
# 当然这里可以将n_components设置为任何小于原始特征维度的数目
lda = LinearDiscriminantAnalysis(n_components=1)
X_r2 = lda.fit(X, y).transform(X)
X_Zreo = np.zeros(X_r2.shape)
for c ,i , target_names in zip(‘ryb‘, [0, 1, 2], target_names):
plt.scatter(X_r2[y == i], X_Zreo[y == i], c=c, label=target_names)
plt.grid()
plt.legend()
plt.show()
这里是将iris数据集的4维特征,转换成了一维的特征,可以看出,转换之后的特征任然有很强的分类能力,这就是LDA的数据降维能力。
线性判别分析(Linear Discriminant Analysis)
标签:
原文地址:http://blog.csdn.net/daunxx/article/details/51881956