Python中的LDA线性判别分析技巧
更新时间:2023-11-16LDA线性判别分析技巧
LDA(线性判别分析)是一种常用的分类算法,它可以将数据投射到低维空间,然后再进行分类。在这个过程中,LDA会尽量让不同类别之间的距离最大化,同时让同一类别内部的方差最小化。这种算法在很多领域都有应用,包括模式识别、人脸识别、自然语言处理等。
LDA的原理
LDA的核心思想是将高维数据投射到低维空间,使得不同类别之间的距离最大化,同时保持同一类别内部的方差最小化。具体来讲,我们可以先计算每个类别的均值向量:
import numpy as np def compute_mean_vectors(X, y): unique_classes=np.unique(y) mean_vectors=[] for c in unique_classes: mean_vectors.append(np.mean(X[y==c], axis=0)) return np.array(mean_vectors)
然后计算类内散度矩阵$S_w$和类间散度矩阵$S_b$:
def compute_scatter_matrices(X, y): unique_classes=np.unique(y) mean_vectors=compute_mean_vectors(X, y) S_w=np.zeros((X.shape[1], X.shape[1])) S_b=np.zeros((X.shape[1], X.shape[1])) for c, mv in zip(unique_classes, mean_vectors): X_c=X[y==c] n_c=X_c.shape[0] mean_vec_c=mv.reshape((-1, 1)) S_w +=np.dot((X_c-mean_vec_c), (X_c-mean_vec_c).T) mean_vec=mean_vectors.mean(axis=0).reshape((-1, 1)) S_b +=n_c * np.dot((mean_vec_c - mean_vec), (mean_vec_c - mean_vec).T) return S_w, S_b
接着我们可以计算投影矩阵$W$,通过对原始数据进行投影,即可得到低维空间下的表示:
def lda(X, y, n_components): S_w, S_b=compute_scatter_matrices(X, y) eigenvalues, eigenvectors=np.linalg.eig(np.dot(np.linalg.inv(S_w), S_b)) sorted_indices=np.argsort(eigenvalues)[::-1][:n_components] W=eigenvectors[:,sorted_indices] return np.dot(X, W)
LDA的应用
LDA在很多领域都有应用,下面我们介绍两个实际的案例。
人脸识别
人脸识别是LDA的一个重要应用,我们可以使用LDA将人脸数据投射到低维空间,然后再进行识别。下面是一个使用LDA进行人脸识别的例子:
from sklearn.datasets import fetch_lfw_people from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.neighbors import KNeighborsClassifier from sklearn.decomposition import PCA from sklearn.discriminant_analysis import LinearDiscriminantAnalysis data=fetch_lfw_people(min_faces_per_person=70, resize=0.4) X_train, X_test, y_train, y_test=train_test_split( data.data, data.target, stratify=data.target, test_size=0.25, random_state=42) # 使用PCA降维 pca=PCA(n_components=100) X_train_pca=pca.fit_transform(X_train) X_test_pca=pca.transform(X_test) # 使用LDA降维 lda=LinearDiscriminantAnalysis(n_components=100) X_train_lda=lda.fit_transform(X_train, y_train) X_test_lda=lda.transform(X_test) # 训练KNN分类器,并计算准确率 knn_pca=KNeighborsClassifier(n_neighbors=5) knn_pca.fit(X_train_pca, y_train) accuracy_pca=accuracy_score(y_test, knn_pca.predict(X_test_pca)) knn_lda=KNeighborsClassifier(n_neighbors=5) knn_lda.fit(X_train_lda, y_train) accuracy_lda=accuracy_score(y_test, knn_lda.predict(X_test_lda)) print("PCA accuracy:", accuracy_pca) print("LDA accuracy:", accuracy_lda)
从结果可以看出,使用LDA降维可以比PCA取得更好的分类结果。
文本分类
LDA也可以用于文本分类,我们可以将每个文档映射到一个低维空间,然后再进行分类。下面是一个使用LDA进行文本分类的例子:
from sklearn.datasets import fetch_20newsgroups from sklearn.feature_extraction.text import CountVectorizer from sklearn.model_selection import cross_val_score from sklearn.discriminant_analysis import LinearDiscriminantAnalysis data=fetch_20newsgroups(subset='all') vectorizer=CountVectorizer(stop_words='english') X=vectorizer.fit_transform(data.data) y=data.target lda=LinearDiscriminantAnalysis(n_components=20) X_lda=lda.fit_transform(X.toarray(), y) scores=cross_val_score(LogisticRegression(), X_lda, y, cv=5) print("LDA accuracy:", np.mean(scores))
同样可以看到,使用LDA降维可以比直接使用词频向量取得更好的分类结果。
总结
LDA(线性判别分析)是一种常用的分类算法,它可以将数据投射到低维空间,然后再进行分类。在这个过程中,LDA会尽量让不同类别之间的距离最大化,同时让同一类别内部的方差最小化。在人脸识别、文本分类等领域都有应用。