机器学习中的数据预处理步骤2

机器学习中的数据预处理步骤

数据预处理是机器学习工作流程中至关重要的一环,它能够显著提高模型的性能和准确性。以下是数据预处理的主要步骤及相关的scikit-learn函数和使用场景:

1. 数据加载与探索

在开始处理数据之前,首先需要加载数据并了解其基本情况。

常用函数:

  • pandas.read_csv()/pandas.read_excel() - 读取数据文件
  • pandas.DataFrame.describe() - 获取数据统计摘要
  • pandas.DataFrame.info() - 查看数据类型和缺失值
  • pandas.DataFrame.head() - 查看前几行数据

实例:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 加载数据
df = pd.read_csv('dataset.csv')

# 查看数据信息
print(df.info())
print(df.describe())

# 查看前几行数据
print(df.head())

# 数据可视化
plt.figure(figsize=(10, 6))
sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
plt.title('特征相关性矩阵')
plt.show()

2. 处理缺失值

缺失值可能会影响模型训练效果,需要通过填充或删除来处理。

常用函数:

  • sklearn.impute.SimpleImputer - 用于替换缺失值
  • pandas.DataFrame.dropna() - 删除包含缺失值的行或列

使用场景:

  • 当缺失值较少时,可以考虑删除包含缺失值的行
  • 对于连续型变量,可以用均值、中位数或众数填充
  • 对于分类变量,可以用众数填充

实例:

from sklearn.impute import SimpleImputer

# 使用均值填充数值型特征的缺失值
numerical_imputer = SimpleImputer(strategy='mean')
df_numerical = df.select_dtypes(include=['int64', 'float64'])
df[df_numerical.columns] = numerical_imputer.fit_transform(df_numerical)

# 使用众数填充分类特征的缺失值
categorical_imputer = SimpleImputer(strategy='most_frequent')
df_categorical = df.select_dtypes(include=['object'])
df[df_categorical.columns] = categorical_imputer.fit_transform(df_categorical)

3. 处理异常值/离群点

异常值会影响统计分析和模型训练,需要识别并处理。

常用函数:

  • sklearn.ensemble.IsolationForest - 异常检测
  • scipy.stats.zscore - 计算Z分数

使用场景:

  • 当数据集较大且异常点很明显时,可以考虑删除
  • 也可以考虑将异常值截断到某个合理范围
  • 对于高维数据,可以使用隔离森林等算法检测异常值

实例:

import numpy as np
from scipy import stats

# 使用Z分数检测并处理异常值
z_scores = stats.zscore(df['feature'])
abs_z_scores = np.abs(z_scores)
filtered_entries = (abs_z_scores < 3)  # 保留Z分数绝对值小于3的数据点
df_no_outliers = df[filtered_entries]

