[转载]十大数据预处理方法

原文链接:​通透!十大数据预处理方法 最强总结!

数据预处理在机器学习和数据科学中是非常非常重要的,因为它直接影响模型的性能和准确性。

  1. 提高数据质量: 现实中的数据往往存在噪声、缺失值和异常值。如果不清洗和修正,这些问题会导致模型做出错误的预测或分析。因此,数据预处理通过清理、修复和标准化数据,确保输入的数据是干净、可靠的。

  2. 增强模型性能: 不同的特征在数据集中可能有不同的量纲或尺度,这可能会使某些特征对模型的影响过大或过小。通过归一化、标准化和特征选择,可以让模型更均衡地利用所有特征,从而提高模型的性能。

  3. 防止过拟合: 过多的特征或不相关的数据会增加模型的复杂性,导致过拟合。通过特征选择和降维,可以减少特征的数量,降低模型的复杂度,从而提高模型的泛化能力,防止过拟合。

  4. 处理不平衡数据: 在实际应用中,数据集的类别分布可能严重不平衡,如果不加以处理,模型可能会偏向多数类,忽视少数类。通过过采样、降采样等方法可以平衡数据集,从而提高模型对少数类的识别能力。

  5. 提高模型的解释性和效率: 简化数据结构和减少无用特征不仅可以提高模型的计算效率,还能使模型更容易解释。这样,决策者可以更好地理解模型的输出,并做出更明智的决策。

没有有效的数据预处理,模型可能难以捕捉到数据中的真实模式,最终影响预测结果的可靠性。

今天提到的10种数据预处理方法有:

  • 标准化

  • 归一化

  • 主成分分析

  • 标签编码

  • 独热编码

  • 过采样

  • 滑动窗口

  • 插值

  • 降采样

  • 特征选择

咱们下面详细的聊聊这些方法,大家一定会有一个完整的认识。

1. 标准化(Standardization)

核心公式

标准化的目标是使数据具有零均值和单位方差。给定一个数据集 ,标准化的步骤如下:

  1. 计算均值:

  1. 计算标准差:

  1. 标准化公式:

通过上述公式,我们将每个数据点  转换为标准化值 ,使得所有数据点的均值为0,方差为1。

优点

  • 提高模型训练的稳定性。

  • 使不同特征具有相同的尺度,适合于对距离敏感的算法。

缺点

  • 对于有明显离群值的数据,标准化可能会受到影响,导致结果不理想。

适用场景

  • 特别适用于要求数据分布近似正态分布的算法,如SVM、线性回归和KNN等。

核心案例

from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import StandardScaler
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 加载数据集
california = fetch_california_housing()
data = pd.DataFrame(california.data, columns=california.feature_names)

# 原始数据统计信息
print("原始数据统计信息:\n", data.describe())

# 标准化
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# 将标准化后的数据转为DataFrame
data_scaled = pd.DataFrame(data_scaled, columns=california.feature_names)

# 标准化后数据统计信息
print("标准化后数据统计信息:\n", data_scaled.describe())

# 可视化前后数据分布
plt.figure(figsize=(16, 6))

# 标准化前的分布
plt.subplot(1, 2, 1)
sns.histplot(data['MedInc'], kde=True, color='blue')
plt.title('Distribution of Median Income before Standardization')

# 标准化后的分布
plt.subplot(1, 2, 2)
sns.histplot(data_scaled['MedInc'], kde=True, color='red')
plt.title('Distribution of Median Income after Standardization')

plt.show()

2. 归一化(Normalization)

核心公式

归一化的目标是将数据缩放到特定的范围(通常是[0, 1])。给定一个数据集 ,归一化的步骤如下:

  1. 找到最小值和最大值:

  1. 归一化公式:

通过该公式,所有数据点将被缩放到 [0, 1] 范围内。

优点

  • 使得数据在同一尺度上,有助于加快梯度下降的收敛速度。

  • 适用于需要计算距离的算法,如KNN和神经网络。

缺点

  • 对于有离群值的数据,归一化后的数据分布可能会受到影响。

适用场景

  • 特别适用于距离度量敏感的算法,如KNN、神经网络。

核心案例

