作者:桂。

时间:2017-05-23  06:37:31

链接:http://www.cnblogs.com/xingshansi/p/6892317.html


前言

仍然是python库函数scikit-learn的学习笔记,内容Regression-1.2Linear and Quadratic Discriminant Analysis部分,主要包括:

   1)线性分类判别(Linear discriminant analysis, LDA)

  2)二次分类判别(Quadratic discriminant analysis, QDA)

  3)Fisher判据

 一、线性分类判别

对于二分类问题,LDA针对的是:数据服从高斯分布,且均值不同,方差相同

概率密度:

p是数据的维度。

分类判别函数:

可以看出结果是关于x的一次函数:wx+w0,线性分类判别的说法由此得来。

参数计算:

二、二次分类判别

对于二分类问题,QDA针对的是:数据服从高斯分布,且均值不同,方差不同

数据方差相同的时候,一次判别就可以,如左图所示;但如果方差差别较大,就是一个二次问题了,像右图那样。

从sklearn给的例子中,也容易观察到:

QDA对数据有更好的适用性,QDA判别公式:

三、Fisher判据

  A-Fisher理论推导

Fisher一个总原则是:投影之后的数据,最小化类内误差,同时最大化类间误差

其中,分别对应投影后的类均值。对应投影后的类内方差。

重写类内总方差、类间距离:

准则函数重写:

这就是泛化瑞利熵的形式了,容易求解:

其中常借助SVD求解:Sw = U∑VT,Sw-1 = U∑-1VT,借助特征值分解也是可以的。

   B-LDA与Fisher

这里的LDA指代上面提到的利用概率求解的贝叶斯最优估计器。可以证明:

二分类任务中两类数据满足高斯分布且方差相同时,线性判别分析(指Fisher方法)产生贝叶斯最优分类器(指本文的LDA)。

对于Fisher,求J的最大值:

贝叶斯最优,即距离分类中心距离除以两个类中心距离的比值最小:

二者倒数关系,一个最大化,一个最小化,所以是等价的。

补充一句:误差为高斯分布,与最小二乘也是等价的

这样一来,求解就有了三个思路:奇异值分解SVD,最小二乘Lsqr,特征值分解eigen,这也是Sklearn的思路:

  C-多分类LDA

定义类内散度矩阵:

定义类间散度矩阵:

定义总散度矩阵:

可见ST 、SB、 SW三者任意取两个即可。

准则函数:

其中

最优化求解:

看作投影矩阵,其闭式解是的d'个最大非零广义特征值对应的特征向量组成的矩阵。d'通常远小于原数据属性数d,这就实现了监督的降维。

参数求解利用train data:

