python机器学习 数据集划分

标准的做法是将数据划分为训练集(Training Set),测试集(Test Set)与验证集(Validation Set)

训练集(Training Set)

用于训练模型,使其学习到数据中的潜在模式

测试集(Test Set)

用于在模型投入生产环境之前,对其泛化误差(Generalization Error)进行最终评估

OS : 在项目启动之前,测试集的数据通常不应被触碰或浏览,以避免数据窥探偏误(data snooping bias),这可能导致对模型性能做出过于乐观的估计,

验证集(Validation Set)

通常会从训练集中分离出一个验证集,专门用于比较候选模型和调整超参数(hyperparameters)

from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn.datasets import load_breast_cancer

# 加载示例数据
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target)

# 先切出测试集
X_temp, X_test, y_temp, y_test = train_test_split(
    X, y,
    test_size=0.2,
    stratify=y,
    random_state=42
)

# 再从剩余数据中切验证集
X_train, X_val, y_train, y_val = train_test_split(
    X_temp, y_temp,
    test_size=0.25,  # 0.25 × 0.8 = 0.2
    stratify=y_temp,
    random_state=42
)

print("训练集:", X_train.shape)
print("验证集:", X_val.shape)
print("测试集:", X_test.shape)

修改成分3组数据集,并且分组分布规律

def train_test_split_3_row(X,y,test_size=0.2,test_size_val=0.25,random_state=42):
    X_temp, X_test, y_temp, y_test = train_test_split(
        X, y,
        test_size=test_size,
        stratify=y,
        random_state=random_state
    )

    # 再从剩余数据中切验证集
    X_train, X_val, y_train, y_val = train_test_split(
        X_temp, y_temp,
        test_size=test_size_val,  # 0.25 × 0.8 = 0.2
        stratify=y_temp,
        random_state=random_state
    )

    print("训练集:", X_train.shape)
    print("验证集:", X_val.shape)
    print("测试集:", X_test.shape)
    return X_train , X_val , X_test , y_train , y_val , y_test

采样的重要性与偏差(Sampling Importance and Bias)

  • 代表性不足的风险: 如果训练集不能很好地代表你想要泛化的新实例,模型就不可能做出准确的预测,尤其是在针对极端贫穷或极端富裕的国家进行预测时,如果训练数据没有相应的代表性,模型可能会显著偏离实际情况
  • 采样噪声与偏差: 即使数据集很大,如果采样方式选择不当,也可能导致采样偏差(Sampling Bias),从而引入非代表性数据,使训练集不能代表全体人口

数据集划分与抽样方法(Data Splitting and Sampling Techniques)

要确保测试集和训练集(以及验证集)具有代表性,特别是针对将来的预测,需要采取细致的划分策略:

  • 分层抽样 (Stratified Sampling):
    • 如果数据集不够大,或者在某些重要属性上(如收入中位数)不希望出现采样偏差,应使用分层抽样
    • 分层抽样的目标是确保测试集能够代表总体的比例
    • 该方法需要将人口划分为均匀的子集(或称为层),然后从每层中抽取正确数量的实例,以确保测试集合的比例代表了总体的比例
    • 实例: 在预测房价中位数时,由于收入中位数是一个非常重要的属性,应该在训练集和测试集中确保不同的收入类别都得到充分的代表

使用 stratify=y

X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.3,
    stratify=y,
    random_state=42
)

print("测试集类别分布(分层抽样):")
print(y_test.value_counts())