我们将使用Iris数据集来展示归一化的效果,并生成相关的图表。

from sklearn.datasets import load_iris
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 加载数据集
iris = load_iris()
data = pd.DataFrame(iris.data, columns=iris.feature_names)

# 原始数据统计信息
print("原始数据统计信息:\n", data.describe())

# 归一化
scaler = MinMaxScaler()
data_normalized = scaler.fit_transform(data)

# 将归一化后的数据转为DataFrame
data_normalized = pd.DataFrame(data_normalized, columns=iris.feature_names)

# 归一化数据统计信息
print("归一化后数据统计信息:\n", data_normalized.describe())

# 可视化前后数据分布
plt.figure(figsize=(16, 6))

# 归一化前的分布
plt.subplot(1, 2, 1)
sns.histplot(data['sepal length (cm)'], kde=True, color='green')
plt.title('Distribution of Sepal Length before Normalization')

# 归一化后的分布
plt.subplot(1, 2, 2)
sns.histplot(data_normalized['sepal length (cm)'], kde=True, color='orange')
plt.title('Distribution of Sepal Length after Normalization')

plt.show()

3. 主成分分析(PCA)

核心公式

主成分分析的目标是将高维数据投影到低维空间,同时最大化投影后的方差。核心步骤包括:

  1. 数据中心化:

其中 \mu 是数据的均值向量。

  1. 计算协方差矩阵:

  1. 特征分解: 对协方差矩阵 C 进行特征分解,得到特征值和特征向量:

其中 \lambda _{i} 为特征值, v _{i}为对应的特征向量。

  1. 降维: 选择前 k 个最大特征值对应的特征向量,形成投影矩阵w _{k} ,然后将数据投影到低维空间:

优点

  • 能有效降低数据的维度,减少计算复杂度。

  • 可以去除冗余特征,提高模型的泛化能力。

缺点

  • PCA是线性方法,对于非线性数据效果不佳。

  • 主成分的物理意义不明确,可能不利于解释。

适用场景

  • 特别适用于高维数据的降维,如图像处理、基因数据分析。

核心案例

我们使用Wine数据集来展示PCA的效果~

from sklearn.datasets import load_wine
from sklearn.decomposition import PCA
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 加载数据集
wine = load_wine()
data = pd.DataFrame(wine.data, columns=wine.feature_names)

# 原始数据统计信息
print("原始数据统计信息:\n", data.describe())

# PCA降维至2维
pca = PCA(n_components=2)
data_pca = pca.fit_transform(data)

# 将PCA后的数据转为DataFrame
data_pca = pd.DataFrame(data_pca, columns=['PC1', 'PC2'])

# 可视化PCA结果
plt.figure(figsize=(10, 8))
sns.scatterplot(x='PC1', y='PC2', hue=wine.target, palette='bright', data=data_pca)
plt.title('PCA of Wine Dataset')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()

4. 标签编码(Label Encoding)

核心逻辑

标签编码的目标是将分类变量转换为整数值,使得模型可以处理非数值数据。

具体步骤如下:

类别映射:

假设有一个分类特征 ,标签编码将每个类别 c_{i} 映射为一个整数值l _{i} 。

例如

优点

  • 简单易用,适合有序的类别数据。

  • 对存储空间需求小,直接使用整数表示。

缺点

  • 对无序类别数据引入了虚假的顺序关系,可能影响模型性能。

适用场景

  • 适用于有序类别数据,如学历(高中、本科、硕士)。

核心案例

我们使用模拟的学历数据来展示标签编码的效果,并生成相关的图表。

import pandas as pd
from sklearn.preprocessing import LabelEncoder
import matplotlib.pyplot as plt
import seaborn as sns

# 创建示例数据
data = pd.DataFrame({
    'Education': ['High School', 'Bachelor', 'Master', 'PhD', 'Bachelor', 'High School', 'Master', 'PhD']
})

# 标签编码
label_encoder = LabelEncoder()
data['Education_encoded'] = label_encoder.fit_transform(data['Education'])

# 可视化标签编码结果
plt.figure(figsize=(8, 6))
sns.countplot(x='Education_encoded', data=data, palette='coolwarm')
plt.title('Label Encoded Education Levels')
plt.xlabel('Encoded Labels')
plt.ylabel('Count')
plt.show()

