首页 > 编程语言 >Python实现线性判别分析鸢尾花数据集或随机生成两个线性可分的数据集

Python实现线性判别分析鸢尾花数据集或随机生成两个线性可分的数据集

时间:2024-01-20 17:04:52浏览次数:50  
标签:lda plt 判别分析 label set eig 线性 鸢尾花 mean

线性判别分析是一种经典的线性学习方法,在二分类问题上最早由Fisher在1936年提出,亦称Fisher线性判别。线性判别的思想非常朴素:给定训练样例集,设法将样例投影到一条直线上,使得同类样例的投影点尽可能接近,异类样例的投影点尽可能远离;在对新样本进行分类时,将其投影到同样的直线上,再根据投影点的位置来确定新样本的类别。

使用Python:

1. 导入线性判别分析函数或其它常用机器学习库,并自学线性判别分析函数的使用方法

2. 导入鸢尾花数据集或随机生成两个线性可分的数据集

3. 编写程序,使用线性判别分析对2个数据集进行分类

4. 以列表或图像的方式输出判别结果

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

f #导入包

import pandas as pd

import numpy as np

from matplotlib import pyplot as plt

from sklearn.preprocessing import LabelEncoder

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA

feature_dict = {i: label for i, label in zip(range(4),

                                             ("Sepal.Length",

                                              "Sepal.Width",

                                              "Petal.Length",

                                              "Petal.Width",))}

df = pd.read_csv('iris_training1.csv', sep=',')

df.columns = ["Number"] + [l for i, l in sorted(feature_dict.items())] + ['Species']

# to drop the empty line at file-end

df.dropna(how='all', inplace=True)

#把数据分成data和label

X = df[["Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"]].values

y = df['Species'].values

enc = LabelEncoder()

label_encoder = enc.fit(y)

y = label_encoder.transform(y) + 1

label_dict = {1: 'setosa', 2: 'versicolor', 3: 'virginica'}

#三个类别均值

np.set_printoptions(precision=4)

mean_vectors = []

for c1 in range(1, 4):

    mean_vectors.append(np.mean(X[y == c1], axis=0))

    print('Mean Vector class %s : %s\n' % (c1, mean_vectors[c1 - 1]))

    #计算两个 4*4 维矩阵:类内散布矩阵和类间散布矩阵

#类内散布矩阵

S_W = np.zeros((4, 4))

for c1, mv in zip(range(1, 4), mean_vectors):

    # scatter matrix for every class

    class_sc_mat = np.zeros((4, 4))

    for row in X[y == c1]:

        # make column vectors

        row, mv = row.reshape(4, 1), mv.reshape(4, 1)

        class_sc_mat += (row - mv).dot((row - mv).T)

    # sum class scatter metrices

    S_W += class_sc_mat


#类间散布矩阵

overall_mean = np.mean(X, axis=0)

S_B = np.zeros((4, 4))

for i, mean_vec in enumerate(mean_vectors):

    n = X[y == i + 1, :].shape[0]

    # make column vector

    mean_vec = mean_vec.reshape(4, 1)

    # make column vector

    overall_mean = overall_mean.reshape(4, 1)

    S_B += n * (mean_vec - overall_mean).dot((mean_vec - overall_mean).T)


eig_vals, eig_vecs = np.linalg.eig(np.linalg.inv(S_W).dot(S_B))

for i in range(len(eig_vals)):

    eigvec_sc = eig_vecs[:, i].reshape(4, 1)

    print('\n Eigenvector {}: \n {}'.format(i+1, eigvec_sc.real))

    print('Eigenvalue {: }: {:.2e}'.format(i+1, eig_vals[i].real))


# make a list of (eigenvalue, eigenvector) tuples

eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:, i]) for i in range(len(eig_vals))]


# sort the (eigenvalue, eigenvector) tuples from high to low

eig_pairs = sorted(eig_pairs, key=lambda k: k[0], reverse=True)


# Visually cinfirm that the list is correctly sorted by decreasing eigenvalues

print('特征向量: \n')

for i in eig_pairs:

    print(i[0])


#特征值

eigv_sum = sum(eig_vals)

for i, j in enumerate(eig_pairs):

    print('eigenvalue {0:}: {1:.2%}'.format(i + 1, (j[0] / eigv_sum).real))


#选择前两维特征

#特征矩阵

W = np.hstack((eig_pairs[0][1].reshape(4, 1), eig_pairs[1][1].reshape(4, 1)))


#LDA

X_lda = X.dot(W)

assert X_lda.shape == (150, 2), 'The matrix is not 150*2 dimensional.'