四、Sk-learn基本用法

  LDA:

  1. lda = LinearDiscriminantAnalysis(solver="svd", store_covariance=True)
  2. y_pred = lda.fit(X, y).predict(X)

  QDA:

  1. qda = QuadraticDiscriminantAnalysis(store_covariances=True)
  2. y_pred = qda.fit(X, y).predict(X)

  LDA与QDA应用实例:

  1. """
  2. ====================================================================
  3. Linear and Quadratic Discriminant Analysis with confidence ellipsoid
  4. ====================================================================
  5.  
  6. Plot the confidence ellipsoids of each class and decision boundary
  7. """
  8. print(__doc__)
  9.  
  10. from scipy import linalg
  11. import numpy as np
  12. import matplotlib.pyplot as plt
  13. import matplotlib as mpl
  14. from matplotlib import colors
  15.  
  16. from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
  17. from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
  18.  
  19. ###############################################################################
  20. # colormap
  21. cmap = colors.LinearSegmentedColormap(
  22. 'red_blue_classes',
  23. {'red': [(0, 1, 1), (1, 0.7, 0.7)],
  24. 'green': [(0, 0.7, 0.7), (1, 0.7, 0.7)],
  25. 'blue': [(0, 0.7, 0.7), (1, 1, 1)]})
  26. plt.cm.register_cmap(cmap=cmap)
  27.  
  28. ###############################################################################
  29. # generate datasets
  30. def dataset_fixed_cov():
  31. '''Generate 2 Gaussians samples with the same covariance matrix'''
  32. n, dim = 300, 2
  33. np.random.seed(0)
  34. C = np.array([[0., -0.23], [0.83, .23]])
  35. X = np.r_[np.dot(np.random.randn(n, dim), C),
  36. np.dot(np.random.randn(n, dim), C) + np.array([1, 1])]
  37. y = np.hstack((np.zeros(n), np.ones(n)))
  38. return X, y
  39.  
  40. def dataset_cov():
  41. '''Generate 2 Gaussians samples with different covariance matrices'''
  42. n, dim = 300, 2
  43. np.random.seed(0)
  44. C = np.array([[0., -1.], [2.5, .7]]) * 2.
  45. X = np.r_[np.dot(np.random.randn(n, dim), C),
  46. np.dot(np.random.randn(n, dim), C.T) + np.array([1, 4])]
  47. y = np.hstack((np.zeros(n), np.ones(n)))
  48. return X, y
  49.  
  50. ###############################################################################
  51. # plot functions
  52. def plot_data(lda, X, y, y_pred, fig_index):
  53. splot = plt.subplot(2, 2, fig_index)
  54. if fig_index == 1:
  55. plt.title('Linear Discriminant Analysis')
  56. plt.ylabel('Data with fixed covariance')
  57. elif fig_index == 2:
  58. plt.title('Quadratic Discriminant Analysis')
  59. elif fig_index == 3:
  60. plt.ylabel('Data with varying covariances')
  61.  
  62. tp = (y == y_pred) # True Positive
  63. tp0, tp1 = tp[y == 0], tp[y == 1]
  64. X0, X1 = X[y == 0], X[y == 1]
  65. X0_tp, X0_fp = X0[tp0], X0[~tp0]
  66. X1_tp, X1_fp = X1[tp1], X1[~tp1]
  67.  
  68. alpha = 0.5
  69.  
  70. # class 0: dots
  71. plt.plot(X0_tp[:, 0], X0_tp[:, 1], 'o', alpha=alpha,
  72. color='red')
  73. plt.plot(X0_fp[:, 0], X0_fp[:, 1], '*', alpha=alpha,
  74. color='#990000') # dark red
  75.  
  76. # class 1: dots
  77. plt.plot(X1_tp[:, 0], X1_tp[:, 1], 'o', alpha=alpha,
  78. color='blue')
  79. plt.plot(X1_fp[:, 0], X1_fp[:, 1], '*', alpha=alpha,
  80. color='#000099') # dark blue
  81.  
  82. # class 0 and 1 : areas
  83. nx, ny = 200, 100
  84. x_min, x_max = plt.xlim()
  85. y_min, y_max = plt.ylim()
  86. xx, yy = np.meshgrid(np.linspace(x_min, x_max, nx),
  87. np.linspace(y_min, y_max, ny))
  88. Z = lda.predict_proba(np.c_[xx.ravel(), yy.ravel()])
  89. Z = Z[:, 1].reshape(xx.shape)
  90. plt.pcolormesh(xx, yy, Z, cmap='red_blue_classes',
  91. norm=colors.Normalize(0., 1.))
  92. plt.contour(xx, yy, Z, [0.5], linewidths=2., colors='k')
  93.  
  94. # means
  95. plt.plot(lda.means_[0][0], lda.means_[0][1],
  96. 'o', color='black', markersize=10)
  97. plt.plot(lda.means_[1][0], lda.means_[1][1],
  98. 'o', color='black', markersize=10)
  99.  
  100. return splot
  101.  
  102. def plot_ellipse(splot, mean, cov, color):
  103. v, w = linalg.eigh(cov)
  104. u = w[0] / linalg.norm(w[0])
  105. angle = np.arctan(u[1] / u[0])
  106. angle = 180 * angle / np.pi # convert to degrees
  107. # filled Gaussian at 2 standard deviation
  108. ell = mpl.patches.Ellipse(mean, 2 * v[0] ** 0.5, 2 * v[1] ** 0.5,
  109. 180 + angle, facecolor=color, edgecolor='yellow',
  110. linewidth=2, zorder=2)
  111. ell.set_clip_box(splot.bbox)
  112. ell.set_alpha(0.5)
  113. splot.add_artist(ell)
  114. splot.set_xticks(())
  115. splot.set_yticks(())
  116.  
  117. def plot_lda_cov(lda, splot):
  118. plot_ellipse(splot, lda.means_[0], lda.covariance_, 'red')
  119. plot_ellipse(splot, lda.means_[1], lda.covariance_, 'blue')
  120.  
  121. def plot_qda_cov(qda, splot):
  122. plot_ellipse(splot, qda.means_[0], qda.covariances_[0], 'red')
  123. plot_ellipse(splot, qda.means_[1], qda.covariances_[1], 'blue')
  124.  
  125. ###############################################################################
  126. for i, (X, y) in enumerate([dataset_fixed_cov(), dataset_cov()]):
  127. # Linear Discriminant Analysis
  128. lda = LinearDiscriminantAnalysis(solver="svd", store_covariance=True)
  129. y_pred = lda.fit(X, y).predict(X)
  130. splot = plot_data(lda, X, y, y_pred, fig_index=2 * i + 1)
  131. plot_lda_cov(lda, splot)
  132. plt.axis('tight')
  133.  
  134. # Quadratic Discriminant Analysis
  135. qda = QuadraticDiscriminantAnalysis(store_covariances=True)
  136. y_pred = qda.fit(X, y).predict(X)
  137. splot = plot_data(qda, X, y, y_pred, fig_index=2 * i + 2)
  138. plot_qda_cov(qda, splot)
  139. plt.axis('tight')
  140. plt.suptitle('Linear Discriminant Analysis vs Quadratic Discriminant Analysis')
  141. plt.show()

