mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
234 lines
19 KiB
Markdown
234 lines
19 KiB
Markdown
# モデルデータの準備と評価
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|
||
|
||
モデルデータの準備は、機械学習パイプラインにおいて重要なステップであり、生データを機械学習モデルのトレーニングに適した形式に変換することを含みます。このプロセスにはいくつかの重要なステップがあります:
|
||
|
||
1. **データ収集**: データベース、API、ファイルなど、さまざまなソースからデータを収集します。データは構造化されている(例:テーブル)場合もあれば、非構造化されている(例:テキスト、画像)場合もあります。
|
||
2. **データクリーニング**: 誤った、不完全な、または関連性のないデータポイントを削除または修正します。このステップでは、欠損値の処理、重複の削除、外れ値のフィルタリングが含まれる場合があります。
|
||
3. **データ変換**: モデリングに適した形式にデータを変換します。これには、正規化、スケーリング、カテゴリ変数のエンコーディング、特徴エンジニアリングのような技術を通じて新しい特徴を作成することが含まれる場合があります。
|
||
4. **データ分割**: データセットをトレーニング、検証、テストセットに分割し、モデルが未見のデータに対しても一般化できるようにします。
|
||
|
||
## データ収集
|
||
|
||
データ収集は、さまざまなソースからデータを収集することを含みます。これには以下が含まれます:
|
||
- **データベース**: リレーショナルデータベース(例:SQLデータベース)やNoSQLデータベース(例:MongoDB)からデータを抽出します。
|
||
- **API**: ウェブAPIからデータを取得し、リアルタイムまたは履歴データを提供します。
|
||
- **ファイル**: CSV、JSON、XMLなどの形式のファイルからデータを読み取ります。
|
||
- **ウェブスクレイピング**: ウェブスクレイピング技術を使用してウェブサイトからデータを収集します。
|
||
|
||
機械学習プロジェクトの目標に応じて、データは問題領域を代表するように関連するソースから抽出され、収集されます。
|
||
|
||
## データクリーニング
|
||
|
||
データクリーニングは、データセット内のエラーや不整合を特定し修正するプロセスです。このステップは、機械学習モデルのトレーニングに使用されるデータの品質を確保するために不可欠です。データクリーニングの主なタスクには以下が含まれます:
|
||
- **欠損値の処理**: 欠損データポイントを特定し対処します。一般的な戦略には以下が含まれます:
|
||
- 欠損値を含む行または列を削除する。
|
||
- 平均、中央値、または最頻値の補完などの技術を使用して欠損値を補完する。
|
||
- K近傍法(KNN)補完や回帰補完のような高度な方法を使用する。
|
||
- **重複の削除**: 重複レコードを特定し削除して、各データポイントがユニークであることを確保します。
|
||
- **外れ値のフィルタリング**: モデルのパフォーマンスを歪める可能性のある外れ値を検出し削除します。Zスコア、IQR(四分位範囲)、または視覚化(例:箱ひげ図)などの技術を使用して外れ値を特定できます。
|
||
|
||
### データクリーニングの例
|
||
```python
|
||
import pandas as pd
|
||
# Load the dataset
|
||
data = pd.read_csv('data.csv')
|
||
|
||
# Finding invalid values based on a specific function
|
||
def is_valid_possitive_int(num):
|
||
try:
|
||
num = int(num)
|
||
return 1 <= num <= 31
|
||
except ValueError:
|
||
return False
|
||
|
||
invalid_days = data[~data['days'].astype(str).apply(is_valid_positive_int)]
|
||
|
||
## Dropping rows with invalid days
|
||
data = data.drop(invalid_days.index, errors='ignore')
|
||
|
||
|
||
|
||
# Set "NaN" values to a specific value
|
||
## For example, setting NaN values in the 'days' column to 0
|
||
data['days'] = pd.to_numeric(data['days'], errors='coerce')
|
||
|
||
## For example, set "NaN" to not ips
|
||
def is_valid_ip(ip):
|
||
pattern = re.compile(r'^((25[0-5]|2[0-4][0-9]|[01]?\d?\d)\.){3}(25[0-5]|2[0-4]\d|[01]?\d?\d)$')
|
||
if pd.isna(ip) or not pattern.match(str(ip)):
|
||
return np.nan
|
||
return ip
|
||
df['ip'] = df['ip'].apply(is_valid_ip)
|
||
|
||
# Filling missing values based on different strategies
|
||
numeric_cols = ["days", "hours", "minutes"]
|
||
categorical_cols = ["ip", "status"]
|
||
|
||
## Filling missing values in numeric columns with the median
|
||
num_imputer = SimpleImputer(strategy='median')
|
||
df[numeric_cols] = num_imputer.fit_transform(df[numeric_cols])
|
||
|
||
## Filling missing values in categorical columns with the most frequent value
|
||
cat_imputer = SimpleImputer(strategy='most_frequent')
|
||
df[categorical_cols] = cat_imputer.fit_transform(df[categorical_cols])
|
||
|
||
## Filling missing values in numeric columns using KNN imputation
|
||
knn_imputer = KNNImputer(n_neighbors=5)
|
||
df[numeric_cols] = knn_imputer.fit_transform(df[numeric_cols])
|
||
|
||
|
||
|
||
# Filling missing values
|
||
data.fillna(data.mean(), inplace=True)
|
||
|
||
# Removing duplicates
|
||
data.drop_duplicates(inplace=True)
|
||
# Filtering outliers using Z-score
|
||
from scipy import stats
|
||
z_scores = stats.zscore(data.select_dtypes(include=['float64', 'int64']))
|
||
data = data[(z_scores < 3).all(axis=1)]
|
||
```
|
||
## データ変換
|
||
|
||
データ変換は、データをモデル化に適した形式に変換することを含みます。このステップには以下が含まれる場合があります:
|
||
- **正規化と標準化**:数値特徴を共通の範囲にスケーリングすること、通常は [0, 1] または [-1, 1]。これにより、最適化アルゴリズムの収束が改善されます。
|
||
- **最小-最大スケーリング**:特徴を固定範囲に再スケーリングすること、通常は [0, 1]。これは次の式を使用して行われます: `X' = (X - X_{min}) / (X_{max} - X_{min})`
|
||
- **Zスコア正規化**:平均を引き、標準偏差で割ることによって特徴を標準化し、平均が0、標準偏差が1の分布を得ること。これは次の式を使用して行われます: `X' = (X - μ) / σ`、ここで μ は平均、σ は標準偏差です。
|
||
- **歪度と尖度**:特徴の分布を調整して歪度(非対称性)と尖度(ピークの高さ)を減少させること。これは対数変換、平方根変換、またはBox-Cox変換のような変換を使用して行うことができます。例えば、特徴が歪んだ分布を持つ場合、対数変換を適用することで正規化を助けることができます。
|
||
- **文字列正規化**:文字列を一貫した形式に変換すること、例えば:
|
||
- 小文字化
|
||
- 特殊文字の削除(関連するものを保持)
|
||
- ストップワードの削除(意味に寄与しない一般的な単語、例えば "the", "is", "and" など)
|
||
- あまりにも頻繁な単語とあまりにも稀な単語の削除(例えば、90%以上の文書に出現する単語やコーパス内で5回未満出現する単語)
|
||
- 空白のトリミング
|
||
- ステミング/レマタイゼーション:単語をその基本形またはルート形に減少させること(例えば、"running" を "run" に)。
|
||
|
||
- **カテゴリ変数のエンコーディング**:カテゴリ変数を数値表現に変換すること。一般的な技術には:
|
||
- **ワンホットエンコーディング**:各カテゴリのためにバイナリ列を作成すること。
|
||
- 例えば、特徴が "red"、"green"、"blue" のカテゴリを持つ場合、これは3つのバイナリ列に変換されます: `is_red`(100)、`is_green`(010)、および `is_blue`(001)。
|
||
- **ラベルエンコーディング**:各カテゴリにユニークな整数を割り当てること。
|
||
- 例えば、"red" = 0、"green" = 1、"blue" = 2。
|
||
- **順序エンコーディング**:カテゴリの順序に基づいて整数を割り当てること。
|
||
- 例えば、カテゴリが "low"、"medium"、"high" の場合、これらはそれぞれ0、1、2としてエンコードできます。
|
||
- **ハッシングエンコーディング**:ハッシュ関数を使用してカテゴリを固定サイズのベクトルに変換すること、これは高次元のカテゴリ変数に役立ちます。
|
||
- 例えば、特徴が多くのユニークなカテゴリを持つ場合、ハッシングは次元を削減しつつカテゴリに関する情報を保持できます。
|
||
- **単語の袋(BoW)**:テキストデータを単語のカウントまたは頻度の行列として表現すること、各行は文書に対応し、各列はコーパス内のユニークな単語に対応します。
|
||
- 例えば、コーパスに "cat"、"dog"、"fish" という単語が含まれている場合、"cat" と "dog" を含む文書は [1, 1, 0] として表現されます。この特定の表現は "unigram" と呼ばれ、単語の順序を捉えないため、意味情報を失います。
|
||
- **バイグラム/トライグラム**:BoWを拡張して単語のシーケンス(バイグラムまたはトライグラム)を捉え、いくつかの文脈を保持します。例えば、"cat and dog" は "cat and" のバイグラム [1, 1] と "and dog" のバイグラム [1, 1] として表現されます。この場合、より多くの意味情報が収集され(表現の次元が増加)、同時に2または3単語のみに対して行われます。
|
||
- **TF-IDF(用語頻度-逆文書頻度)**:文書内の単語の重要性を文書のコレクション(コーパス)に対して評価する統計的指標です。これは用語頻度(単語が文書に出現する頻度)と逆文書頻度(全文書における単語の稀少性)を組み合わせます。
|
||
- 例えば、"cat" という単語が文書内で頻繁に出現するが、コーパス全体では稀である場合、その文書における重要性を示す高いTF-IDFスコアを持ちます。
|
||
|
||
- **特徴エンジニアリング**:既存の特徴から新しい特徴を作成し、モデルの予測力を高めること。これには特徴の結合、日付/時間コンポーネントの抽出、またはドメイン特有の変換の適用が含まれる場合があります。
|
||
|
||
## データ分割
|
||
|
||
データ分割は、データセットをトレーニング、検証、およびテストのための別々のサブセットに分割することを含みます。これは、モデルの未見データに対する性能を評価し、過学習を防ぐために不可欠です。一般的な戦略には:
|
||
- **トレイン-テスト分割**:データセットをトレーニングセット(通常はデータの60-80%)、ハイパーパラメータを調整するための検証セット(データの10-15%)、およびテストセット(データの10-15%)に分割します。モデルはトレーニングセットで訓練され、テストセットで評価されます。
|
||
- 例えば、1000サンプルのデータセットがある場合、700サンプルをトレーニングに、150を検証に、150をテストに使用することがあります。
|
||
- **層化サンプリング**:トレーニングセットとテストセットのクラスの分布が全体のデータセットに似ていることを保証します。これは、いくつかのクラスが他のクラスよりも著しく少ないサンプルを持つ不均衡データセットにとって特に重要です。
|
||
- **時系列分割**:時系列データの場合、データセットは時間に基づいて分割され、トレーニングセットには早い時期のデータが含まれ、テストセットには後の時期のデータが含まれます。これにより、モデルの将来のデータに対する性能を評価するのに役立ちます。
|
||
- **K-分割交差検証**:データセットをK個のサブセット(フォールド)に分割し、モデルをK回訓練し、各回で異なるフォールドをテストセットとして使用し、残りのフォールドをトレーニングセットとして使用します。これにより、モデルが異なるデータのサブセットで評価され、性能のより堅牢な推定が提供されます。
|
||
|
||
## モデル評価
|
||
|
||
モデル評価は、未見データに対する機械学習モデルの性能を評価するプロセスです。これは、モデルが新しいデータにどれだけ一般化できるかを定量化するためにさまざまな指標を使用します。一般的な評価指標には:
|
||
|
||
### 精度
|
||
|
||
精度は、全体のインスタンスの中で正しく予測されたインスタンスの割合です。これは次のように計算されます:
|
||
```plaintext
|
||
Accuracy = (Number of Correct Predictions) / (Total Number of Predictions)
|
||
```
|
||
> [!TIP]
|
||
> 精度はシンプルで直感的な指標ですが、あるクラスが他のクラスを支配する不均衡なデータセットには適さない場合があります。なぜなら、モデルのパフォーマンスについて誤解を招く印象を与える可能性があるからです。例えば、データの90%がクラスAに属し、モデルがすべてのインスタンスをクラスAとして予測した場合、90%の精度を達成しますが、クラスBを予測するのには役立ちません。
|
||
|
||
### Precision
|
||
|
||
Precisionは、モデルが行ったすべての正の予測の中で、真の正の予測の割合です。次のように計算されます:
|
||
```plaintext
|
||
Precision = (True Positives) / (True Positives + False Positives)
|
||
```
|
||
> [!TIP]
|
||
> 精度は、医療診断や詐欺検出など、偽陽性が高価または望ましくないシナリオにおいて特に重要です。たとえば、モデルが100件のインスタンスを陽性と予測したが、そのうち実際に陽性であるのは80件だけの場合、精度は0.8(80%)になります。
|
||
|
||
### リコール(感度)
|
||
|
||
リコールは、感度または真陽性率とも呼ばれ、すべての実際の陽性インスタンスに対する真陽性予測の割合です。これは次のように計算されます:
|
||
```plaintext
|
||
Recall = (True Positives) / (True Positives + False Negatives)
|
||
```
|
||
> [!TIP]
|
||
> リコールは、偽陰性が高コストまたは望ましくないシナリオ、例えば病気検出やスパムフィルタリングにおいて重要です。例えば、モデルが100の実際の陽性インスタンスのうち80を特定した場合、リコールは0.8(80%)になります。
|
||
|
||
### F1スコア
|
||
|
||
F1スコアは、精度とリコールの調和平均であり、2つの指標のバランスを提供します。計算式は次の通りです:
|
||
```plaintext
|
||
F1 Score = 2 * (Precision * Recall) / (Precision + Recall)
|
||
```
|
||
> [!TIP]
|
||
> F1スコアは、不均衡なデータセットを扱う際に特に有用であり、偽陽性と偽陰性の両方を考慮します。これは、精度と再現率のトレードオフを捉える単一の指標を提供します。たとえば、モデルの精度が0.8で再現率が0.6の場合、F1スコアは約0.69になります。
|
||
|
||
### ROC-AUC (受信者動作特性 - 曲線下面積)
|
||
|
||
ROC-AUCメトリックは、さまざまな閾値設定で真陽性率(感度)と偽陽性率をプロットすることによって、クラスを区別するモデルの能力を評価します。ROC曲線の下の面積(AUC)は、モデルのパフォーマンスを定量化し、1の値は完璧な分類を示し、0.5の値はランダムな推測を示します。
|
||
|
||
> [!TIP]
|
||
> ROC-AUCは、バイナリ分類問題に特に有用であり、さまざまな閾値にわたるモデルのパフォーマンスの包括的なビューを提供します。精度に比べてクラスの不均衡に対して敏感ではありません。たとえば、AUCが0.9のモデルは、正のインスタンスと負のインスタンスを区別する能力が高いことを示しています。
|
||
|
||
### 特異度
|
||
|
||
特異度(真陰性率とも呼ばれる)は、すべての実際の負のインスタンスの中で真陰性予測の割合です。これは次のように計算されます:
|
||
```plaintext
|
||
Specificity = (True Negatives) / (True Negatives + False Positives)
|
||
```
|
||
> [!TIP]
|
||
> 特異性は、偽陽性が高コストまたは望ましくないシナリオ、例えば医療テストや詐欺検出において重要です。これは、モデルがネガティブなインスタンスをどれだけうまく特定できるかを評価するのに役立ちます。例えば、モデルが100の実際のネガティブインスタンスのうち90を正しく特定した場合、特異性は0.9(90%)になります。
|
||
|
||
### Matthews Correlation Coefficient (MCC)
|
||
Matthews Correlation Coefficient (MCC)は、バイナリ分類の質を測る指標です。これは、真陽性と偽陽性、真陰性と偽陰性を考慮し、モデルのパフォーマンスのバランスの取れた見方を提供します。MCCは次のように計算されます:
|
||
```plaintext
|
||
MCC = (TP * TN - FP * FN) / sqrt((TP + FP) * (TP + FN) * (TN + FP) * (TN + FN))
|
||
```
|
||
where:
|
||
- **TP**: 真陽性
|
||
- **TN**: 真陰性
|
||
- **FP**: 偽陽性
|
||
- **FN**: 偽陰性
|
||
|
||
> [!TIP]
|
||
> MCCは-1から1の範囲で、1は完璧な分類を示し、0はランダムな推測を示し、-1は予測と観察の間の完全な不一致を示します。これは、すべての4つの混同行列の要素を考慮するため、特に不均衡なデータセットに役立ちます。
|
||
|
||
### 平均絶対誤差 (MAE)
|
||
平均絶対誤差 (MAE) は、予測値と実際の値の間の平均絶対差を測定する回帰指標です。計算式は次のようになります:
|
||
```plaintext
|
||
MAE = (1/n) * Σ|y_i - ŷ_i|
|
||
```
|
||
where:
|
||
- **n**: インスタンスの数
|
||
- **y_i**: インスタンス i の実際の値
|
||
- **ŷ_i**: インスタンス i の予測値
|
||
|
||
> [!TIP]
|
||
> MAE は予測の平均誤差の明確な解釈を提供し、理解しやすくなっています。他の指標、例えば平均二乗誤差 (MSE) に比べて外れ値に対して敏感ではありません。例えば、モデルの MAE が 5 の場合、平均してモデルの予測は実際の値から 5 ユニットずれていることを意味します。
|
||
|
||
### 混同行列
|
||
|
||
混同行列は、真陽性、真陰性、偽陽性、偽陰性の予測のカウントを示すことによって、分類モデルのパフォーマンスを要約する表です。モデルが各クラスでどれだけうまく機能しているかの詳細なビューを提供します。
|
||
|
||
| | 予測陽性 | 予測陰性 |
|
||
|---------------|------------------|------------------|
|
||
| 実際の陽性 | 真陽性 (TP) | 偽陰性 (FN) |
|
||
| 実際の陰性 | 偽陽性 (FP) | 真陰性 (TN) |
|
||
|
||
- **真陽性 (TP)**: モデルが正しく陽性クラスを予測しました。
|
||
- **真陰性 (TN)**: モデルが正しく陰性クラスを予測しました。
|
||
- **偽陽性 (FP)**: モデルが誤って陽性クラスを予測しました (タイプ I エラー)。
|
||
- **偽陰性 (FN)**: モデルが誤って陰性クラスを予測しました (タイプ II エラー)。
|
||
|
||
混同行列は、精度、適合率、再現率、F1 スコアなどのさまざまな評価指標を計算するために使用できます。
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|