# 或者使用IQR方法检测并处理异常值
Q1 = df['feature'].quantile(0.25)
Q3 = df['feature'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
df_no_outliers = df[(df['feature'] >= lower_bound) & (df['feature'] <= upper_bound)]

4. 特征编码

将分类特征转换为数值形式,以便模型可以处理。

常用函数:

  • sklearn.preprocessing.LabelEncoder - 将类别标签编码为0到n_classes-1
  • sklearn.preprocessing.OneHotEncoder - 将分类特征转换为独热编码
  • sklearn.preprocessing.OrdinalEncoder - 用于有序分类特征的编码
  • sklearn.preprocessing.TargetEncoder - 用目标变量的均值替换分类变量

使用场景:

  • LabelEncoder适用于目标变量的编码
  • OneHotEncoder适用于没有顺序关系的分类特征
  • OrdinalEncoder适用于有顺序关系的分类特征
  • TargetEncoder适合处理高基数分类特征

实例:

from sklearn.preprocessing import LabelEncoder, OneHotEncoder

# 对目标变量进行标签编码
label_encoder = LabelEncoder()
df['target_encoded'] = label_encoder.fit_transform(df['target'])

# 对分类特征进行独热编码
categorical_features = ['feature1', 'feature2']
one_hot_encoder = OneHotEncoder(sparse_output=False, drop='first')
encoded_features = one_hot_encoder.fit_transform(df[categorical_features])
encoded_df = pd.DataFrame(encoded_features, 
                          columns=one_hot_encoder.get_feature_names_out(categorical_features))
df = pd.concat([df.drop(categorical_features, axis=1), encoded_df], axis=1)

5. 特征缩放/标准化

调整特征的尺度,使特征具有可比性,这对于许多算法非常重要。

常用函数:

  • sklearn.preprocessing.StandardScaler - 标准化,使数据均值为0,标准差为1
  • sklearn.preprocessing.MinMaxScaler - 将数据缩放到特定范围(默认为[0,1])
  • sklearn.preprocessing.RobustScaler - 使用中位数和四分位数,对异常值不敏感
  • sklearn.preprocessing.Normalizer - 将样本缩放到单位范数

使用场景:

  • StandardScaler适用于正态分布数据
  • MinMaxScaler适用于希望特征在固定范围内的情况
  • RobustScaler适用于存在异常值的数据
  • Normalizer适用于需要考虑样本向量方向而非幅值的情况

实例:

from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler

# 标准化
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df[['feature1', 'feature2', 'feature3']])

# MinMax缩放到[0,1]区间
min_max_scaler = MinMaxScaler()
df_min_max_scaled = min_max_scaler.fit_transform(df[['feature1', 'feature2', 'feature3']])

# 使用RobustScaler处理有异常值的数据
robust_scaler = RobustScaler()
df_robust_scaled = robust_scaler.fit_transform(df[['feature1', 'feature2', 'feature3']])

6. 特征选择

选择最相关或最重要的特征,减少维度,提高模型性能。

常用函数:

  • sklearn.feature_selection.SelectKBest - 选择K个最佳特征
  • sklearn.feature_selection.RFE - 递归特征消除
  • sklearn.feature_selection.SelectFromModel - 基于模型的特征选择

使用场景:

  • SelectKBest适用于基于统计测试选择特征
  • RFE适用于通过递归减少特征数量
  • SelectFromModel适用于基于树模型等提取特征重要性

实例:

from sklearn.feature_selection import SelectKBest, f_classif, RFE
from sklearn.ensemble import RandomForestClassifier

# 使用SelectKBest选择最佳的3个特征
selector = SelectKBest(score_func=f_classif, k=3)
X_new = selector.fit_transform(X, y)
selected_features = X.columns[selector.get_support()]

# 使用随机森林和RFE进行特征选择
rf = RandomForestClassifier()
rfe = RFE(estimator=rf, n_features_to_select=5)
X_rfe = rfe.fit_transform(X, y)
selected_features_rfe = X.columns[rfe.support_]

7. 特征工程

创建新特征或转换现有特征,以提高模型性能。

常用函数:

  • sklearn.preprocessing.PolynomialFeatures - 创建多项式特征
  • sklearn.preprocessing.FunctionTransformer - 应用自定义函数变换
  • sklearn.decomposition.PCA - 主成分分析降维

使用场景:

  • PolynomialFeatures适用于捕捉非线性关系
  • FunctionTransformer适用于应用自定义变换
  • PCA适用于降维和处理多重共线性

实例:

from sklearn.preprocessing import PolynomialFeatures
from sklearn.decomposition import PCA

# 创建多项式特征
poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(X)

# 使用PCA降维
pca = PCA(n_components=5)
X_pca = pca.fit_transform(X)
print(f"解释方差比例: {pca.explained_variance_ratio_}")

8. 数据分割

将数据集分为训练集和测试集,以评估模型性能。

常用函数:

  • sklearn.model_selection.train_test_split - 随机分割数据集
  • sklearn.model_selection.KFold - K折交叉验证