LDA与PCA,LDA与PCA都可以借助SVD求解,但本质是不同的:

顺便提一句之前梳理的独立成分分析(ICA)与PCA的差别,PCA立足点是相关性,是基于协方差矩阵(二阶统计量);而ICA立足点是独立性,利用概率分布(也就是高阶统计量),当然如果是正态分布,二者就等价了。

关于LDA、PCA降维的对比,Sklearn给出了IRIS数据的示例:

The Iris dataset represents 3 kind of Iris flowers (Setosa, Versicolour and Virginica) with 4 attributes: sepal length, sepal width, petal length and petal width.即数据类别数是3,每一个样本对应的特征维度是4,现在分别用LDA、PCA降至2维。

code:

  1. print(__doc__)
  2.  
  3. import matplotlib.pyplot as plt
  4.  
  5. from sklearn import datasets
  6. from sklearn.decomposition import PCA
  7. from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
  8.  
  9. iris = datasets.load_iris()
  10.  
  11. X = iris.data
  12. y = iris.target
  13. target_names = iris.target_names
  14.  
  15. pca = PCA(n_components=2)
  16. X_r = pca.fit(X).transform(X)
  17.  
  18. lda = LinearDiscriminantAnalysis(n_components=2)
  19. X_r2 = lda.fit(X, y).transform(X)
  20.  
  21. # Percentage of variance explained for each components
  22. print('explained variance ratio (first two components): %s'
  23. % str(pca.explained_variance_ratio_))
  24.  
  25. plt.figure()
  26. colors = ['navy', 'turquoise', 'darkorange']
  27. lw = 2
  28.  
  29. for color, i, target_name in zip(colors, [0, 1, 2], target_names):
  30. plt.scatter(X_r[y == i, 0], X_r[y == i, 1], color=color, alpha=.8, lw=lw,
  31. label=target_name)
  32. plt.legend(loc='best', shadow=False, scatterpoints=1)
  33. plt.title('PCA of IRIS dataset')
  34.  
  35. plt.figure()
  36. for color, i, target_name in zip(colors, [0, 1, 2], target_names):
  37. plt.scatter(X_r2[y == i, 0], X_r2[y == i, 1], alpha=.8, color=color,
  38. label=target_name)
  39. plt.legend(loc='best', shadow=False, scatterpoints=1)
  40. plt.title('LDA of IRIS dataset')
  41.  
  42. plt.show()

