hacktricks/src/AI/AI-Model-Data-Preparation-and-Evaluation.md

234 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 模型数据准备与评估
{{#include ../banners/hacktricks-training.md}}
模型数据准备是机器学习流程中的关键步骤,因为它涉及将原始数据转换为适合训练机器学习模型的格式。此过程包括几个关键步骤:
1. **数据收集**从各种来源收集数据例如数据库、API或文件。数据可以是结构化的例如表格或非结构化的例如文本、图像
2. **数据清理**:删除或更正错误、不完整或不相关的数据点。此步骤可能涉及处理缺失值、删除重复项和过滤异常值。
3. **数据转换**:将数据转换为适合建模的格式。这可能包括归一化、缩放、编码分类变量,以及通过特征工程等技术创建新特征。
4. **数据拆分**:将数据集划分为训练集、验证集和测试集,以确保模型能够很好地泛化到未见过的数据。
## 数据收集
数据收集涉及从各种来源收集数据,这些来源可以包括:
- **数据库**从关系数据库例如SQL数据库或NoSQL数据库例如MongoDB提取数据。
- **API**从网络API获取数据这些API可以提供实时或历史数据。
- **文件**从CSV、JSON或XML等格式的文件中读取数据。
- **网络爬虫**:使用网络爬虫技术从网站收集数据。
根据机器学习项目的目标,数据将从相关来源提取和收集,以确保其代表问题领域。
## 数据清理
数据清理是识别和更正数据集中错误或不一致的过程。此步骤对于确保用于训练机器学习模型的数据质量至关重要。数据清理中的关键任务包括:
- **处理缺失值**:识别和处理缺失的数据点。常见策略包括:
- 删除缺失值的行或列。
- 使用均值、中位数或众数插补缺失值。
- 使用K近邻KNN插补或回归插补等高级方法。
- **删除重复项**:识别并删除重复记录,以确保每个数据点都是唯一的。
- **过滤异常值**检测并删除可能影响模型性能的异常值。可以使用Z-score、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",它将被转换为三个二进制列: `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" 将表示为二元组 [1, 1] 对于 "cat and" 和 [1, 1] 对于 "and dog"。在这些情况下,收集了更多的语义信息(增加了表示的维度),但一次仅限于 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.880%)。
### 召回率(敏感性)
召回率,也称为敏感性或真正阳性率,是所有实际正实例中真正阳性预测的比例。它的计算公式为:
```plaintext
Recall = (True Positives) / (True Positives + False Negatives)
```
> [!TIP]
> 召回率在假阴性代价高昂或不可取的场景中至关重要例如在疾病检测或垃圾邮件过滤中。例如如果一个模型识别出100个实际阳性实例中的80个则召回率为0.880%)。
### F1 Score
F1分数是精确率和召回率的调和平均值提供了两者之间的平衡。它的计算公式为
```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.990%)。
### 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 表示预测与观察之间的完全不一致。它对于不平衡数据集特别有用,因为它考虑了所有四个混淆矩阵组件。
### 平均绝对误差 (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)**: 模型错误预测了正类(第一类错误)。
- **假负例 (FN)**: 模型错误预测了负类(第二类错误)。
混淆矩阵可用于计算各种评估指标,如准确率、精确率、召回率和 F1 分数。
{{#include ../banners/hacktricks-training.md}}