def plt_step_lda():

    ax = plt.subplot(111)

    for label, marker, color in zip(range(1, 4), ('o', '^', 's'), ('green', 'orange', 'pink')):

        plt.scatter(x=X_lda[:, 0].real[y == label],

                    y=X_lda[:, 1].real[y == label],

                    marker=marker,

                    color=color,

                    alpha=0.5,

                    label=label_dict[label])

    plt.xlabel('LD1')

    plt.ylabel('LD2')

    leg = plt.legend(loc='upper right', fancybox=True)

    leg.get_frame().set_alpha(0.5)

    plt.title('LDA: Iris projection onto the first 2 linear discriminants')


    # hide axis ticks

    plt.tick_params(axis='both', which='both', bottom='off',

                    top='off', labelbottom='on', left='off',

                    labelleft='on')

    ax.spines['top'].set_visible(False)

    ax.spines['right'].set_visible(False)

    ax.spines['bottom'].set_visible(False)

    ax.spines['left'].set_visible(False)


    plt.grid()

    plt.tight_layout()

    plt.show()

plt_step_lda()



#使用sklearn实现lda:

# LDA

sklearn_lda = LDA(n_components=2)

X_lda_sklearn = sklearn_lda.fit_transform(X, y)


def plot_scikit_lda(X, title):

    ax = plt.subplot(111)

    for label, marker, color in zip(range(1, 4), ('o', '^', 's'), ('green', 'orange', 'pink')):

        plt.scatter(x=X_lda[:, 0].real[y == label],

                    # flip the figure

                    y=X_lda[:, 1].real[y == label] * -1,

                    marker=marker,

                    color=color,

                    alpha=0.5,

                    label=label_dict[label])

    plt.xlabel('LD1')

    plt.ylabel('LD2')


    leg = plt.legend(loc='upper right', fancybox=True)

    leg.get_frame().set_alpha(0.5)

    plt.title(title)


    # hide axis ticks

    plt.tick_params(axis='both', which='both', bottom='off',

                    top='off', labelbottom='on', left='off',

                    labelleft='on')


    # remove axis spines

    ax.spines['top'].set_visible(False)

    ax.spines['right'].set_visible(False)

    ax.spines['bottom'].set_visible(False)

    ax.spines['left'].set_visible(False)


    plt.grid()

    plt.tight_layout()

    plt.show()

plot_scikit_lda(X, title='Default LDA via scikit-learn')

#导入包

import pandas as pd

import numpy as np

from matplotlib import pyplot as plt

from sklearn.preprocessing import LabelEncoder

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA

feature_dict = {i: label for i, label in zip(range(4),

                                             ("Sepal.Length",

                                              "Sepal.Width",

                                              "Petal.Length",

                                              "Petal.Width",))}

df = pd.read_csv('iris_training1.csv', sep=',')

df.columns = ["Number"] + [l for i, l in sorted(feature_dict.items())] + ['Species']

# to drop the empty line at file-end

df.dropna(how='all', inplace=True)

#把数据分成data和label

X = df[["Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"]].values

y = df['Species'].values

enc = LabelEncoder()

label_encoder = enc.fit(y)

y = label_encoder.transform(y) + 1

label_dict = {1: 'setosa', 2: 'versicolor', 3: 'virginica'}

#三个类别均值

np.set_printoptions(precision=4)

mean_vectors = []

for c1 in range(1, 4):

    mean_vectors.append(np.mean(X[y == c1], axis=0))

    print('Mean Vector class %s : %s\n' % (c1, mean_vectors[c1 - 1]))

    #计算两个 4*4 维矩阵:类内散布矩阵和类间散布矩阵

#类内散布矩阵

S_W = np.zeros((4, 4))

for c1, mv in zip(range(1, 4), mean_vectors):

    # scatter matrix for every class

    class_sc_mat = np.zeros((4, 4))

    for row in X[y == c1]:

        # make column vectors

        row, mv = row.reshape(4, 1), mv.reshape(4, 1)

        class_sc_mat += (row - mv).dot((row - mv).T)

    # sum class scatter metrices

    S_W += class_sc_mat


#类间散布矩阵

overall_mean = np.mean(X, axis=0)

S_B = np.zeros((4, 4))

for i, mean_vec in enumerate(mean_vectors):

    n = X[y == i + 1, :].shape[0]

    # make column vector

    mean_vec = mean_vec.reshape(4, 1)

    # make column vector

    overall_mean = overall_mean.reshape(4, 1)

    S_B += n * (mean_vec - overall_mean).dot((mean_vec - overall_mean).T)


eig_vals, eig_vecs = np.linalg.eig(np.linalg.inv(S_W).dot(S_B))

for i in range(len(eig_vals)):

    eigvec_sc = eig_vecs[:, i].reshape(4, 1)

    print('\n Eigenvector {}: \n {}'.format(i+1, eigvec_sc.real))

    print('Eigenvalue {: }: {:.2e}'.format(i+1, eig_vals[i].real))


# make a list of (eigenvalue, eigenvector) tuples

eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:, i]) for i in range(len(eig_vals))]


# sort the (eigenvalue, eigenvector) tuples from high to low

eig_pairs = sorted(eig_pairs, key=lambda k: k[0], reverse=True)


# Visually cinfirm that the list is correctly sorted by decreasing eigenvalues

print('特征向量: \n')

for i in eig_pairs:

    print(i[0])


#特征值

eigv_sum = sum(eig_vals)

for i, j in enumerate(eig_pairs):

    print('eigenvalue {0:}: {1:.2%}'.format(i + 1, (j[0] / eigv_sum).real))


#选择前两维特征

#特征矩阵

W = np.hstack((eig_pairs[0][1].reshape(4, 1), eig_pairs[1][1].reshape(4, 1)))


#LDA

X_lda = X.dot(W)

assert X_lda.shape == (150, 2), 'The matrix is not 150*2 dimensional.'


def plt_step_lda():

    ax = plt.subplot(111)

    for label, marker, color in zip(range(1, 4), ('o', '^', 's'), ('green', 'orange', 'pink')):

        plt.scatter(x=X_lda[:, 0].real[y == label],

                    y=X_lda[:, 1].real[y == label],

                    marker=marker,

                    color=color,

                    alpha=0.5,

                    label=label_dict[label])

    plt.xlabel('LD1')

    plt.ylabel('LD2')

    leg = plt.legend(loc='upper right', fancybox=True)

    leg.get_frame().set_alpha(0.5)

    plt.title('LDA: Iris projection onto the first 2 linear discriminants')


    # hide axis ticks

    plt.tick_params(axis='both', which='both', bottom='off',

                    top='off', labelbottom='on', left='off',

                    labelleft='on')

    ax.spines['top'].set_visible(False)

    ax.spines['right'].set_visible(False)

    ax.spines['bottom'].set_visible(False)

    ax.spines['left'].set_visible(False)


    plt.grid()

    plt.tight_layout()

    plt.show()

plt_step_lda()



#使用sklearn实现lda:

# LDA

sklearn_lda = LDA(n_components=2)

X_lda_sklearn = sklearn_lda.fit_transform(X, y)


def plot_scikit_lda(X, title):

    ax = plt.subplot(111)

    for label, marker, color in zip(range(1, 4), ('o', '^', 's'), ('green', 'orange', 'pink')):

        plt.scatter(x=X_lda[:, 0].real[y == label],

                    # flip the figure

                    y=X_lda[:, 1].real[y == label] * -1,

                    marker=marker,

                    color=color,

                    alpha=0.5,

                    label=label_dict[label])

    plt.xlabel('LD1')

    plt.ylabel('LD2')


    leg = plt.legend(loc='upper right', fancybox=True)

    leg.get_frame().set_alpha(0.5)

    plt.title(title)


    # hide axis ticks

    plt.tick_params(axis='both', which='both', bottom='off',

                    top='off', labelbottom='on', left='off',

                    labelleft='on')


    # remove axis spines

    ax.spines['top'].set_visible(False)

    ax.spines['right'].set_visible(False)

    ax.spines['bottom'].set_visible(False)

    ax.spines['left'].set_visible(False)


    plt.grid()

    plt.tight_layout()

    plt.show()

plot_scikit_lda(X, title='Default LDA via scikit-learn')

运行结果:

Python实现线性判别分析鸢尾花数据集或随机生成两个线性可分的数据集_数据集

Python实现线性判别分析鸢尾花数据集或随机生成两个线性可分的数据集_ci_02

1. 叙述线性判别分析的实现过程

答:给定训练样例集,设法将样例投影到一条直线上,使得同类样例的投影点尽可能接近、异类样例的投影点尽可能远离;在对新样本进行分类时,将其投影到同样的这条直线上,再根据投影点的位置来确定新样本的类别。

输入:数据集 D = {(x1, y1),  (x2, y2), .... (xm, ym)},其中任意样本 xi 为 n维向量, yi € {C1,  c2, ...Ck},降维到的维度 d。

输出:降维后的样本集 D'

计算类内散度矩阵Sw

Python实现线性判别分析鸢尾花数据集或随机生成两个线性可分的数据集_ci_03

Python实现线性判别分析鸢尾花数据集或随机生成两个线性可分的数据集_线性判别分析_04

计算类间散度矩阵

Python实现线性判别分析鸢尾花数据集或随机生成两个线性可分的数据集_ci_05

Python实现线性判别分析鸢尾花数据集或随机生成两个线性可分的数据集_线性判别分析_06

计算矩阵Sw-1Sb

计算Sw-1Sb的最大的 d个特征值和对应的 d个特征向量 (w1, w2, ... wd),得到投影矩阵 W

对样本集中的每一个样本特征 xii,转化为新的样本zi = WTxi

