LDAとは。 機械学習のための線形判別分析

LDAとは。

By Priyankur Sarkar

Linear Discriminant AnalysisまたはLDAは次元削減手法の1つである。 機械学習やパターン分類の応用において、前処理の段階として使用される。 LDAの目的は、高次元空間の特徴を低次元空間に投影し、次元の呪いを回避し、リソースと次元コストを削減することである。 オリジナルの線形判別は2クラスの手法として記述されていた。 その後、C.R.Raoにより複数クラスが一般化され、Multiple Discriminant Analysisと呼ばれるようになった。 LDAは教師あり分類の手法であり、競争力のある機械学習モデルを作るための一部と考えられている。 このカテゴリの次元削減は、画像認識やマーケティングにおける予測分析などの分野で使用されている。次元削減とは何か?次元削減の技術は、機械学習、データマイニング、バイオインフォマティクス、情報検索のアプリケーションで重要である。 簡単に言えば、データの大部分を保持したまま、特定のデータセットの次元(=変数)を削減することである。 多次元データは、互いに相関を持つ複数の特徴から構成される。次元削減により、多次元データをわずか2次元または3次元にプロットすることができる。 ロジスティック回帰の限界は何か?ロジスティック回帰は、シンプルで強力な線形分類アルゴリズムです。 しかし、これにはいくつかの欠点があり、LDAのような代替の分類アルゴリズムにつながっています。 ロジスティック回帰の限界のいくつかは以下のとおりです:2クラス問題 – ロジスティック回帰は、伝統的に2クラスとバイナリ分類問題に使用されています。 外挿されてマルチクラス分類で使用することもできますが、これはめったに実行されません。 一方,線形判別分析は,マルチクラス分類が必要なときはいつでもよりよい選択とみなされ,バイナリ分類の場合は,ロジスティック回帰とLDAの両方が適用される.よく分離したクラスで不安定 – クラスがよく分離しているとき,ロジスティック回帰は安定性に欠けることがある. 少数の例で不安定 – パラメータを推定する例が少ないと,ロジスティック回帰は不安定になる. しかし、線形判別分析は、そのような場合でも安定する傾向があるので、より良い選択肢です。LDAモデルへの実用的なアプローチを持つには?各色が異なるクラスを表す2つの変数の間の関係をプロットした状況を考えてみましょう。 もし、次元数を1にしてよければ、下図のようにすべてをX軸に投影することができます。 この方法では、2番目の特徴によって提供される有用な情報が無視されます。 しかし、LDAを使ってそれをプロットすることができます。 LDAの利点は、両方の特徴からの情報を使って新しい軸を作成し、その結果、2つの変数の分散を最小化し、クラス距離を最大化することです。LDAはどのように機能するか?LDAは主に、高次元空間の特徴を低次元に投影することに焦点を当てています。 まず、異なるクラスの平均間の距離であるクラス間の分離可能性を計算する必要があります。 次に、各クラスの平均とサンプルの間の距離を計算します。 最後に、クラス間分散を最大化し、クラス内分散を最小化する低次元空間を構築する。 LDAのモデルはどのように表現されるのか? モデルは、各クラスについて計算されたデータの統計的特性から構成されます。 多変数の場合は、多変量ガウスで計算されます。 多変量は平均と共変量行列です。予測は、統計的特性をLDA式に与えることによって行われます。 統計的特性はデータから推定されます。 LDAモデルはどのように学習するのか?LDAモデルがデータに対して行う仮定:データ中の各変数は、プロットするとベルカーブの形になる、すなわちガウシアンである。平均 =Sum(x)/Nkhere Mean = クラスに対する x の平均値 N = 数 k = 数 Sum(x) = 各入力 x の値の合計.分散は,平均からの各値の差の2乗の平均としてすべてのクラスにわたって計算される: Σ²=Sum((x – M)²)/(N – k)where Σ² = すべての入力xにわたる分散. Sum((x – M)²) = すべての (x – M)²の値の和. M = 入力xの平均 LDAモデルは、どのように予測を行うのか?LDAモデルは、確率を推定するためにベイズの定理を使用する。 彼らは、新しい入力データセットが各クラスに属する確率に基づいて予測を行う。 最も高い確率を持つクラスが出力クラスとみなされ、LDAは予測を行う。 予測は、入力が与えられたときの出力クラスの確率を推定するベイズの定理を用いることで簡単に行うことができる。 また、各クラスの確率と各クラスに属するデータの確率を利用する: P(Y=x|X=x) = / ここで x = 入力、k = 出力クラス。 Plk = Nk/n または学習データで観測された各クラスの基本確率。 fk(x) = xがクラスkに属する推定確率.f(x) はガウス分布関数を用いてプロットされ、それを上記の式にプラグインすると、次のような式が得られる: Dk(x) = x∗(mean/Σ²) – (mean²/(2*Σ²)). + Dk(x)はクラスkの判別関数と呼ばれ、入力x、平均、Σ²、Plkがデータから推定され、最も大きな値を持つクラスが出力分類に考慮されます。 LDAのデータを準備するには?LDAモデルを構築するためにデータを準備する際に心に留めておくべきいくつかの提案: LDAは、主にカテゴリカルの出力変数がある分類問題で使用されます。 標準的なLDAモデルは、入力変数のガウス分布の利用を可能にします。 各属性の一変量分布を確認し、よりガウス的な分布に変換する必要があります。 LDAは各入力変数が同じ分散を持っていると仮定するので、LDAモデルを使用する前にデータを標準化することが常に良いことです。 LDAは各入力変数が同じ分散であることを仮定しているので、LDAモデルを使用する前に必ずデータを標準化した方が良いです。平均を0、標準偏差を1にしてください。 まずはモデルに必要なライブラリをインポートします。from sklearn.datasets import load_wineimport pandas as pdimport numpy as npnp.set_printoptions(precision=4)from matplotlib import pyplot as pltimport seaborn as snssns.set()from sklearn.datasets import load_wineimport pdimport numpy as npnp.set_printoptions(precision=4)preprocessing import LabelEncoderfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import confusion_matrixワインデータセットを扱うので、UCI機械学習リポジトリから入手することが可能です。 Wine_info = load_wine()X = pd.DataFrame(wine_info.data, columns=wine_info.feature_names)y = pd.Categorical.from_codes(wine_info.target, wine_info.target_names)The wine dataset consist of 178 rows with 13 columns each each.X. (Xは13列の行からなる)ワインデータセットは178行からなります。shape(178, 13)ワインデータセットの属性は、ワインのアルコール度数、マグネシウム含有量、色の濃さ、色相など、様々な特徴から構成されています:X.head()ワインデータセットには3種類のワインが含まれています:wine_info.target_names array(, dtype='<U7′)Now we create a DataFrame which contains both the features and the content of the dataset:df = X.join(pd. columns).The dataset of the wine dataset contains the three different kinds of wine:wine_info.target_names array(, dtype='<U7′)The dataset of the wine dataet contains the characteristics and the content of two different kinds of wine.Series(y, name=’class’))線形判別分析のプロセスを以下の5つのステップに分けることができます:ステップ1 – クラス内およびクラス間の散布行列を計算するステップ2 – 散布行列の固有ベクトルとそれに対応する固有値を計算するステップ3 – 固有値をソートして上位k件を選択するステップ。ステップ4 – k個の固有値にマッピングされた固有ベクトルを含む新しい行列を作成するステップ5 – データとステップ4の行列の内積を取ることによって新しい特徴を取得するクラス内散布行列クラス内散布行列を計算するには、次の数式を使用できます:ここで、c = 別々のクラスの総数、ここで、x = サンプル(つまり行)です。 ここで、各特徴の平均値からベクトルを作成します:feature_means1 = pd.DataFrame(columns=wine_info.target_names)for c, rows in df.groupby(‘class’):feature_means1 = rows.mean()feature_means1 この平均ベクトルを上記の式にプラグインして、クラス内散布行列を得ます: withinclass_scatter_matrix = np.DataFrame_name(rows=wine_info.target_names):feature_means1 (mi),weeks(mi)。zeros((13,13))for c, rows in df.groupby(‘class’):rows = rows.drop(, axis=1)s = np.zeros((13,13))for index, row in rows.iterrows():x, mc = row.values.reshape(13,1),feature_means1.values.reshape(13,1)s += (x – mc).dot((x – mc).T)withinclass_scatter_matrix += sクラス間散布行列次の数式を使用してクラス間散布行列を計算することができます:andfeature_means2 = df.mean()betweenclass_scatter_matrix = np.zeros((13,13))for c in feature_means1: n = len(df.loc == c].index) mc, m = feature_means1.values.reshape(13,1), feature_means2.values.reshape(13,3), feature_means2.values.reshape(13,4), feature_means1.values.reshape(13,4), feature_means2.values.reshape(13,4)reshape(13,1)betweenclass_scatter_matrix += n * (mc – m).dot((mc – m).T)Now we will solve the generalized eigenvalue problem to obtain the linear discriminants for:eigen_values, eigen_vectors = np.Scatter_matrix.T。linalg.eig(np.linalg.inv(withinclass_scatter_matrix).dot(betweenclass_scatter_matrix))We sort the eigenvalues from the highest to the lowest because the eigenvalues with the highest values carry the most information about the distribution of data is done.ここで、固有値を高いものから低いものへ並べ替えます。 次に、最初に固有ベクトルをkする。 最後に、並べ替えが終わった後に、固有値が同じ固有ベクトルに対応することを確認するために、固有値を一時配列に入れます:eigen_pairs = ), eigen_vectors) for i in range(len(eigen_values))eigen_pairs = sorted(eigen_pairs, key=lambda x: x, reverse=True)for pair in eigen_pairs:print(pair)237.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.4612319830225146.982859387586841.4317197551638386e-141.2141209883217706e-141.2141209883217706e-148.279823065850476e-157.105427357601002e-156.0293733655173466e-156.0293733655173466e-154.737608877108813e-154.737608877108813e-152.4737196789039026e-159.84629525010022e-16ここで、各成分で分散のどれくらいを説明しているのかがわかりにくいので、値をパーセンテージに変換します。sum_of_eigen_values = sum(eigen_values)print(‘Explained Variance’)for i, pair in enumerate(eigen_pairs): print(‘Eigenvector {}: {}’.format(i, (pair/sum_of_eigen_values).real))Explained Variance固有ベクトル 0: 0.8348256799387275固有ベクトル 1: 0.1651743200612724 固有ベクトル 2: 5.033396012077518e-17 固有ベクトル 3: 4.4.268399397827047e-17固有ベクトル 4:4.268399397827047e-17 固有ベクトル 5:2.9108789097898625e-17 固有ベクトル 6:2.498004906118145e-17 固有ベクトル 7:2.119704204950956e-17 固有ベクトル 8:2.119704204950956e-17 固有ベクトル 9:1.1.665567688286435e-17 固有ベクトル 10: 1.665567688286435e-17 固有ベクトル 11: 8.696681541121664e-18 固有ベクトル 12: 3.4615924706522496e-18 最初に、最初の二つの固有ベクトルを用いて新しい行列Wを作る:W_matrix = np.W_Matrix = 8.696681541121664e-18.8.69668154126e-18.8.66556756e-18.6655675688286435e-17.6655676286435e17hstack((eigen_pairs.reshape(13,1), eigen_pairs.reshape(13,1))).real 次に,X と W の内積を新しい行列 Y に保存します:Y = X∗W ここで,X = n サンプル,d 次元を持つ n x d 行列. X_lda = np.array(X.dot(W_matrix)) 次の作業は、プロットにクラスラベルを組み込むために、すべてのクラスのメンバをエンコードすることです。 これは、matplotlibがカテゴリ変数を直接扱えないために行われます。最後に、各クラスに異なる色を使用して、2つのLDAコンポーネントの関数としてデータをプロットします: plt.xlabel(‘LDA1’)plt.ylabel(‘LDA2′)plt.scatter(X_lda,X_lda,c=y,cmap=’rainbow’,alpha=0.7,edgecolors=’b’)<matplotlib.collections.PathCollection at 0x7fd08a20e908> How to implement LDA using scikit-learn?LDA for implementing using scikit-learn では同じワインデータセットで作業をしてみましょう。 UCI機械学習リポジトリから入手することも可能です。 scikit-learnのライブラリで用意されているLinearDiscriminant Analysisという定義済みのクラスを使って、毎回ゼロから実装するのではなく、LDAを実装します。from sklearn.discriminant_analysis import LinearDiscriminantAnalysislda_model = LinearDiscriminantAnalysis()X_lda = lda_model.fit_transform(X, y) それぞれの要素に応じた分散を取得するには次のプロパティにアクセスします: lda.explained_variance_ratio_array()again, we will plot the two LDA components just like we did before:plt.xlabel(‘LDA1’)plt.ylabel(‘LDA2′)plt.scatter(X_lda,X_lda, c=y,cmap=’rainbow’, alpha=0.7,edgecolors=’b’)<matplotlib.collections.PathCollection at 0x7fd089f60358>Linear Discriminant Analysis vs PCAB以下は、LDAとPCAの違いです:PCAはクラスラベルを無視し、与えられたデータの分散を最大化する主成分を見つけることに焦点を当てます。 従って、教師なしアルゴリズムである。 一方、LDAは、異なるクラス間の分離を最大化する軸を表す線形識別関数を求めることを目的とした教師ありアルゴリズムである。 しかし、サンプルサイズが比較的小さい場合には、PCAの方が良い性能を発揮します。 次元削減の場合、LDAとPCAの両方が使用されます。 PCAクラスのインスタンスを作成し、フィットさせてみましょう:from sklearn.decomposition import PCApca_class = PCA(n_components=2)X_pca = pca.fit_transform(X, y)より理解を深めるために、値をパーセントで表示するには、explounded_variance_ratio_プロパティにアクセスします:pca.LDAはPCAクラス、PCAはLDAと同じように、PCAクラスのインスタンスを作成し、フィットさせてみましょう。explained_variance_ratio_array()Clearly, PCAは、最も多くの情報を保持できる成分を選択し、クラス間の分離を最大化する成分は無視します。plt.xlabel(‘PCA1’)plt.ylabel(‘PCA2′)plt.scatter( X_pca, X_pca, c=y, cmap=’rainbow’, alpha=0.X_pca, X_pca, c=y, cmap=’rainbow’, alpha=0.X, PCA2′)7, edgecolors=’bさて、LDA成分を特徴量とした分類モデルを作成するために、データをトレーニングデータセットとテストデータセットに分割します:X_train, X_test, y_train, y_test = train_test_split(X_lda, y, random_state=1) 次に行うことは決定木を作成することです。 次に、各サンプルテストのカテゴリを予測し、LDAモデルの性能を評価するための混同行列を作成します:data = DecisionTreeClassifier()data.fit(X_train, y_train)y_pred = data.predict(X_test)confusion_matrix(y_test, y_pred)array(, , ])つまり、決定木分類器はテストデータセットのすべてを正しく分類したことがわかります。LDAの拡張は?LDAは、特に分類技術において非常にシンプルで有効な手法であると考えられています。 二次判別分析(QDA) – 入力変数が複数ある場合、各クラスは独自の分散と共分散の推定値を使用します。柔軟判別分析(FDA) – この手法は、入力の非線形結合をスプラインとして使用する場合に実行されます。LDAの実際のアプリケーションを以下に示します。顔認識 – LDAは顔認識において、実際の分類の前に属性の数をより管理しやすい数に減らすために使用されます。 生成される次元は、テンプレートを形成するピクセルの線形結合である。 これらはフィッシャーの顔と呼ばれています。医療 – LDAを使用して、患者の病気を軽度、中等度、重度に分類することができます。 この分類は、患者の様々なパラメータと医学的な軌跡に基づいて行われる。 顧客の識別 – 簡単な質問と回答の調査を実行することによって、顧客の特徴を得ることができます。 LDAは、ショッピングモールで特定の商品を購入する可能性が最も高い顧客グループの特性を記述する識別と選択を支援します。 まとめこの記事で取り上げたトピックを見てみましょう。 次元削減とLDAの必要性 LDAモデルの動作 LDAにおける表現、学習、予測、データの準備 LDAモデルの実装 scikit-learnを用いたLDAの実装 LDA vs PCA LDAの拡張と応用 Pythonの線形判別分析は、機械学習における分類の非常にシンプルでよく理解されたアプローチである。 ロジスティック回帰やPCAのような他の次元削減手法もありますが、LDAは多くの特殊な分類のケースで好まれています。 機械学習のエキスパートを目指すのであれば、線形判別分析の知識があれば、難なくそのポジションに就くことができるでしょう。 データサイエンスと機械学習のコースに登録して、この分野でより有利なキャリアの選択肢を得、認定データサイエンティストになりましょう。

コメントを残す

メールアドレスが公開されることはありません。