Sklearn还提供了归一化:

只在求解方法为lsqr和eigen时有效,就是前面提到的特征值分解和最小二乘啦。

分别用归一化/不归一化:

  1. clf1 = LinearDiscriminantAnalysis(solver='lsqr', shrinkage='auto').fit(X, y)
  2. clf2 = LinearDiscriminantAnalysis(solver='lsqr', shrinkage=None).fit(X, y)

  应用实例:

  1. from __future__ import division
  2.  
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5.  
  6. from sklearn.datasets import make_blobs
  7. from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
  8.  
  9. n_train = 20 # samples for training
  10. n_test = 200 # samples for testing
  11. n_averages = 50 # how often to repeat classification
  12. n_features_max = 75 # maximum number of features
  13. step = 4 # step size for the calculation
  14.  
  15. def generate_data(n_samples, n_features):
  16. """Generate random blob-ish data with noisy features.
  17.  
  18. This returns an array of input data with shape `(n_samples, n_features)`
  19. and an array of `n_samples` target labels.
  20.  
  21. Only one feature contains discriminative information, the other features
  22. contain only noise.
  23. """
  24. X, y = make_blobs(n_samples=n_samples, n_features=1, centers=[[-2], [2]])
  25.  
  26. # add non-discriminative features
  27. if n_features > 1:
  28. X = np.hstack([X, np.random.randn(n_samples, n_features - 1)])
  29. return X, y
  30.  
  31. acc_clf1, acc_clf2 = [], []
  32. n_features_range = range(1, n_features_max + 1, step)
  33. for n_features in n_features_range:
  34. score_clf1, score_clf2 = 0, 0
  35. for _ in range(n_averages):
  36. X, y = generate_data(n_train, n_features)
  37.  
  38. clf1 = LinearDiscriminantAnalysis(solver='lsqr', shrinkage='auto').fit(X, y)
  39. clf2 = LinearDiscriminantAnalysis(solver='lsqr', shrinkage=None).fit(X, y)
  40.  
  41. X, y = generate_data(n_test, n_features)
  42. score_clf1 += clf1.score(X, y)
  43. score_clf2 += clf2.score(X, y)
  44.  
  45. acc_clf1.append(score_clf1 / n_averages)
  46. acc_clf2.append(score_clf2 / n_averages)
  47.  
  48. features_samples_ratio = np.array(n_features_range) / n_train
  49.  
  50. plt.plot(features_samples_ratio, acc_clf1, linewidth=2,
  51. label="Linear Discriminant Analysis with shrinkage", color='navy')
  52. plt.plot(features_samples_ratio, acc_clf2, linewidth=2,
  53. label="Linear Discriminant Analysis", color='gold')
  54.  
  55. plt.xlabel('n_features / n_samples')
  56. plt.ylabel('Classification accuracy')
  57.  
  58. plt.legend(loc=1, prop={'size': 12})
  59. plt.suptitle('Linear Discriminant Analysis vs. \
  60. shrinkage Linear Discriminant Analysis (1 discriminative feature)')
  61. plt.show()

  结果图可以看出,shrinkage更鲁棒:

参考

  • http://blog.csdn.net/daunxx/article/details/51881956
  • http://scikit-learn.org/stable/modules/lda_qda.html