得到输出样本集D' = {(z1, y1),  (z2, y2), .... (zm, ym)}

2. 说明“Linear Discriminant Analysis”函数(Python)或“Classify”函数(Matlab)中各参数的意义

答: solver : 即求LDA超平面特征矩阵使用的方法。可以选择的方法有奇异值分解"svd",最小二乘"lsqr"和特征分解"eigen"。一般来说特征数非常多的时候推荐使用svd,而特征数不多的时候推荐使用eigen。主要注意的是,如果使用svd,则不能指定正则化参数shrinkage进行正则化。默认值是svd

shrinkage:正则化参数,可以增强LDA分类的泛化能力。如果仅仅只是为了降维,则一般可以忽略这个参数。默认是None,即不进行正则化。可以选择"auto",让算法自己决定是否正则化。当然我们也可以选择不同的[0,1]之间的值进行交叉验证调参。注意shrinkage只在solver为最小二乘"lsqr"和特征分解"eigen"时有效。

priors :类别权重,可以在做分类模型时指定不同类别的权重,进而影响分类模型建立。降维时一般不需要关注这个参数。

n_components:即我们进行LDA降维时降到的维数。在降维时需要输入这个参数。注意只能为[1,类别数-1)范围之间的整数。如果我们不是用于降维,则这个值可以用默认的None。

从上面的描述可以看出,如果我们只是为了降维,则只需要输入n_components,注意这个值必须小于“类别数-1”。

标签:lda,plt,判别分析,label,set,eig,线性,鸢尾花,mean
From: https://blog.51cto.com/u_16532251/9345762

相关文章

  • AP5101C 高压线性 LED恒流驱动器 DFN2*2 LED灯汽车雾灯转向灯
    产品描述   AP5101C是一款高压线性LED恒流芯片,简单、内置功率管,适用于6-100V输入的高精度降压LED恒流驱动芯片。电流2.0A。AP5101C可实现内置MOS做2.0A,外置MOS可做3.0A的。AP5101C内置温度保护功能,温度保护点为130度,温度达到130度时,输出电流慢......
  • 笔记重修计划三:线性基(施工中)
    正在备战THUWC,暂时停更。目前准备将这一系列内容迁移到cnblogs。本文属于笔记重修计划中的第三部,主要介绍广义的线性基与高斯消元的关联吗,以及在OI中应用较广的异或线性基。建议先阅读重修计划二高斯消元(目前很需要施工故未公开)的内容。其实我觉得这两章的内容如果分开来看......
  • 【算法】【线性表】【链表】LRU 缓存
    1 题目请你设计并实现一个满足  LRU(最近最少使用)缓存 约束的数据结构。实现 LRUCache 类:LRUCache(intcapacity) 以 正整数 作为容量 capacity 初始化LRU缓存intget(intkey) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。voidput......
  • 线性代数
    线性相关若有\(\mathbb{a}=\{a_1,a_2,\dots,a_n\}\),且\(x\mathbb{a}=0\),那么这组向量线性相关。大致可以理解成有一些无用的方程。一组可以表示原来所有线性组合的向量叫做一组基。如果值域只有\(0/1\),那这就是异或线性基。否则,上高消就可以搞出一组这样的基。异或线性基......
  • SAS,Stata,HLM,R,SPSS和Mplus分层线性模型HLM分析学生受欢迎程度数据|附代码数据
    全文链接:http://tecdat.cn/?p=10809最近我们被客户要求撰写关于分层线性模型的研究报告,包括一些图形和统计输出。本文用于比较六个不同统计软件程序(SAS,Stata,HLM,R,SPSS和Mplus)的两级分层线性模型的过程和输出下面介绍的六个模型都是两级分层模型的变体,也称为多级模型,这是混合模型......
  • 线性基
    P4570[BJWC2011]元素有两种属性要求其中一种选出来线性无关(不能异或为0)前提下,另外一种属性加起来最大,把第二种属性从大到小排个序,能加就加。感性理解一下,就是我们对于线性基每个位置我们都尽可能让第二种属性大的去占住,这样就可以保证第二种属性加起来最大#include<bit......
  • 【算法】【线性表】【链表】随机链表的复制
    1 题目给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random......
  • 【算法】【线性表】【链表】环形链表
    1 题目给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从0开始)。注意:pos 不作为参数进行传递 。仅......
  • 数学建模入门笔记(1)——Python pulp库解线性规划问题
    参考:Python求解线性规划——PuLP使用教程-Only(AR)-博客园(cnblogs.com)1.Definethemodelmodel=pl.LpProblem(name="",sense=pl.LpMaximize)name模型的名字sense模型的类型(pl.LpMaximize/pl.LpMinimize)2.Definethedecisionvariables用x[i]存储变量,命名为xi......
  • 【算法】【线性表】【链表】K 个一组翻转链表
    1 题目给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。示例1:......