print("标签编码结果:\n", data)

5. 独热编码(One-Hot Encoding)

核心公式

独热编码的目标是将分类变量转换为二进制向量,使得每个类别被单独表示。假设有一个分类特征 ,独热编码的步骤如下:

类别向量化:

每个类别  c_{i}  被表示为一个长度为 m 的二进制向量,其中第 i 位为1,其余为0。

例如

优点

  • 消除类别之间的顺序关系,避免模型引入虚假的顺序信息。

  • 提高模型对类别变量的处理能力,适合无序类别。

缺点

  • 当类别较多时,会显著增加数据的维度,导致“维度灾难”。

  • 对于高基数的分类特征,如城市、国家,编码后的稀疏矩阵会占用大量内存。

适用场景

  • 适用于无序类别数据,如性别、颜色等。

核心案例

我们使用Titanic数据集中的性别特征来展示独热编码的效果~

import pandas as pd
from sklearn.preprocessing import OneHotEncoder
import matplotlib.pyplot as plt
import seaborn as sns

# 创建示例数据
data = pd.DataFrame({
    'Gender': ['Male', 'Female', 'Female', 'Male', 'Female', 'Male', 'Male', 'Female']
})

# 独热编码
onehot_encoder = OneHotEncoder(sparse=False)
gender_encoded = onehot_encoder.fit_transform(data[['Gender']])

# 将独热编码后的数据转为DataFrame
gender_encoded_df = pd.DataFrame(gender_encoded, columns=onehot_encoder.categories_[0])

# 可视化独热编码结果
plt.figure(figsize=(8, 6))
sns.heatmap(gender_encoded_df, annot=True, cbar=False, cmap='coolwarm')
plt.title('One-Hot Encoded Gender')
plt.xlabel('Gender')
plt.ylabel('Sample Index')
plt.show()

print("独热编码结果:\n", gender_encoded_df)

6. 过采样(Over-sampling)

核心公式

过采样的目标是通过复制少数类样本来平衡类别分布,主要方法包括简单复制和SMOTE(合成少数类过采样技术)。

SMOTE的核心步骤如下:

  1. 选择样本: 从少数类样本中随机选择一个样本 x。

  2. 找到k个最近邻样本: 在少数类样本中找到k个最近邻样本x_{neighbor} 。

  3. 生成新样本: 在原样本x  和一个最近邻样本 x_{neighbor}之间生成一个新样本x_{new} ,其计算公式为:

其中 \lambda 是一个0到1之间的随机数。

优点

  • 增加少数类样本数量,提高分类模型对少数类的识别能力。

  • 使用SMOTE生成的新样本更具多样性,减轻了过拟合的风险。

缺点

  • 可能会引入噪声样本,导致模型过拟合。

  • 简单复制方法可能会加剧少数类的过拟合问题。

适用场景

  • 特别适用于类别不平衡问题,如欺诈检测、医疗诊断等。

核心案例

我们使用模拟的二分类不平衡数据集来展示过采样的效果~

from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt
import seaborn as sns

# 创建不平衡数据集
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0,
                           n_clusters_per_class=1, weights=[0.9, 0.1], random_state=42)

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

# 可视化过采样前后的数据分布
plt.figure(figsize=(16, 6))

# 过采样前
plt.subplot(1, 2, 1)
sns.scatterplot(X[:, 0], X[:, 1], hue=y, palette='coolwarm')
plt.title('Before SMOTE')

# 过采样后
plt.subplot(1, 2, 2)
sns.scatterplot(X_resampled[:, 0], X_resampled[:, 1], hue=y_resampled, palette='coolwarm')
plt.title('After SMOTE')

plt.show()

7. 滑动窗口(Sliding Window)

核心公式

滑动窗口的目标是在时间序列数据上提取固定大小的子序列,用于捕捉局部时间特征。

核心步骤:

  1. 定义窗口大小: 设定窗口大小 w 和步长 s。

  2. 生成窗口: 对时间序列数据  ,从第 t 个时间步开始,生成子序列 X_{window}

  1. 移动窗口: 按照步长 s 移动窗口,生成下一个子序列,直到覆盖整个时间序列。

