From e5241682c5a1a271430e406dca9de39e2b1b4d32 Mon Sep 17 00:00:00 2001 From: Translator Date: Sat, 7 Jun 2025 23:36:32 +0000 Subject: [PATCH] Translated ['src/AI/AI-Unsupervised-Learning-algorithms.md', 'src/AI/AI- --- src/AI/AI-Unsupervised-Learning-algorithms.md | 442 ++++++++++++++++++ src/AI/AI-llm-architecture/README.md | 98 ++++ 2 files changed, 540 insertions(+) create mode 100644 src/AI/AI-Unsupervised-Learning-algorithms.md create mode 100644 src/AI/AI-llm-architecture/README.md diff --git a/src/AI/AI-Unsupervised-Learning-algorithms.md b/src/AI/AI-Unsupervised-Learning-algorithms.md new file mode 100644 index 000000000..edf97c1a8 --- /dev/null +++ b/src/AI/AI-Unsupervised-Learning-algorithms.md @@ -0,0 +1,442 @@ +# 教師なし学習アルゴリズム + +{{#include ../banners/hacktricks-training.md}} + +## 教師なし学習 + + +教師なし学習は、ラベル付きの応答なしでデータに基づいてモデルを訓練する機械学習の一種です。目的は、データ内のパターン、構造、または関係を見つけることです。ラベル付きの例から学習する教師あり学習とは異なり、教師なし学習アルゴリズムはラベルのないデータで動作します。 +教師なし学習は、クラスタリング、次元削減、異常検出などのタスクにしばしば使用されます。データ内の隠れたパターンを発見したり、類似のアイテムをグループ化したり、データの本質的な特徴を保持しながらその複雑さを減少させるのに役立ちます。 + + +### K-Meansクラスタリング + +K-Meansは、各点を最も近いクラスタ平均に割り当てることによってデータをK個のクラスタに分割する重心ベースのクラスタリングアルゴリズムです。アルゴリズムは次のように機能します: +1. **初期化**: K個の初期クラスタ中心(重心)を選択します。通常はランダムに、またはk-means++のようなよりスマートな方法で行います。 +2. **割り当て**: 距離メトリック(例:ユークリッド距離)に基づいて、各データポイントを最も近い重心に割り当てます。 +3. **更新**: 各クラスタに割り当てられたすべてのデータポイントの平均を取ることによって重心を再計算します。 +4. **繰り返し**: クラスタの割り当てが安定するまで(重心が大きく移動しなくなるまで)ステップ2〜3を繰り返します。 + +> [!TIP] +> *サイバーセキュリティにおけるユースケース:* K-Meansは、ネットワークイベントをクラスタリングすることによって侵入検知に使用されます。例えば、研究者はKDD Cup 99侵入データセットにK-Meansを適用し、トラフィックを正常と攻撃のクラスタに効果的に分割できることを発見しました。実際には、セキュリティアナリストは、ログエントリやユーザー行動データをクラスタリングして、類似の活動のグループを見つけることがあります。適切に形成されたクラスタに属さないポイントは、異常を示す可能性があります(例:新しいマルウェアの亜種が独自の小さなクラスタを形成する)。K-Meansは、動作プロファイルや特徴ベクトルに基づいてバイナリをグループ化することによって、マルウェアファミリーの分類にも役立ちます。 + +#### Kの選択 +クラスタの数(K)は、アルゴリズムを実行する前に定義する必要があるハイパーパラメータです。エルボー法やシルエットスコアのような手法は、クラスタリングのパフォーマンスを評価することによってKの適切な値を決定するのに役立ちます: + +- **エルボー法**: 各ポイントからその割り当てられたクラスタ重心までの二乗距離の合計をKの関数としてプロットします。減少率が急激に変化する「エルボー」ポイントを探し、適切なクラスタ数を示します。 +- **シルエットスコア**: Kの異なる値に対してシルエットスコアを計算します。シルエットスコアが高いほど、より明確に定義されたクラスタを示します。 + +#### 仮定と制限 + +K-Meansは、**クラスタが球状で同じサイズである**と仮定していますが、これはすべてのデータセットに当てはまるわけではありません。初期の重心の配置に敏感であり、局所的な最小値に収束する可能性があります。さらに、K-Meansは、異なる密度や非球状の形状を持つデータセットや、異なるスケールの特徴には適していません。すべての特徴が距離計算に等しく寄与することを保証するために、正規化や標準化のような前処理ステップが必要になる場合があります。 + +
+例 -- ネットワークイベントのクラスタリング + +以下では、ネットワークトラフィックデータをシミュレートし、K-Meansを使用してクラスタリングします。接続時間やバイト数のような特徴を持つイベントがあると仮定します。「正常」トラフィックの3つのクラスタと、攻撃パターンを表す1つの小さなクラスタを作成します。その後、K-Meansを実行して、それらを分離できるかどうかを確認します。 +```python +import numpy as np +from sklearn.cluster import KMeans + +# Simulate synthetic network traffic data (e.g., [duration, bytes]). +# Three normal clusters and one small attack cluster. +rng = np.random.RandomState(42) +normal1 = rng.normal(loc=[50, 500], scale=[10, 100], size=(500, 2)) # Cluster 1 +normal2 = rng.normal(loc=[60, 1500], scale=[8, 200], size=(500, 2)) # Cluster 2 +normal3 = rng.normal(loc=[70, 3000], scale=[5, 300], size=(500, 2)) # Cluster 3 +attack = rng.normal(loc=[200, 800], scale=[5, 50], size=(50, 2)) # Small attack cluster + +X = np.vstack([normal1, normal2, normal3, attack]) +# Run K-Means clustering into 4 clusters (we expect it to find the 4 groups) +kmeans = KMeans(n_clusters=4, random_state=0, n_init=10) +labels = kmeans.fit_predict(X) + +# Analyze resulting clusters +clusters, counts = np.unique(labels, return_counts=True) +print(f"Cluster labels: {clusters}") +print(f"Cluster sizes: {counts}") +print("Cluster centers (duration, bytes):") +for idx, center in enumerate(kmeans.cluster_centers_): +print(f" Cluster {idx}: {center}") +``` +この例では、K-Meansは4つのクラスターを見つけるべきです。異常に高い持続時間(約200)を持つ小さな攻撃クラスターは、通常のクラスターからの距離を考慮して、理想的には独自のクラスターを形成します。結果を解釈するために、クラスターのサイズと中心を印刷します。実際のシナリオでは、少数のポイントを持つクラスターに潜在的な異常としてラベルを付けるか、そのメンバーを悪意のある活動のために調査することができます。 +
+ +### 階層的クラスタリング + +階層的クラスタリングは、ボトムアップ(凝集型)アプローチまたはトップダウン(分割型)アプローチを使用して、クラスターの階層を構築します。 + +1. **凝集型(ボトムアップ)**: 各データポイントを別々のクラスターとして開始し、最も近いクラスターを反復的にマージして、単一のクラスターが残るか、停止基準が満たされるまで続けます。 +2. **分割型(トップダウン)**: すべてのデータポイントを単一のクラスターに入れ、各データポイントが独自のクラスターになるか、停止基準が満たされるまでクラスターを反復的に分割します。 + +凝集型クラスタリングは、クラスター間の距離の定義と、どのクラスターをマージするかを決定するためのリンク基準を必要とします。一般的なリンク方法には、単一リンク(2つのクラスター間の最も近いポイントの距離)、完全リンク(最も遠いポイントの距離)、平均リンクなどがあり、距離メトリックはしばしばユークリッドです。リンクの選択は生成されるクラスターの形状に影響を与えます。クラスターの数Kを事前に指定する必要はなく、選択したレベルで樹形図を「カット」して、希望する数のクラスターを得ることができます。 + +階層的クラスタリングは、異なる粒度レベルでクラスター間の関係を示す樹形図を生成します。樹形図は、特定の数のクラスターを得るために希望するレベルでカットすることができます。 + +> [!TIP] +> *サイバーセキュリティにおけるユースケース:* 階層的クラスタリングは、イベントやエンティティをツリーに整理して関係を特定することができます。たとえば、マルウェア分析では、凝集型クラスタリングがサンプルを行動の類似性によってグループ化し、マルウェアファミリーとバリアントの階層を明らかにすることができます。ネットワークセキュリティでは、IPトラフィックフローをクラスタリングし、樹形図を使用してトラフィックのサブグループ(例:プロトコル別、次に行動別)を確認することができます。Kを事前に選択する必要がないため、攻撃カテゴリの数が不明な新しいデータを探索する際に便利です。 + +#### 仮定と制限 + +階層的クラスタリングは特定のクラスター形状を仮定せず、ネストされたクラスターをキャプチャできます。これは、グループ間の分類法や関係を発見するのに役立ちます(例:マルウェアをファミリーサブグループでグループ化)。これは決定論的であり(ランダム初期化の問題はありません)、主要な利点は樹形図であり、すべてのスケールでデータのクラスタリング構造に関する洞察を提供します。セキュリティアナリストは、意味のあるクラスターを特定するための適切なカットオフを決定できます。ただし、計算コストが高く(通常は$O(n^2)$時間またはそれ以上のナイーブな実装)、非常に大きなデータセットには実行可能ではありません。また、これは貪欲な手法であり、一度マージまたは分割が行われると元に戻すことができず、早期に間違いが発生した場合に最適でないクラスターが生じる可能性があります。外れ値も一部のリンク戦略に影響を与える可能性があります(単一リンクは、外れ値を介してクラスターがリンクする「チェイニング」効果を引き起こす可能性があります)。 + +
+例 -- イベントの凝集型クラスタリング + + +K-Meansの例からの合成データ(3つの正常なクラスター + 1つの攻撃クラスター)を再利用し、凝集型クラスタリングを適用します。次に、樹形図とクラスターラベルを取得する方法を示します。 +```python +from sklearn.cluster import AgglomerativeClustering +from scipy.cluster.hierarchy import linkage, dendrogram + +# Perform agglomerative clustering (bottom-up) on the data +agg = AgglomerativeClustering(n_clusters=None, distance_threshold=0, linkage='ward') +# distance_threshold=0 gives the full tree without cutting (we can cut manually) +agg.fit(X) + +print(f"Number of merge steps: {agg.n_clusters_ - 1}") # should equal number of points - 1 +# Create a dendrogram using SciPy for visualization (optional) +Z = linkage(X, method='ward') +# Normally, you would plot the dendrogram. Here we'll just compute cluster labels for a chosen cut: +clusters_3 = AgglomerativeClustering(n_clusters=3, linkage='ward').fit_predict(X) +print(f"Labels with 3 clusters: {np.unique(clusters_3)}") +print(f"Cluster sizes for 3 clusters: {np.bincount(clusters_3)}") +``` +
+ +### DBSCAN (ノイズを伴うアプリケーションの密度ベースの空間クラスタリング) + +DBSCANは、密度ベースのクラスタリングアルゴリズムで、密集しているポイントをグループ化し、低密度領域のポイントを外れ値としてマークします。これは、異なる密度と非球形の形状を持つデータセットに特に有用です。 + +DBSCANは、2つのパラメータを定義することによって機能します: +- **Epsilon (ε)**: 同じクラスタの一部と見なされる2つのポイント間の最大距離。 +- **MinPts**: 密な領域(コアポイント)を形成するために必要な最小ポイント数。 + +DBSCANは、コアポイント、ボーダーポイント、ノイズポイントを識別します: +- **コアポイント**: ε距離内に少なくともMinPtsの隣接ポイントを持つポイント。 +- **ボーダーポイント**: コアポイントのε距離内にあるが、MinPts未満の隣接ポイントを持つポイント。 +- **ノイズポイント**: コアポイントでもボーダーポイントでもないポイント。 + +クラスタリングは、未訪問のコアポイントを選択し、それを新しいクラスタとしてマークし、そこから密度到達可能なすべてのポイント(コアポイントとその隣接ポイントなど)を再帰的に追加することによって進行します。ボーダーポイントは近くのコアのクラスタに追加されます。すべての到達可能なポイントを拡張した後、DBSCANは別の未訪問のコアに移動して新しいクラスタを開始します。どのコアにも到達できなかったポイントはノイズとしてラベル付けされます。 + +> [!TIP] +> *サイバーセキュリティにおけるユースケース:* DBSCANはネットワークトラフィックの異常検出に役立ちます。たとえば、通常のユーザー活動は特徴空間において1つ以上の密なクラスタを形成するかもしれませんが、新しい攻撃行動は散発的なポイントとして現れ、DBSCANはそれをノイズ(外れ値)としてラベル付けします。これは、ポートスキャンやサービス拒否トラフィックをポイントのまばらな領域として検出できるネットワークフローレコードのクラスタリングに使用されてきました。別のアプリケーションはマルウェアのバリアントをグループ化することです:ほとんどのサンプルがファミリーごとにクラスタリングされる一方で、いくつかはどこにも適合しない場合、それらはゼロデイマルウェアである可能性があります。ノイズをフラグ付けする能力により、セキュリティチームはこれらの外れ値の調査に集中できます。 + +#### 仮定と制限 + +**仮定と強み:** DBSCANは球状のクラスタを仮定しません – 任意の形状のクラスタ(連鎖状または隣接するクラスタさえも)を見つけることができます。データの密度に基づいてクラスタの数を自動的に決定し、外れ値をノイズとして効果的に識別できます。これにより、不規則な形状とノイズを持つ実世界のデータに対して強力です。外れ値に対して頑健です(K-Meansとは異なり、外れ値をクラスタに強制的に入れません)。クラスタがほぼ均一な密度を持つ場合にうまく機能します。 + +**制限:** DBSCANのパフォーマンスは、適切なεとMinPtsの値を選択することに依存します。異なる密度を持つデータに対しては苦労するかもしれません – 単一のεでは、密なクラスタとまばらなクラスタの両方を収容できません。εが小さすぎると、ほとんどのポイントがノイズとしてラベル付けされます;大きすぎると、クラスタが不正にマージされる可能性があります。また、DBSCANは非常に大きなデータセットでは非効率的になる可能性があります(単純には$O(n^2)$ですが、空間インデックスが役立つことがあります)。高次元の特徴空間では、「ε内の距離」の概念があまり意味を持たなくなることがあります(次元の呪い)、DBSCANは慎重なパラメータ調整が必要になるか、直感的なクラスタを見つけられない場合があります。それにもかかわらず、HDBSCANのような拡張は、いくつかの問題(異なる密度など)に対処します。 + +
+例 -- ノイズを伴うクラスタリング + +```python +from sklearn.cluster import DBSCAN + +# Generate synthetic data: 2 normal clusters and 5 outlier points +cluster1 = rng.normal(loc=[100, 1000], scale=[5, 100], size=(100, 2)) +cluster2 = rng.normal(loc=[120, 2000], scale=[5, 100], size=(100, 2)) +outliers = rng.uniform(low=[50, 50], high=[180, 3000], size=(5, 2)) # scattered anomalies +data = np.vstack([cluster1, cluster2, outliers]) + +# Run DBSCAN with chosen eps and MinPts +eps = 15.0 # radius for neighborhood +min_pts = 5 # minimum neighbors to form a dense region +db = DBSCAN(eps=eps, min_samples=min_pts).fit(data) +labels = db.labels_ # cluster labels (-1 for noise) + +# Analyze clusters and noise +num_clusters = len(set(labels) - {-1}) +num_noise = np.sum(labels == -1) +print(f"DBSCAN found {num_clusters} clusters and {num_noise} noise points") +print("Cluster labels for first 10 points:", labels[:10]) +``` +このスニペットでは、データスケールに合わせて `eps` と `min_samples` を調整しました(特徴単位で15.0、クラスタを形成するために5ポイントが必要)。DBSCANは2つのクラスタ(通常のトラフィッククラスタ)を見つけ、5つの注入された外れ値をノイズとしてフラグ付けする必要があります。これを確認するために、クラスタ数とノイズポイントの数を出力します。実際の設定では、εを反復処理し(εを選択するためにk距離グラフヒューリスティックを使用)、MinPts(一般的にはデータの次元数+1に設定されることが多い)を使用して安定したクラスタリング結果を見つけることがあります。ノイズを明示的にラベル付けする能力は、さらなる分析のために潜在的な攻撃データを分離するのに役立ちます。 + +
+ +### 主成分分析 (PCA) + +PCAは、データの最大分散を捉える新しい直交軸(主成分)を見つけるための**次元削減**手法です。簡単に言えば、PCAはデータを新しい座標系に回転させて投影し、最初の主成分(PC1)が可能な限り最大の分散を説明し、2番目のPC(PC2)がPC1に直交する最大の分散を説明し、以下同様です。数学的には、PCAはデータの共分散行列の固有ベクトルを計算します。これらの固有ベクトルは主成分の方向であり、対応する固有値は各固有ベクトルによって説明される分散の量を示します。PCAは、特徴抽出、視覚化、ノイズ削減によく使用されます。 + +この手法は、データセットの次元に**重要な線形依存関係や相関関係**が含まれている場合に有用です。 + +PCAは、データの主成分を特定することによって機能します。主成分は最大分散の方向です。PCAに関与するステップは次のとおりです: +1. **標準化**:データの平均を引き、単位分散にスケーリングしてデータを中心にします。 +2. **共分散行列**:標準化されたデータの共分散行列を計算し、特徴間の関係を理解します。 +3. **固有値分解**:共分散行列に対して固有値分解を行い、固有値と固有ベクトルを取得します。 +4. **主成分の選択**:固有値を降順に並べ、最大の固有値に対応する上位K個の固有ベクトルを選択します。これらの固有ベクトルが新しい特徴空間を形成します。 +5. **データの変換**:選択した主成分を使用して、元のデータを新しい特徴空間に投影します。 +PCAは、データの視覚化、ノイズ削減、他の機械学習アルゴリズムの前処理ステップとして広く使用されています。データの次元を削減しながら、その本質的な構造を保持するのに役立ちます。 + +#### 固有値と固有ベクトル + +固有値は、対応する固有ベクトルによって捉えられる分散の量を示すスカラーです。固有ベクトルは、データが最も変動する特徴空間の方向を表します。 + +Aが正方行列で、vがゼロでないベクトルであると仮定します: `A * v = λ * v` +ここで: +- Aは [ [1, 2], [2, 1]] のような正方行列(例:共分散行列) +- vは固有ベクトル(例:[1, 1]) + +すると、`A * v = [ [1, 2], [2, 1]] * [1, 1] = [3, 3]` となり、これは固有値λが固有ベクトルvで掛けられたもので、固有値λ = 3になります。 + +#### PCAにおける固有値と固有ベクトル + +これを例で説明しましょう。100x100ピクセルの顔のグレースケール画像がたくさんあるデータセットがあると仮定します。各ピクセルは特徴と見なすことができるため、画像ごとに10,000の特徴(または画像ごとの10,000成分のベクトル)があります。このデータセットの次元をPCAを使用して削減したい場合、次の手順に従います: + +1. **標準化**:データセットから各特徴(ピクセル)の平均を引いてデータを中心にします。 +2. **共分散行列**:標準化されたデータの共分散行列を計算し、特徴(ピクセル)がどのように一緒に変動するかを捉えます。 +- 2つの変数(この場合はピクセル)間の共分散は、どの程度一緒に変化するかを示します。ここでのアイデアは、どのピクセルが線形関係で一緒に増加または減少する傾向があるかを見つけることです。 +- 例えば、ピクセル1とピクセル2が一緒に増加する傾向がある場合、彼らの間の共分散は正になります。 +- 共分散行列は10,000x10,000の行列になり、各エントリは2つのピクセル間の共分散を表します。 +3. **固有値方程式を解く**:解くべき固有値方程式は `C * v = λ * v` で、ここでCは共分散行列、vは固有ベクトル、λは固有値です。次のような方法で解くことができます: +- **固有値分解**:共分散行列に対して固有値分解を行い、固有値と固有ベクトルを取得します。 +- **特異値分解 (SVD)**:代わりに、SVDを使用してデータ行列を特異値とベクトルに分解し、主成分を得ることもできます。 +4. **主成分の選択**:固有値を降順に並べ、最大の固有値に対応する上位K個の固有ベクトルを選択します。これらの固有ベクトルは、データの最大分散の方向を表します。 + +> [!TIP] +> *サイバーセキュリティにおけるユースケース:* セキュリティにおけるPCAの一般的な使用法は、異常検出のための特徴削減です。例えば、40以上のネットワークメトリック(NSL-KDDの特徴など)を持つ侵入検知システムは、PCAを使用して数個の成分に削減し、視覚化やクラスタリングアルゴリズムへの入力のためにデータを要約できます。アナリストは、最初の2つの主成分の空間でネットワークトラフィックをプロットして、攻撃が通常のトラフィックから分離されるかどうかを確認することがあります。PCAは、冗長な特徴(相関がある場合の送信バイトと受信バイトなど)を排除するのにも役立ち、検出アルゴリズムをより堅牢で迅速にします。 + +#### 仮定と制限 + +PCAは、**分散の主軸が意味のあるものであると仮定します** – これは線形手法であるため、データの線形相関を捉えます。これは教師なしであり、特徴の共分散のみを使用します。PCAの利点には、ノイズ削減(小さな分散の成分はしばしばノイズに対応する)や特徴の非相関化が含まれます。中程度の高次元に対して計算効率が良く、他のアルゴリズムの前処理ステップとしてしばしば有用です(次元の呪いを軽減するため)。1つの制限は、PCAが線形関係に制限されていることです – 複雑な非線形構造を捉えることはできません(オートエンコーダやt-SNEができるかもしれません)。また、PCAの成分は元の特徴の観点から解釈が難しい場合があります(それらは元の特徴の組み合わせです)。サイバーセキュリティでは、注意が必要です:低分散の特徴に微妙な変化を引き起こす攻撃は、上位PCに現れないかもしれません(PCAは分散を優先するため、「興味深さ」を必ずしも優先するわけではありません)。 + +
+例 -- ネットワークデータの次元削減 + + +ネットワーク接続ログに複数の特徴(例:持続時間、バイト、カウント)があると仮定します。相関のある特徴を持つ合成の4次元データセットを生成し、PCAを使用して視覚化やさらなる分析のために2次元に削減します。 +```python +from sklearn.decomposition import PCA + +# Create synthetic 4D data (3 clusters similar to before, but add correlated features) +# Base features: duration, bytes (as before) +base_data = np.vstack([normal1, normal2, normal3]) # 1500 points from earlier normal clusters +# Add two more features correlated with existing ones, e.g. packets = bytes/50 + noise, errors = duration/10 + noise +packets = base_data[:, 1] / 50 + rng.normal(scale=0.5, size=len(base_data)) +errors = base_data[:, 0] / 10 + rng.normal(scale=0.5, size=len(base_data)) +data_4d = np.column_stack([base_data[:, 0], base_data[:, 1], packets, errors]) + +# Apply PCA to reduce 4D data to 2D +pca = PCA(n_components=2) +data_2d = pca.fit_transform(data_4d) +print("Explained variance ratio of 2 components:", pca.explained_variance_ratio_) +print("Original shape:", data_4d.shape, "Reduced shape:", data_2d.shape) +# We can examine a few transformed points +print("First 5 data points in PCA space:\n", data_2d[:5]) +``` +ここでは、以前の通常のトラフィッククラスタを取り、各データポイントにバイトと期間に相関する2つの追加機能(パケットとエラー)を拡張しました。次に、PCAを使用して4つの特徴を2つの主成分に圧縮します。説明された分散比を印刷し、たとえば、2つの成分によって95%以上の分散が捕捉されていることを示すかもしれません(つまり、情報損失が少ないことを意味します)。出力は、データの形状が(1500, 4)から(1500, 2)に減少することも示しています。PCA空間の最初のいくつかのポイントが例として示されています。実際には、data_2dをプロットして、クラスタが区別可能かどうかを視覚的に確認できます。異常が存在する場合、PCA空間の主要なクラスタから離れた点として見ることができるかもしれません。したがって、PCAは複雑なデータを人間の解釈や他のアルゴリズムへの入力として管理可能な形に抽出するのに役立ちます。 + +
+ +### ガウス混合モデル (GMM) + +ガウス混合モデルは、データが**未知のパラメータを持ついくつかのガウス(正規)分布の混合から生成される**と仮定します。本質的には、これは確率的クラスタリングモデルです:各ポイントをK個のガウス成分の1つに柔軟に割り当てようとします。各ガウス成分kには、平均ベクトル(μ_k)、共分散行列(Σ_k)、およびそのクラスタの普及度を表す混合重み(π_k)があります。K-Meansが「ハード」割り当てを行うのに対し、GMMは各ポイントが各クラスタに属する確率を与えます。 + +GMMのフィッティングは通常、期待値最大化(EM)アルゴリズムを介して行われます: + +- **初期化**:平均、共分散、および混合係数の初期推定値から始める(またはK-Meansの結果を出発点として使用する)。 + +- **Eステップ(期待値)**:現在のパラメータに基づいて、各ポイントに対する各クラスタの責任を計算します:本質的には`r_nk = P(z_k | x_n)`であり、ここでz_kはポイントx_nのクラスタメンバーシップを示す潜在変数です。これはベイズの定理を使用して行われ、現在のパラメータに基づいて各ポイントが各クラスタに属する後方確率を計算します。責任は次のように計算されます: +```math +r_{nk} = \frac{\pi_k \mathcal{N}(x_n | \mu_k, \Sigma_k)}{\sum_{j=1}^{K} \pi_j \mathcal{N}(x_n | \mu_j, \Sigma_j)} +``` +ここで: +- \( \pi_k \) はクラスタkの混合係数(クラスタkの事前確率)です。 +- \( \mathcal{N}(x_n | \mu_k, \Sigma_k) \) は、平均\( \mu_k \)と共分散\( \Sigma_k \)が与えられたポイント\( x_n \)のガウス確率密度関数です。 + +- **Mステップ(最大化)**:Eステップで計算された責任を使用してパラメータを更新します: +- 各平均μ_kをポイントの重み付き平均として更新します。重みは責任です。 +- 各共分散Σ_kをクラスタkに割り当てられたポイントの重み付き共分散として更新します。 +- 混合係数π_kをクラスタkの平均責任として更新します。 + +- **EおよびMステップを収束するまで繰り返す**(パラメータが安定するか、尤度の改善が閾値を下回るまで)。 + +結果は、全体のデータ分布を集団的にモデル化するガウス分布のセットです。フィッティングされたGMMを使用して、各ポイントを最も高い確率のガウスに割り当てることでクラスタリングするか、不確実性のために確率を保持することができます。また、新しいポイントの尤度を評価して、モデルに適合するかどうかを確認することもできます(異常検出に役立ちます)。 + +> [!TIP] +> *サイバーセキュリティにおけるユースケース:* GMMは、正常なデータの分布をモデル化することによって異常検出に使用できます:学習した混合の下で非常に低い確率のポイントは異常としてフラグ付けされます。たとえば、正当なネットワークトラフィックの特徴に基づいてGMMをトレーニングすることができます。学習したクラスタに似ていない攻撃接続は低い尤度を持つでしょう。GMMは、クラスタが異なる形状を持つ可能性がある活動をクラスタリングするためにも使用されます。たとえば、行動プロファイルによってユーザーをグループ化する場合、各プロファイルの特徴はガウス的である可能性がありますが、それぞれ独自の分散構造を持っています。別のシナリオ:フィッシング検出では、正当なメールの特徴が1つのガウスクラスタを形成し、既知のフィッシングが別のものを形成し、新しいフィッシングキャンペーンは、既存の混合に対して別のガウスまたは低い尤度のポイントとして現れる可能性があります。 + +#### 仮定と制限 + +GMMは、共分散を取り入れたK-Meansの一般化であり、クラスタは楕円体(球状だけでなく)になることができます。共分散が完全であれば、異なるサイズと形状のクラスタを処理します。クラスタ境界があいまいな場合、ソフトクラスタリングは利点です。たとえば、サイバーセキュリティでは、イベントが複数の攻撃タイプの特性を持つ可能性があります。GMMは確率でその不確実性を反映できます。GMMはまた、データの確率密度推定を提供し、外れ値(すべての混合成分の下で低い尤度を持つポイント)を検出するのに役立ちます。 + +一方で、GMMは成分の数Kを指定する必要があります(ただし、BIC/AICのような基準を使用して選択できます)。EMは時々遅く収束したり、局所最適に収束したりすることがあるため、初期化が重要です(通常、EMを複数回実行します)。データが実際にガウスの混合に従わない場合、モデルは適合が悪い可能性があります。また、1つのガウスが外れ値をカバーするために縮小するリスクもあります(ただし、正則化や最小共分散境界を使用することで軽減できます)。 + +
+例 -- ソフトクラスタリングと異常スコア + +```python +from sklearn.mixture import GaussianMixture + +# Fit a GMM with 3 components to the normal traffic data +gmm = GaussianMixture(n_components=3, covariance_type='full', random_state=0) +gmm.fit(base_data) # using the 1500 normal data points from PCA example + +# Print the learned Gaussian parameters +print("GMM means:\n", gmm.means_) +print("GMM covariance matrices:\n", gmm.covariances_) + +# Take a sample attack-like point and evaluate it +sample_attack = np.array([[200, 800]]) # an outlier similar to earlier attack cluster +probs = gmm.predict_proba(sample_attack) +log_likelihood = gmm.score_samples(sample_attack) +print("Cluster membership probabilities for sample attack:", probs) +print("Log-likelihood of sample attack under GMM:", log_likelihood) +``` +このコードでは、正常なトラフィックに対して3つのガウス分布を持つGMMをトレーニングします(正当なトラフィックの3つのプロファイルを知っていると仮定します)。印刷された平均と共分散はこれらのクラスタを説明します(例えば、1つの平均は[50,500]の周辺で、1つのクラスタの中心に対応するかもしれません)。次に、疑わしい接続[duration=200, bytes=800]をテストします。predict_probaは、このポイントが3つのクラスタのそれぞれに属する確率を示します – [200,800]が正常なクラスタから遠く離れているため、これらの確率は非常に低いか、非常に偏っていると予想されます。全体のscore_samples(対数尤度)が印刷されます;非常に低い値は、そのポイントがモデルにうまく適合していないことを示し、異常としてフラグを立てます。実際には、対数尤度(または最大確率)にしきい値を設定して、ポイントが悪意のあるものと見なされるには十分にありそうもないかどうかを判断できます。したがって、GMMは異常検出を行うための原則的な方法を提供し、不確実性を認めるソフトクラスタも生成します。 + +### Isolation Forest + +**Isolation Forest**は、ポイントをランダムに孤立させるというアイデアに基づいたアンサンブル異常検出アルゴリズムです。原則は、異常は少なく異なるため、正常なポイントよりも孤立させやすいということです。Isolation Forestは、多くのバイナリ孤立木(ランダム決定木)を構築し、データをランダムに分割します。木の各ノードでは、ランダムな特徴が選択され、その特徴の最小値と最大値の間でランダムな分割値が選ばれます。この分割はデータを2つの枝に分けます。木は、各ポイントが自分の葉に孤立するか、最大の木の高さに達するまで成長します。 + +異常検出は、これらのランダムな木の各ポイントのパスの長さを観察することによって行われます – ポイントを孤立させるために必要な分割の数です。直感的に、異常(外れ値)は、ランダムな分割が外れ値(まばらな領域にある)を分離する可能性が高いため、より早く孤立する傾向があります。Isolation Forestは、すべての木の平均パスの長さから異常スコアを計算します:平均パスが短いほど → より異常です。スコアは通常[0,1]に正規化され、1は非常に高い異常の可能性を意味します。 + +> [!TIP] +> *サイバーセキュリティにおけるユースケース:* Isolation Forestは、侵入検知や詐欺検知に成功裏に使用されています。例えば、主に正常な動作を含むネットワークトラフィックログでIsolation Forestをトレーニングします;フォレストは、奇妙なトラフィック(聞いたことのないポートを使用するIPや異常なパケットサイズパターンなど)に対して短いパスを生成し、検査のためにフラグを立てます。ラベル付きの攻撃を必要としないため、未知の攻撃タイプを検出するのに適しています。また、ユーザーログインデータに展開してアカウント乗っ取りを検出することもできます(異常なログイン時間や場所が迅速に孤立します)。あるユースケースでは、Isolation Forestがシステムメトリクスを監視し、メトリクスの組み合わせ(CPU、ネットワーク、ファイル変更)が歴史的パターンと非常に異なる場合(短い孤立パス)にアラートを生成することで、企業を保護するかもしれません。 + +#### Assumptions and Limitations + +**利点**: Isolation Forestは分布の仮定を必要とせず、孤立を直接ターゲットにします。高次元データや大規模データセットに対して効率的です(フォレストを構築するための線形複雑度$O(n\log n)$)ので、各木は特徴のサブセットと分割のみでポイントを孤立させます。数値特徴をうまく処理する傾向があり、$O(n^2)$の可能性がある距離ベースの方法よりも速くなることがあります。また、自動的に異常スコアを提供するため、アラートのしきい値を設定することができます(または、期待される異常の割合に基づいてカットオフを自動的に決定するために汚染パラメータを使用できます)。 + +**制限**: ランダムな性質のため、結果は実行間でわずかに異なる場合があります(ただし、十分な数の木があればこれは小さいです)。データに多くの無関係な特徴がある場合や、異常がどの特徴でも強く区別されない場合、孤立が効果的でない可能性があります(ランダムな分割が偶然に正常なポイントを孤立させる可能性があります – ただし、多くの木を平均化することでこれを軽減します)。また、Isolation Forestは一般的に異常が少数派であると仮定します(これは通常、サイバーセキュリティのシナリオでは真実です)。 + +
+例 -- ネットワークログにおける外れ値の検出 + + +以前のテストデータセット(正常なポイントといくつかの攻撃ポイントを含む)を使用し、Isolation Forestを実行して攻撃を分離できるかどうかを確認します。デモンストレーションのために、データの約15%が異常であると予想すると仮定します。 +```python +from sklearn.ensemble import IsolationForest + +# Combine normal and attack test data from autoencoder example +X_test_if = test_data # (120 x 2 array with 100 normal and 20 attack points) +# Train Isolation Forest (unsupervised) on the test set itself for demo (in practice train on known normal) +iso_forest = IsolationForest(n_estimators=100, contamination=0.15, random_state=0) +iso_forest.fit(X_test_if) +# Predict anomalies (-1 for anomaly, 1 for normal) +preds = iso_forest.predict(X_test_if) +anomaly_scores = iso_forest.decision_function(X_test_if) # the higher, the more normal +print("Isolation Forest predicted labels (first 20):", preds[:20]) +print("Number of anomalies detected:", np.sum(preds == -1)) +print("Example anomaly scores (lower means more anomalous):", anomaly_scores[:5]) +``` +このコードでは、`IsolationForest`を100本の木でインスタンス化し、`contamination=0.15`を設定します(これは約15%の異常を期待することを意味します; モデルはスコアの閾値を設定し、約15%のポイントがフラグ付けされるようにします)。`X_test_if`にフィットさせますが、これは通常のポイントと攻撃ポイントの混合を含んでいます(注意: 通常はトレーニングデータにフィットさせ、新しいデータに対して予測を行いますが、ここでは結果を直接観察するために同じセットでフィットと予測を行います)。 + +出力は最初の20ポイントの予測ラベルを示しています(-1は異常を示します)。また、検出された異常の合計数といくつかの異常スコアの例を印刷します。120ポイントのうち約18ポイントが-1とラベル付けされることを期待します(汚染が15%だったため)。もし私たちの20の攻撃サンプルが本当に最も外れたものであれば、そのほとんどはこれらの-1予測に現れるはずです。異常スコア(Isolation Forestの決定関数)は、通常のポイントでは高く、異常では低く(より負の値)なります – 分離を確認するためにいくつかの値を印刷します。実際には、データをスコアでソートしてトップの外れ値を確認し、調査することができます。したがって、Isolation Forestは、大規模なラベルのないセキュリティデータを効率的にふるい分け、人間の分析やさらなる自動的な精査のために最も不規則なインスタンスを選び出す方法を提供します。 + +### t-SNE (t-分布確率的近傍埋め込み) + +**t-SNE**は、高次元データを2次元または3次元で視覚化するために特別に設計された非線形次元削減技術です。データポイント間の類似性を結合確率分布に変換し、低次元投影における局所的な近傍の構造を保持しようとします。簡単に言えば、t-SNEは(例えば)2Dにポイントを配置し、類似したポイント(元の空間で)を近くに配置し、異なるポイントを高い確率で遠くに配置します。 + +アルゴリズムには2つの主要なステージがあります: + +1. **高次元空間でのペアワイズ親和性の計算:** 各ポイントのペアについて、t-SNEはそのペアを近隣として選ぶ確率を計算します(これは各ポイントにガウス分布を中心にして距離を測定することで行われます – パープレキシティパラメータは考慮される近隣の実効数に影響を与えます)。 +2. **低次元(例えば2D)空間でのペアワイズ親和性の計算:** 最初に、ポイントは2Dにランダムに配置されます。t-SNEはこのマップの距離に対して類似の確率を定義します(より遠くのポイントに自由を与えるために、ガウスよりも重い尾を持つスチューデントt分布カーネルを使用します)。 +3. **勾配降下法:** t-SNEは次に、2Dのポイントを反復的に移動させ、高次元の親和性分布と低次元のそれとの間のクルバック–ライブラー(KL)ダイバージェンスを最小化します。これにより、2Dの配置が高次元の構造をできるだけ反映するようになります – 元の空間で近かったポイントは互いに引き寄せ合い、遠くにあるものは反発し、バランスが見つかるまで続きます。 + +その結果、データ内のクラスターが明らかになる視覚的に意味のある散布図が得られます。 + +> [!TIP] +> *サイバーセキュリティにおけるユースケース:* t-SNEはしばしば**人間の分析のために高次元のセキュリティデータを視覚化する**ために使用されます。例えば、セキュリティオペレーションセンターでは、アナリストがポート番号、頻度、バイト数などの数十の特徴を持つイベントデータセットを取り、t-SNEを使用して2Dプロットを生成することができます。このプロットでは、攻撃が独自のクラスターを形成したり、通常のデータから分離されたりすることがあり、識別が容易になります。マルウェアファミリーのグルーピングや、異なる攻撃タイプが明確にクラスター化されるネットワーク侵入データに適用され、さらなる調査を導くことができます。基本的に、t-SNEはサイバーデータの構造を視覚化する方法を提供します。 + +#### 仮定と制限 + +t-SNEはパターンの視覚的発見に優れています。クラスター、サブクラスター、他の線形手法(PCAなど)では見えない外れ値を明らかにすることができます。マルウェアの行動プロファイルやネットワークトラフィックパターンなどの複雑なデータを視覚化するためにサイバーセキュリティ研究で使用されてきました。局所的な構造を保持するため、自然なグルーピングを示すのに適しています。 + +しかし、t-SNEは計算負荷が重く(おおよそ$O(n^2)$)、非常に大きなデータセットではサンプリングが必要になる場合があります。また、出力に影響を与えるハイパーパラメータ(パープレキシティ、学習率、反復回数)があります – 例えば、異なるパープレキシティ値は異なるスケールでクラスターを明らかにするかもしれません。t-SNEプロットは時折誤解されることがあります – マップ内の距離はグローバルに直接的な意味を持たず(局所的な近傍に焦点を当てているため、時にはクラスターが人工的に分離されて見えることがあります)。また、t-SNEは主に視覚化のためのものであり、新しいデータポイントを再計算なしに投影するための簡単な方法を提供せず、予測モデリングの前処理として使用することは意図されていません(UMAPはこれらの問題のいくつかをより速い速度で解決する代替手段です)。 + +
+例 -- ネットワーク接続の視覚化 + + +t-SNEを使用してマルチフィーチャーデータセットを2Dに削減します。例として、以前の4Dデータ(通常のトラフィックの3つの自然なクラスターがあったもの)を取り、いくつかの異常ポイントを追加します。その後、t-SNEを実行し、(概念的に)結果を視覚化します。 +```python +# 1 ───────────────────────────────────────────────────────────────────── +# Create synthetic 4-D dataset +# • Three clusters of “normal” traffic (duration, bytes) +# • Two correlated features: packets & errors +# • Five outlier points to simulate suspicious traffic +# ────────────────────────────────────────────────────────────────────── +import numpy as np +import matplotlib.pyplot as plt +from sklearn.manifold import TSNE +from sklearn.preprocessing import StandardScaler + +rng = np.random.RandomState(42) + +# Base (duration, bytes) clusters +normal1 = rng.normal(loc=[50, 500], scale=[10, 100], size=(500, 2)) +normal2 = rng.normal(loc=[60, 1500], scale=[8, 200], size=(500, 2)) +normal3 = rng.normal(loc=[70, 3000], scale=[5, 300], size=(500, 2)) + +base_data = np.vstack([normal1, normal2, normal3]) # (1500, 2) + +# Correlated features +packets = base_data[:, 1] / 50 + rng.normal(scale=0.5, size=len(base_data)) +errors = base_data[:, 0] / 10 + rng.normal(scale=0.5, size=len(base_data)) + +data_4d = np.column_stack([base_data, packets, errors]) # (1500, 4) + +# Outlier / attack points +outliers_4d = np.column_stack([ +rng.normal(250, 1, size=5), # extreme duration +rng.normal(1000, 1, size=5), # moderate bytes +rng.normal(5, 1, size=5), # very low packets +rng.normal(25, 1, size=5) # high errors +]) + +data_viz = np.vstack([data_4d, outliers_4d]) # (1505, 4) + +# 2 ───────────────────────────────────────────────────────────────────── +# Standardize features (recommended for t-SNE) +# ────────────────────────────────────────────────────────────────────── +scaler = StandardScaler() +data_scaled = scaler.fit_transform(data_viz) + +# 3 ───────────────────────────────────────────────────────────────────── +# Run t-SNE to project 4-D → 2-D +# ────────────────────────────────────────────────────────────────────── +tsne = TSNE( +n_components=2, +perplexity=30, +learning_rate='auto', +init='pca', +random_state=0 +) +data_2d = tsne.fit_transform(data_scaled) +print("t-SNE output shape:", data_2d.shape) # (1505, 2) + +# 4 ───────────────────────────────────────────────────────────────────── +# Visualize: normal traffic vs. outliers +# ────────────────────────────────────────────────────────────────────── +plt.figure(figsize=(8, 6)) +plt.scatter( +data_2d[:-5, 0], data_2d[:-5, 1], +label="Normal traffic", +alpha=0.6, +s=10 +) +plt.scatter( +data_2d[-5:, 0], data_2d[-5:, 1], +label="Outliers / attacks", +alpha=0.9, +s=40, +marker="X", +edgecolor='k' +) + +plt.title("t-SNE Projection of Synthetic Network Traffic") +plt.xlabel("t-SNE component 1") +plt.ylabel("t-SNE component 2") +plt.legend() +plt.tight_layout() +plt.show() +``` +ここでは、以前の4Dノーマルデータセットと少数の極端な外れ値を組み合わせました(外れ値は1つの特徴(「duration」)が非常に高く設定されており、奇妙なパターンをシミュレートしています)。通常のパープレキシティ30でt-SNEを実行します。出力データdata_2dの形状は(1505, 2)です。このテキストでは実際にプロットはしませんが、もし行った場合、3つのノーマルクラスタに対応する3つの密集したクラスタと、5つの外れ値がそれらのクラスタから遠く離れた孤立した点として現れることが予想されます。インタラクティブなワークフローでは、ポイントをラベル(ノーマルまたはどのクラスタ、対異常)で色分けしてこの構造を確認できます。ラベルがなくても、アナリストは2Dプロット上の空白のスペースに座っている5つのポイントに気づき、それらをフラグ付けするかもしれません。これは、t-SNEがサイバーセキュリティデータにおける視覚的異常検出とクラスタ検査に強力な支援を提供し、上記の自動化アルゴリズムを補完する方法を示しています。 + +
+ + +{{#include ../banners/hacktricks-training.md}} diff --git a/src/AI/AI-llm-architecture/README.md b/src/AI/AI-llm-architecture/README.md new file mode 100644 index 000000000..87c8123ad --- /dev/null +++ b/src/AI/AI-llm-architecture/README.md @@ -0,0 +1,98 @@ +# LLMトレーニング - データ準備 + +**これは非常に推奨される本** [**https://www.manning.com/books/build-a-large-language-model-from-scratch**](https://www.manning.com/books/build-a-large-language-model-from-scratch) **からの私のノートで、いくつかの追加情報が含まれています。** + +## 基本情報 + +まず、知っておくべき基本概念についてこの投稿を読むべきです: + +{{#ref}} +0.-basic-llm-concepts.md +{{#endref}} + +## 1. トークン化 + +> [!TIP] +> この初期段階の目標は非常にシンプルです:**入力を意味のある方法でトークン(ID)に分割すること**。 + +{{#ref}} +1.-tokenizing.md +{{#endref}} + +## 2. データサンプリング + +> [!TIP] +> この第二段階の目標は非常にシンプルです:**入力データをサンプリングし、通常は特定の長さの文にデータセットを分け、期待される応答も生成することでトレーニング段階の準備をすること**。 + +{{#ref}} +2.-data-sampling.md +{{#endref}} + +## 3. トークン埋め込み + +> [!TIP] +> この第三段階の目標は非常にシンプルです:**語彙内の各トークンにモデルをトレーニングするために必要な次元のベクトルを割り当てること**。語彙内の各単語はX次元の空間内の点になります。\ +> 最初は、各単語の空間内の位置は「ランダムに」初期化され、これらの位置はトレーニング中に改善されるトレーニング可能なパラメータです。 +> +> さらに、トークン埋め込み中に**別の埋め込み層が作成され**、これは(この場合)**トレーニング文内の単語の絶対位置を表します**。このように、文内の異なる位置にある単語は異なる表現(意味)を持ちます。 + +{{#ref}} +3.-token-embeddings.md +{{#endref}} + +## 4. アテンションメカニズム + +> [!TIP] +> この第四段階の目標は非常にシンプルです:**いくつかのアテンションメカニズムを適用すること**。これらは、**語彙内の単語と現在トレーニング中の文内の隣接単語との関係を捉えるための多くの**繰り返し層**になります。\ +> これには多くの層が使用されるため、多くのトレーニング可能なパラメータがこの情報を捉えることになります。 + +{{#ref}} +4.-attention-mechanisms.md +{{#endref}} + +## 5. LLMアーキテクチャ + +> [!TIP] +> この第五段階の目標は非常にシンプルです:**完全なLLMのアーキテクチャを開発すること**。すべてをまとめ、すべての層を適用し、テキストを生成したり、テキストをIDに変換したり、その逆を行うためのすべての関数を作成します。 +> +> このアーキテクチャは、トレーニング後のテキストのトレーニングと予測の両方に使用されます。 + +{{#ref}} +5.-llm-architecture.md +{{#endref}} + +## 6. 事前トレーニングとモデルの読み込み + +> [!TIP] +> この第六段階の目標は非常にシンプルです:**ゼロからモデルをトレーニングすること**。これには、定義された損失関数とオプティマイザを使用して、モデルのすべてのパラメータをトレーニングするためにデータセットをループする前のLLMアーキテクチャが使用されます。 + +{{#ref}} +6.-pre-training-and-loading-models.md +{{#endref}} + +## 7.0. LoRAによるファインチューニングの改善 + +> [!TIP] +> **LoRAの使用は、すでにトレーニングされたモデルをファインチューニングするために必要な計算を大幅に削減します**。 + +{{#ref}} +7.0.-lora-improvements-in-fine-tuning.md +{{#endref}} + +## 7.1. 分類のためのファインチューニング + +> [!TIP] +> このセクションの目標は、すでに事前トレーニングされたモデルをファインチューニングする方法を示すことです。新しいテキストを生成するのではなく、LLMは**与えられたテキストが各カテゴリに分類される確率を選択します**(例えば、テキストがスパムかどうか)。 + +{{#ref}} +7.1.-fine-tuning-for-classification.md +{{#endref}} + +## 7.2. 指示に従うためのファインチューニング + +> [!TIP] +> このセクションの目標は、**テキストを生成するのではなく、指示に従うためにすでに事前トレーニングされたモデルをファインチューニングする方法を示すこと**です。例えば、チャットボットとしてタスクに応答することです。 + +{{#ref}} +7.2.-fine-tuning-to-follow-instructions.md +{{#endref}}