回归-LDA与QDA的更多相关文章

  1. LDA与QDA

    作者:桂. 时间:2017-05-23  06:37:31 链接:http://www.cnblogs.com/xingshansi/p/6892317.html 前言 仍然是python库函数sci ...

  2. ISLR系列:(2)分类 Logistic Regression & LDA & QDA & KNN

       Classification 此博文是 An Introduction to Statistical Learning with Applications in R 的系列读书笔记,作为本人的一 ...

  3. ML: 降维算法-LDA

    判别分析(discriminant analysis)是一种分类技术.它通过一个已知类别的“训练样本”来建立判别准则,并通过预测变量来为未知类别的数据进行分类.判别分析的方法大体上有三类,即Fishe ...

  4. Python 和 R 数据分析/挖掘工具互查

    如果大家已经熟悉python和R的模块/包载入方式,那下面的表查找起来相对方便.python在下表中以模块.的方式引用,部分模块并非原生模块,请使用 pip install * 安装:同理,为了方便索 ...

  5. R--基本统计分析方法(包及函数)

    摘要:目前经典的统计学分析方法主要有回归分析,Logistic回归,决策树,支持向量机,聚类分析,关联分析,主成分分析,对应分析,因子分析等,那么对于这些经典的分析方法在R中的使用主要有那些程序包及函 ...

  6. 统计学习导论:基于R应用——第四章习题

    第四章习题,部分题目未给出答案 1. 这个题比较简单,有高中生推导水平的应该不难. 2~3证明题,略 4. (a) 这个问题问我略困惑,答案怎么直接写出来了,难道不是10%么 (b) 这个答案是(0. ...

  7. R语言︱常用统计方法包+机器学习包(名称、简介)

    一.一些函数包大汇总 转载于:http://www.dataguru.cn/thread-116761-1-1.html 时间上有点过期,下面的资料供大家参考基本的R包已经实现了传统多元统计的很多功能 ...

  8. ML—R常用多元统计分析包(持续更新中……)

    基本的R包已经实现了传统多元统计的很多功能,然而CRNA的许多其它包提供了更深入的多元统计方法,下面要综述的包主要分为以下几个部分: 1) 多元数据可视化(Visualising multivaria ...

  9. [干货]Kaggle热门 | 用一个框架解决所有机器学习难题

    新智元推荐 来源:LinkedIn 作者:Abhishek Thakur 译者:弗格森 [新智元导读]本文是数据科学家Abhishek Thakur发表的Kaggle热门文章.作者总结了自己参加100 ...

随机推荐

  1. window.onload与document.ready的区别

    1. window.onload必须等到网页中所有的内容加载完(包含图片)才执行 document.ready网页中所有DOM结构绘制完执行,可能DOM并没有加载完 所有document.ready比 ...

  2. MYSQL中 ENUM 类型的详细解释

    ENUM 是一个字符串对象,其值通常选自一个允许值列表中,该列表在表创建时的列规格说明中被明确地列举. 在下列某些情况下,值也可以是空串("") 或 NULL: 如果将一个无效值插 ...

  3. C# CodeFirst编程模型一

    定义实体类型: 定义两个实体Menu和MenuCard,一个menu关联一个menucard,menucard包含对所有menu的引用. public class Menu { public int ...

  4. ES6 Promise 状态解惑

    Promise的概念在ES6标准推出来之前已经深入人心,很多框架和第三方库都有类似的实现.但在深入理解ES6的Promise对象的时候,受之前经验的影响,很多概念给人似是而非的感觉,其中有一个特别明显 ...

  5. css3 新属性

    一 选择器1 兄弟选择器 0 以第一个选择器开始,往后找满足条件的兄弟节点 class~class() <-- lorem+数字 -tab --> 可以输出默认文字2 属性选择器 标签[a ...

  6. git的使用及常用命令

    一,GIT是什么? git是目前世界上最先进的分布式版本控制系统 Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在 ...

  7. 内嵌的Component调用外部的方法

    如果一个内嵌的Component控件需要调用外部定义的方法,用outerDocument.方法名来调用,前提是该方法是public的.如:<mx:DataGridColumn headerTex ...

  8. Mongo汇总问题

    1. 数据 /* 5 */ { "_id" : ObjectId("5902f7ca2b3fe442d60a0946"), "code" : ...

  9. PTA自测-3 数组元素循环右移问题

    自测-3 数组元素循环右移问题  一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M≥0)个位置,即将A中的数据由(A0A1···A​N-1​​)变换为 ...

  10. 运行出错之未能加载文件或程序集“Microsoft.ReportViewer.Common, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91”或它的某一个依赖项。系统找不到指定的文件。文件名:“Microsoft.ReportViewer.Common, Version=11.0.0.0,

    这个问题是因为在项目中缺少Microsoft.ReportViewer.Common程序集. 方法一:缺少哪些文件或程序集,到程序开发计算机下找到对应的烤到客户端的程序启动目录下即可(项目烤到Bin\ ...