优点

  • 能有效捕捉时间序列中的局部模式或趋势。

  • 适合短期预测和时间序列特征提取。

缺点

  • 选择合适的窗口大小较为困难。

  • 对于长序列,滑动窗口生成的大量子序列可能会带来计算开销。

适用场景

  • 特别适用于时间序列预测,如股票价格预测、天气预报等。

核心案例

我们使用模拟的股票价格数据来展示滑动窗口的效果~

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

# 创建模拟的股票价格数据
np.random.seed(42)
time = np.arange(100)
price = np.sin(time / 10) + np.random.normal(scale=0.1, size=len(time))

data = pd.DataFrame({'Time': time, 'Price': price})

# 定义滑动窗口函数
def sliding_window(data, window_size):
    return np.array([data[i:i + window_size] for i in range(len(data) - window_size + 1)])

# 设置窗口大小
window_size = 10
windows = sliding_window(data['Price'], window_size)

# 可视化滑动窗口结果
plt.figure(figsize=(16, 6))
for i, window in enumerate(windows[:5]):
    plt.plot(range(i, i + window_size), window, marker='o')

plt.title('Sliding Window on Simulated Stock Price')
plt.xlabel('Time')
plt.ylabel('Price')
plt.show()

8. 插值(Interpolation)

核心公式

插值的目标是通过已知数据点估计未知数据点。常用方法包括线性插值、多项式插值和样条插值。

核心步骤:

  1. 线性插值公式: 对于两个已知数据点 (x_{1},y_{1}) 和(x_{2},y_{2}) ,插值点  x对应的  y值为:

  1. 多项式插值: 利用拉格朗日插值公式或牛顿插值公式,通过高阶多项式拟合已知数据点。

  2. 样条插值: 在每个子区间上使用低阶多项式插值,同时保证多项式在区间连接处的光滑性。

优点

  • 能有效填补缺失数据,提高数据集的完整性。

  • 多种插值方法可用于不同数据特征的拟合。

缺点

  • 插值方法过于复杂时可能引入噪声或过拟合。

  • 在外推时(即在数据范围之外进行预测),插值结果不可靠。

适用场景

  • 特别适用于有缺失值的数据,如气象数据、传感器数据。

核心案例

我们使用模拟的温度数据来展示插值的效果~

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

# 创建模拟的温度数据
np.random.seed(42)
time = np.arange(0, 100, 0.5)
temperature = np.sin(time) + np.random.normal(scale=0.1, size=len(time))

# 模拟缺失值
temperature[5:7] = np.nan

data = pd.DataFrame({'Time': time, 'Temperature': temperature})

# 线性插值
linear_interp = interp1d(data['Time'], data['Temperature'], kind='linear', fill_value="extrapolate")
time_new = np.arange(0, 100, 0.1)
temperature_linear = linear_interp(time_new)

# 可视化插值结果
plt.figure(figsize=(12, 6))
plt.plot(data['Time'], data['Temperature'], 'o', label='Original Data')
plt.plot(time_new, temperature_linear, '-', label='Linear Interpolation')
plt.title('Linear Interpolation of Simulated Temperature Data')
plt.xlabel('Time')
plt.ylabel('Temperature')
plt.legend()
plt.show()

9. 降采样(Under-sampling)

核心公式

降采样的目标是通过减少多数类样本来平衡类别分布。最简单的方法是随机采样,即从多数类中随机选择与少数类同等数量的样本。

  1. 计算多数类样本数: 假设多数类样本数为 N_{majority},少数类样本数为 N_{minority}

  2. 随机采样: 从多数类样本中随机选择  N_{minority}个样本。

优点

  • 降低数据集的不平衡性,提高分类器对少数类的识别能力。

  • 减少计算开销,适合大规模数据集。

缺点

  • 可能丢失多数类的关键信息,降低模型的整体性能。

  • 只适用于多数类样本数远多于少数类样本数的情况。

适用场景

  • 特别适用于类别严重不平衡的数据,如垃圾邮件检测、不良信用记录分析等。

核心案例

我们使用模拟的二分类不平衡数据集来展示降采样的效果~