使用场景:

  • train_test_split适用于简单的训练/测试分割
  • KFold适用于进行交叉验证

实例:

from sklearn.model_selection import train_test_split, KFold

# 简单的训练/测试分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# K折交叉验证
kf = KFold(n_splits=5, shuffle=True, random_state=42)
for train_index, test_index in kf.split(X):
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]
    y_train, y_test = y.iloc[train_index], y.iloc[test_index]
    # 训练和评估模型

9. 类别不平衡处理

处理训练集中类别分布不均的情况。

常用函数:

  • sklearn.utils.class_weight.compute_class_weight - 计算类别权重
  • imblearn.over_sampling.SMOTE - 合成少数类过采样技术
  • imblearn.under_sampling.RandomUnderSampler - 随机欠采样

使用场景:

  • 当类别严重不平衡时
  • 当少数类样本较少或稀有事件检测

实例:

from imblearn.over_sampling import SMOTE
from sklearn.utils.class_weight import compute_class_weight

# 使用SMOTE过采样
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)

# 计算类别权重
class_weights = compute_class_weight(class_weight='balanced', classes=np.unique(y), y=y)
class_weight_dict = dict(zip(np.unique(y), class_weights))

# 在模型中使用类别权重
model = RandomForestClassifier(class_weight=class_weight_dict)

完整的数据预处理实例

下面是一个完整的数据预处理流程示例,整合了上述步骤:

import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report

# 1. 加载数据
df = pd.read_csv('你的数据.csv')
print("数据基本信息:")
print(df.info())
print("\n数据预览:")
print(df.head())

# 2. 分离特征和目标变量
X = df.drop('target', axis=1)
y = df['target']

# 3. 识别数值和分类特征
numerical_features = X.select_dtypes(include=['int64', 'float64']).columns.tolist()
categorical_features = X.select_dtypes(include=['object']).columns.tolist()

# 4. 创建数据预处理管道
# 数值特征处理:填充缺失值 + 标准化
numerical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())
])

# 分类特征处理:填充缺失值 + 独热编码
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='most_frequent')),
    ('onehot', OneHotEncoder(handle_unknown='ignore'))
])

# 组合所有预处理步骤
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numerical_transformer, numerical_features),
        ('cat', categorical_transformer, categorical_features)
    ])

# 5. 创建完整的模型管道
model_pipeline = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('classifier', RandomForestClassifier(random_state=42))
])

# 6. 分割数据为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 7. 训练模型
model_pipeline.fit(X_train, y_train)

# 8. 评估模型
y_pred = model_pipeline.predict(X_test)
print("\n模型评估:")
print(classification_report(y_test, y_pred))

# 9. 特征重要性分析(如果适用)
if hasattr(model_pipeline.named_steps['classifier'], 'feature_importances_'):
    # 获取处理后的特征名称
    feature_names = []
    
    # 获取数值特征名称
    if numerical_features:
        feature_names.extend(numerical_features)
    
    # 获取独热编码后的分类特征名称
    if categorical_features:
        ohe = preprocessor.named_transformers_['cat'].named_steps['onehot']
        feature_names.extend(ohe.get_feature_names_out(categorical_features))
    
    # 获取特征重要性
    importances = model_pipeline.named_steps['classifier'].feature_importances_
    
    # 创建特征重要性DataFrame并排序
    feature_importance_df = pd.DataFrame({
        'Feature': feature_names,
        'Importance': importances
    }).sort_values(by='Importance', ascending=False)
    
    print("\n特征重要性:")
    print(feature_importance_df.head(10))  # 显示前10个重要特征

以上是使用scikit-learn进行数据预处理的完整流程,包括数据加载、缺失值处理、特征编码、特征缩放、特征工程和模型训练与评估。这个流程适用于大多数机器学习任务,可以根据具体数据集和问题进行适当调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值