一、算法概述
线性判别分析(Linear Discriminant Analysis,LDA)是常用的一种分类算法。它是一种有监督学习方法,也就是需要已知每个样本的类别标签。LDA从特征空间中提取线性判别信息,用于在低维空间中对数据进行分类。
LDA的主要思想是:将样本投影到一条直线上,使得同类之间的距离尽可能小,不同类之间的距离尽可能大。因此,LDA在降维同时也完成了分类任务。
二、算法流程
LDA的算法流程如下:
- 计算每个类别的均值向量。
- 计算类间散度矩阵和类内散度矩阵。
- 求出最大化目标函数的投影方向。
- 降维并进行分类。
三、算法实现
第一步:计算均值向量
设有样本集$D={x_1, x_2, ..., x_n}$,其中$x_i\in R^d$表示第$i$个样本。将样本按照类别分开,设有$k$个类别。第$i$类样本的个数为$n_i$,均值向量为$u_i$。
import numpy as np def mean_vectors(X, y): class_labels = np.unique(y) n_classes = class_labels.shape[0] mean_vectors = np.zeros((n_classes, X.shape[1])) for cl, label in enumerate(class_labels): mean_vectors[cl,:] = np.mean(X[y==label], axis=0) return mean_vectors
第二步:计算类间散度矩阵和类内散度矩阵
类间散度矩阵$S_B$和类内散度矩阵$S_W$的计算方式如下:
$$S_B = \sum_{i=1}^{k}n_i(u_i - u)(u_i - u)^T$$ $$S_W = \sum_{i=1}^{k}\sum_{x\in D_i}(x-u_i)(x-u_i)^T$$ 其中,$u$为所有样本的均值向量,$S_B$表示类别之间的差异,$S_W$表示类别内部的差异。def scatter_matrices(X, y): mean_vectors = mean_vectors(X, y) n_features = X.shape[1] s_within = np.zeros((n_features, n_features)) s_between = np.zeros((n_features, n_features)) mean_overall = np.mean(X, axis=0) for cl, mv in enumerate(mean_vectors): class_sc_mat = np.zeros((n_features, n_features)) for row in X[y == cl]: row, mv = row.reshape(n_features, 1), mv.reshape(n_features, 1) class_sc_mat += (row - mv).dot((row - mv).T) s_within += class_sc_mat n = X[y==cl,:].shape[0] mean_diff = (mv - mean_overall).reshape(n_features, 1) s_between += n * mean_diff.dot(mean_diff.T) return s_within, s_between
第三步:求投影方向
为了求出最大化目标函数的投影方向,需要计算矩阵$S_W^{-1}S_B$的特征向量和特征值。在计算投影矩阵的时候,我们可以取最大的$d'$个特征向量($d'$表示投影后保留的维数)。
def lda(X, y, n_components): s_within, s_between = scatter_matrices(X, y) eig_vals, eig_vecs = np.linalg.eig(np.linalg.inv(s_within).dot(s_between)) eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i]) for i in range(len(eig_vals))] eig_pairs = sorted(eig_pairs, key=lambda k: k[0], reverse=True) proj_mat = eig_pairs[0][1].reshape(X.shape[1],1) for i in range(1,n_components): proj_mat = np.hstack((proj_mat, eig_pairs[i][1].reshape(X.shape[1],1))) return X.dot(proj_mat), proj_mat
第四步:降维并进行分类
使用投影矩阵将样本投影到新的低维空间中,并使用分类算法进行分类。下面的例子中,我们使用支持向量机作为分类器。
from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.svm import SVC iris = datasets.load_iris() X = iris.data y = iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) X_train_lda, proj_mat = lda(X_train, y_train, 2) X_test_lda = X_test.dot(proj_mat) classifier = SVC() classifier.fit(X_train_lda, y_train) score = classifier.score(X_test_lda, y_test) print("Accuracy:", score)
四、总结
LDA作为一种常用的分类算法,在特征提取和降维方面有着广泛的应用。通过计算均值向量和散度矩阵,我们可以求出最大化目标函数的投影方向,从而实现对数据的降维和分类。