from sklearn.datasets import make_classification
from imblearn.under_sampling import RandomUnderSampler
import matplotlib.pyplot as plt
import seaborn as sns

# 创建不平衡数据集
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0,
                           n_clusters_per_class=1, weights=[0.9, 0.1], random_state=42)

# 使用随机降采样
undersampler = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = undersampler.fit_resample(X, y)

# 可视化降采样前后的数据分布
plt.figure(figsize=(16, 6))

# 降采样前
plt.subplot(1, 2, 1)
sns.scatterplot(X[:, 0], X[:, 1], hue=y, palette='coolwarm')
plt.title('Before Under-sampling')

# 降采样后
plt.subplot(1, 2, 2)
sns.scatterplot(X_resampled[:, 0], X_resampled[:, 1], hue=y_resampled, palette='coolwarm')
plt.title('After Under-sampling')

plt.show()

10. 特征选择(Feature Selection)

核心公式

特征选择的目标是从高维数据集中选出最具代表性的一部分特征,常用方法包括过滤法(Filter)、包裹法(Wrapper)和嵌入法(Embedded)。

以过滤法中的卡方检验为例,核心步骤:

  1. 卡方检验公式: 对于每个特征 X_{i} 与标签 y 之间,计算卡方统计量:

其中 O_{i} 是观察值,E_{i} 是期望值。

  1. 特征选择: 选择卡方统计量最大的前 k 个特征。

优点

  • 减少特征数量,降低模型复杂度,防止过拟合。

  • 提高模型的泛化能力和解释性。

缺点

  • 可能丢失有用信息,影响模型性能。

  • 需要精心选择特征选择方法,适应不同的模型和数据。

适用场景

  • 特别适用于高维数据集,如文本分类、基因表达数据分析。

核心案例

我们使用Breast Cancer数据集来展示特征选择的效果

from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import SelectKBest, chi2
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 加载数据集
cancer = load_breast_cancer()
data = pd.DataFrame(cancer.data, columns=cancer.feature_names)

# 使用卡方检验选择前10个最重要的特征
selector = SelectKBest(chi2, k=10)
selector.fit(data, cancer.target)
data_selected = data.iloc[:, selector.get_support(indices=True)]

# 可视化特征选择结果
plt.figure(figsize=(12, 6))
sns.barplot(x=data.columns[selector.get_support()], y=selector.scores_[selector.get_support()])
plt.title('Top 10 Features Selected by Chi-Square Test')
plt.xlabel('Features')
plt.ylabel('Chi-Square Score')
plt.xticks(rotation=90)
plt.show()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中,数据预处理是数据分析和机器学习项目的关键步骤,它包括数据清洗、转换、规范化和特征选择等。以下是常用的一些Python数据预处理方法: 1. **数据清洗(Data Cleaning)**: - 处理缺失值:使用`pandas`库中的`dropna`、`fillna`或插补方法(如`mean`, `median`, `mode`)填充缺失值。 - 删除重复项:`duplicated` 和 `drop_duplicates`。 - 异常值检测:通过统计分析(如Z-score, IQR)或可视化找出离群值并处理。 2. **数据转换(Data Transformation)**: - 标准化/归一化:`scikit-learn`的`StandardScaler` 和 `MinMaxScaler` 对数值型数据进行标准化或归一化。 - 逻辑编码/独热编码:`pandas.get_dummies` 或 `OneHotEncoder` 对类别变量进行编码。 - 对数/指数变换:处理偏斜分布的数据。 3. **数据类型转换**: 使用`astype()` 方法将数据从一种类型转换为另一种类型,如字符串转数字。 4. **特征选择(Feature Selection)**: - 相关性分析:计算特征之间的相关系数,`corr()` 函数。 - 特征重要性:使用随机森林、梯度提升机等模型计算特征的重要性。 5. **数据切分(Data Splitting)**: - 划分训练集和测试集:`train_test_split` 函数,用于模型训练和评估。 6. **编码(Encoding)**: - 数字编码:对文本数据进行编码,如词袋模型或TF-IDF。 - 文本预处理:去除停用词、标点符号,进行词干提取或词形还原。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值