哈喽,我是cos大壮!~
今儿和大家再聊聊算法模型集合中的数据清洗方法,这部分对于算法模型的训练来说,至关重要!
数据清洗是确保数据质量的关键步骤,能够消除噪声和错误,从而提高分析结果的准确性。良好的数据清洗方法能够增强模型的性能,减少过拟合和欠拟合的风险。通过系统化的数据清洗,可以节省后续分析和建模的时间,提高整体工作效率。
方法非常多,本篇文章给大家找出十个最重要、最常用的数据清洗方法:
缺失值处理 异常值处理 重复数据移除 数据一致性处理 数据归一化/标准化 数据离散化 类别不平衡处理 文本数据清洗 数据类型转换 特征工程
1. 缺失值处理
原理
缺失值处理是指在数据集中存在空值或缺失数据的情况下,通过合适的策略填补或处理这些缺失值,以减少对后续分析和模型训练的影响。常见的缺失值处理方法包括删除缺失值、均值填补、中位数填补、众数填补和插值法。
核心公式
1. 均值填补:
其中 为均值, 为有效观测值的数量。
2. 中位数填补:
中位数是数据集中间的值,避免极端值影响。
优缺点
优点:
可保持数据集的大小,减少数据丢失。 使用简单的统计方法进行填补,便于实现。 缺点:
可能引入偏差,尤其是当缺失值不是随机缺失时。 对数据分布的影响可能导致模型性能下降。
适用场景
数据集较小,且缺失值较少。 缺失值的缺失机制已知且为随机缺失。
核心案例代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 创建一个示例数据集
data = {
'Age': [25, np.nan, 30, 22, np.nan, 35],
'Salary': [50000, 60000, np.nan, 52000, 49000, np.nan]
}
df = pd.DataFrame(data)
# 缺失值处理:使用均值填补
df['Age'].fillna(df['Age'].mean(), inplace=True)
df['Salary'].fillna(df['Salary'].mean(), inplace=True)
# 数据分析:绘制直方图和箱线图
plt.figure(figsize=(10, 6))
# 绘制直方图
plt.subplot(1, 2, 1)
sns.histplot(df['Age'], bins=5, color='blue', kde=True)
plt.title('Age Distribution After Imputation')
plt.xlabel('Age')
plt.ylabel('Frequency')
# 绘制箱线图
plt.subplot(1, 2, 2)
sns.boxplot(x=df['Salary'], color='orange')
plt.title('Salary Boxplot After Imputation')
plt.xlabel('Salary')
plt.tight_layout()
plt.show()
直方图: 展示填补后年龄的分布,帮助判断填补方法是否合理。理想情况下,数据应呈现出自然的分布形态。 箱线图: 检查填补后的薪水数据分布及异常值,提供关于薪水变异的信息,理想情况下,箱体应该集中且无显著的离群点。
2. 异常值处理
原理
异常值处理是指识别并处理那些与其他数据点显著不同的观测值。异常值可能是数据录入错误、测量错误或实际存在的极端现象。常见的处理方法包括 z-score、IQR(四分位距)法和基于模型的方法(如孤立森林)。
核心公式
1. Z-score:
其中 为均值, 为标准差。当 时,通常认为是异常值。
2. IQR:
异常值的定义:小于 或大于 的值为异常值。
优缺点
优点:
有效地识别并处理潜在的噪声数据。 Z-score 和 IQR 方法简单易懂,且不需要假设数据分布。 缺点:
对于多维数据,单一维度的异常值检测可能会遗漏整体的异常。 对于具有大量异常值的数据,可能会误判。
适用场景
需要清理数据以提高模型性能。 数据集存在明显的极端值时。
核心案例代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 生成一个包含异常值的示例数据集
data = {
'Value': [10, 12, 12, 13, 12, 11, 100, 12, 11, 10, 12, 13, 11, 9, 300]
}
df = pd.DataFrame(data)
# 计算IQR
Q1 = df['Value'].quantile(0.25)
Q3 = df['Value'].quantile(0.75)
IQR = Q3 - Q1
# 检测异常值
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
df['Outlier'] = ((df['Value'] < lower_bound) | (df['Value'] > upper_bound))
# 数据分析:绘制箱线图和散点图
plt.figure(figsize=(12, 6))
# 绘制箱线图
plt.subplot(1, 2, 1)
sns.boxplot(x=df['Value'], color='lightgreen')
plt.title('Boxplot of Values')
plt.xlabel('Value')
# 绘制散点图
plt.subplot(1, 2, 2)
sns.scatterplot(x=df.index, y='Value', hue='Outlier', data=df, palette={True: 'red', False: 'blue'})
plt.title('Scatter Plot of Values with Outliers')
plt.xlabel('Index')
plt.ylabel('Value')
plt.tight_layout()
plt.show()
箱线图: 展示数据的分布和异常值的情况,箱体外的点即为异常值,帮助快速识别数据中的极端点。 散点图: 通过不同颜色标识出异常值和正常值,提供了更直观的异常值分布情况,便于观察其在数据集中的位置。
3. 重复数据移除
原理
重复数据移除是通过识别数据集中相同的记录,避免分析中出现信息冗余,确保数据集的唯一性。重复数据通常通过查找完全相同的行或部分相同的特征来检测。
优缺点
优点:
消除冗余,提高数据集的质量。 降低内存使用和计算开销。 缺点:
在某些情况下,重复数据可能有其存在的价值(如交易记录)。 删除操作需谨慎,避免误删除有用的信息。
适用场景
数据集在数据收集过程中容易产生重复记录。 数据预处理阶段需要清理以提高数据质量。
核心案例代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 创建一个包含重复数据的示例数据集
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'Alice', 'David', 'Bob'],
'Age': [25, 30, 35, 25, 40, 30],
'Salary': [50000, 60000, 70000, 50000, 80000, 60000]
}
df = pd.DataFrame(data)
# 移除重复数据
df_unique = df.drop_duplicates()
# 数据分析:绘制条形图和饼图
plt.figure(figsize=(12, 6))
# 绘制条形图
plt.subplot(1, 2, 1)
sns.countplot(x='Name', data=df, palette='viridis')
plt.title('Count of Names (Before Removing Duplicates)')
plt.xlabel('Name')
plt.ylabel('Count')
# 绘制饼图
plt.subplot(1, 2, 2)
df_unique['Name'].value_counts().plot.pie(autopct='%1.1f%%', startangle=90, colors=sns.color_palette("pastel"))
plt.title('Proportion of Unique Names (After Removing Duplicates)')
plt.ylabel('')
plt.tight_layout()
plt.show()
条形图: 显示重复数据前每个名字的出现频率,便于观察哪些数据重复。 饼图: 展示去重后每个唯一名字的比例,帮助判断数据的分布及集中情况。
4. 数据一致性处理
原理
数据一致性处理是指确保数据在不同记录之间保持一致性,特别是在涉及多个数据源时。通过标准化字段格式、验证数据范围和逻辑关系来处理。
优缺点
优点:
提高数据的可靠性和准确性。 降低数据处理过程中的错误。 缺点:
一致性检查需要较多的时间和计算资源。 可能会导致数据丢失(在标准化时)。
适用场景
合并多个数据源时,需要确保数据的统一性。 进行数据分析时,需要确保数据的准确性。
核心案例代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 创建一个示例数据集
data = {
'ID': [1, 2, 3, 4],
'Date': ['2024-01-01', '01/02/2024', '2024-03-01', 'March 4, 2024'],
'Salary': [50000, '60000$', '70000', 80000.0]
}
df = pd.DataFrame(data)
# 数据一致性处理:统一日期格式和薪资格式
df['Date'] = pd.to_datetime(df['Date'], errors='coerce').dt.strftime('%Y-%m-%d')
df['Salary'] = df['Salary'].replace({'\$': '', ' ': ''}, regex=True).astype(float)
# 数据分析:绘制条形图和折线图
plt.figure(figsize=(12, 6))
# 绘制条形图
plt.subplot(1, 2, 1)
sns.barplot(x=df['ID'], y=df['Salary'], palette='rocket')
plt.title('Salaries by ID (After Consistency Check)')
plt.xlabel('ID')
plt.ylabel('Salary')
# 绘制折线图
plt.subplot(1, 2, 2)
plt.plot(df['ID'], df['Salary'], marker='o', linestyle='-', color='purple')
plt.title('Salary Trend by ID (After Consistency Check)')
plt.xlabel('ID')
plt.ylabel('Salary')
plt.tight_layout()
plt.show()
条形图: 显示一致性处理后每个 ID 对应的薪资,帮助观察数据清洗后的结果。 折线图: 展示薪资随 ID 的变化趋势,提供了薪资变化的清晰视图。
5. 数据归一化/标准化
原理
数据归一化和标准化是通过将数据缩放到特定范围(如[0, 1])或调整为均值为0、标准差为1来处理不同量纲和范围的特征,以提高模型的训练效果。
核心公式
1. 归一化(Min-Max Scaling):
2. 标准化(Z-score Scaling):
优缺点
优点:
消除特征量纲影响,提高模型的收敛速度。 适用于大多数机器学习算法,尤其是基于距离的算法。 缺点:
对于有异常值的数据,归一化可能会导致极端值对结果的影响增大。 需要对每个特征单独处理,计算成本较高。
适用场景
特征值范围差异较大时。 使用需要计算距离的算法(如 KNN、SVM)时。
核心案例代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 创建一个示例数据集
data = {
'Height': [150, 160, 170, 180, 190],
'Weight': [50, 60, 70, 80, 90]
}
df = pd.DataFrame(data)
# 数据归一化
df_normalized = (df - df.min()) / (df.max() - df.min())
# 数据分析:绘制散点图和热力图
plt.figure(figsize=(12, 6))
# 绘制散点图
plt.subplot(1, 2, 1)
sns.scatterplot(x=df_normalized['Height'], y=df_normalized['Weight'], color='cyan', s=100)
plt.title('Normalized Height vs Weight')
plt.xlabel('Normalized Height')
plt.ylabel('Normalized Weight')
# 绘制热力图
plt.subplot(1, 2, 2)
sns.heatmap(df_normalized.corr(), annot=True, cmap='coolwarm', center=0)
plt.title('Correlation Heatmap of Normalized Data')
plt.tight_layout()
plt.show()
散点图: 显示归一化后身高与体重的关系,便于观察特征之间的相关性。 热力图: 展示归一化后特征间的相关性,帮助识别潜在的多重共线性问题。
6. 数据离散化
原理
数据离散化是将连续特征转换为离散特征的过程,以便在分类问题中提高模型的效果。常用方法包括分箱(Bin)和聚类。
核心公式
1. 等宽离散化:
其中 。
2. 等频离散化:将数据分为 个频率相同的区间。
优缺点
优点:
转换后的离散特征更易于解释和理解。 可以提高某些算法(如决策树)的效果。 缺点:
可能导致信息损失,特别是连续性数据中的细节。 选择分箱数和方法需要谨慎,影响模型性能。
适用场景
在分类问题中使用,需要将连续特征转换为类别特征。 数据分析时需要对数据进行分组处理。
核心案例代码
# 创建一个示例数据集
data = {
'Score': [58, 73, 80, 90, 55, 88, 66, 74, 99, 61]
}
df = pd.DataFrame(data)
# 数据离散化:等宽分箱
bins = [0, 60, 70, 80, 90, 100]
labels = ['F', 'D', 'C', 'B', 'A']
df['Grade'] = pd.cut(df['Score'], bins=bins, labels=labels, right=False)
# 数据分析:绘制条形图和饼图
plt.figure(figsize=(12, 6))
# 绘制条形图
plt.subplot(1, 2, 1)
sns.countplot(x='Grade', data=df, palette='pastel')
plt.title('Grade Distribution After Discretization')
plt.xlabel('Grade')
plt.ylabel('Count')
# 绘制饼图
plt.subplot(1, 2, 2)
df['Grade'].value_counts().plot.pie(autopct='%1.1f%%', startangle=90, colors=sns.color_palette("pastel"))
plt.title('Proportion of Grades After Discretization')
plt.ylabel('')
plt.tight_layout()
plt.show()
条形图: 显示不同等级的分布情况,便于观察离散化效果。 饼图: 展示等级的比例分布,提供各等级的相对权重。
7. 类别不平衡处理
原理
类别不平衡处理用于解决分类问题中某一类别的样本数量显著少于其他类别的问题。常见的方法包括上采样、下采样、SMOTE(合成少数类过采样技术)等。
优缺点
优点:
改善分类器的性能,提高对少数类的识别率。 可通过多种方法灵活实现,易于适应不同数据集。 缺点:
上采样可能导致过拟合,下采样可能导致信息损失。 SMOTE 对于特征分布的假设可能不适用。
适用场景
分类任务中存在显著的类别不平衡时。 需要提高模型的精确度和召回率。
核心案例代码
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
# 创建一个类别不平衡的数据集
X, y = make_classification(n_classes=2, class_sep=2,
weights=[0.9, 0.1], n_informative=3,
n_redundant=1, flip_y=0,
n_features=20, n_clusters_per_class=1,
n_samples=1000, random_state=10)
# 处理类别不平衡:使用SMOTE
sm = SMOTE(random_state=42)
X_res, y_res = sm.fit_resample(X, y)
# 数据分析:绘制条形图和散点图
plt.figure(figsize=(12, 6))
# 绘制条形图
plt.subplot(1, 2, 1)
sns.countplot(x=y, palette='pastel')
plt.title('Class Distribution Before SMOTE')
plt.xlabel('Class')
plt.ylabel('Count')
# 绘制散点图
plt.subplot(1, 2, 2)
sns.scatterplot(x=X_res[:, 0], y=X_res[:, 1], hue=y_res, palette='deep')
plt.title('Scatter Plot After SMOTE')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.tight_layout()
plt.show()
条形图: 显示 SMOTE 前后类分布情况,便于观察类别不平衡。 散点图: 展示 SMOTE 后的特征分布,帮助理解合成样本的效果。
8. 文本数据清洗
原理
文本数据清洗是指在进行文本分析前,对原始文本数据进行处理,以去除噪声、统一格式和提取有用信息。处理步骤包括去除标点、转小写、去除停用词和词干提取等。
优缺点
优点:
提高文本数据的质量,增强后续分析的准确性。 提升模型在文本分类和情感分析等任务中的性能。 缺点:
清洗过程需谨慎,错误的处理可能导致信息丢失。 停用词的选择可能影响特定领域的分析效果。
适用场景
需要进行文本分类、情感分析或主题建模时。 大量原始文本数据需要预处理的场景。
核心案例代码
import re
from sklearn.feature_extraction.text import CountVectorizer
# 创建一个示例文本数据集
documents = [
"I love programming in Python! It's amazing.",
"Python is great for data science, but R is also good.",
"I hate debugging. It's frustrating!",
"Data analysis with Python and R is very popular."
]
# 文本数据清洗
def clean_text(text):
text = text.lower() # 转小写
text = re.sub(r'[^\w\s]', '', text) # 去除标点
return text
cleaned_documents = [clean_text(doc) for doc in documents]
# 文本分析:词频统计
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(cleaned_documents)
word_counts = X.toarray().sum(axis=0)
# 数据分析:绘制条形图和词云图
plt.figure(figsize=(12, 6))
# 绘制条形图
plt.subplot(1, 2, 1)
sns.barplot(x=vectorizer.get_feature_names_out(), y=word_counts, palette='magma')
plt.title('Word Frequency')
plt.xlabel('Words')
plt.ylabel('Count')
plt.xticks(rotation=45)
# 绘制词云图
from wordcloud import WordCloud
wordcloud = WordCloud(width=400, height=200, background_color='white').generate_from_frequencies(dict(zip(vectorizer.get_feature_names_out(), word_counts)))
plt.subplot(1, 2, 2)
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title('Word Cloud')
plt.tight_layout()
plt.show()
条形图: 展示清洗后文本的词频,帮助识别常用词汇。 词云图: 直观展示词频,频率越高的词越大,便于快速理解文本特征。
9. 数据类型转换
原理
数据类型转换是指将数据集中的数据类型进行转换,以便更好地适应后续的数据分析和建模过程。常见的转换包括数值型转类别型、日期型转换等。
优缺点
优点:
提高数据集的可用性,便于后续分析。 确保数据类型与模型要求一致。 缺点:
错误的转换可能导致数据丢失或误判。 需要对每个字段的类型进行合理判断。
适用场景
数据预处理阶段,需要将数据格式转换为适合模型的类型。 数据分析中需要对日期进行处理的场景。
核心案例代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 创建一个示例数据集
data = {
'Date': ['2024-01-01', '2024-01-02', '2024-01-03'],
'Value': ['100', '200.5', '300']
}
df = pd.DataFrame(data)
# 数据类型转换
df['Date'] = pd.to_datetime(df['Date'])
df['Value'] = df['Value'].astype(float)
# 数据分析:绘制折线图和条形图
plt.figure(figsize=(12, 6))
# 绘制折线图
plt.subplot(1, 2, 1)
plt.plot(df['Date'], df['Value'], marker='o', color='skyblue')
plt.title('Value Over Time')
plt.xlabel('Date')
plt.ylabel('Value')
# 绘制条形图
plt.subplot(1, 2, 2)
sns.barplot(x=df['Date'], y=df['Value'], palette='viridis')
plt.title('Bar Plot of Values by Date')
plt.xlabel('Date')
plt.ylabel('Value')
plt.tight_layout()
plt.show()
折线图: 展示数值随时间的变化趋势,便于观察时间序列数据的动态特征。 条形图: 显示每个日期对应的数值,帮助识别单个日期的值。
10. 特征工程
原理
特征工程是指通过提取、选择和转换特征来提高模型性能的过程。这一过程可以包括特征选择、特征提取和特征构造。
优缺点
优点:
提高模型的表现,增强模型的可解释性。 可以利用领域知识提取有意义的特征。 缺点:
特征工程过程可能非常耗时。 需要领域知识以确保选取的特征对任务有帮助。
适用场景
数据分析和建模过程中,需提取有意义的特征。 需要提高模型预测准确性时。
核心案例代码
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
# 加载California Housing数据集
data = fetch_california_housing()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
# 特征工程:构造多项式特征
poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(X)
# 建立线性回归模型
model = LinearRegression()
model.fit(X_poly, y)
# 数据分析:绘制实际 vs 预测图和特征重要性图
plt.figure(figsize=(12, 6))
# 绘制实际 vs 预测图
plt.subplot(1, 2, 1)
plt.scatter(y, model.predict(X_poly), alpha=0.5)
plt.plot([y.min(), y.max()], [y.min(), y.max()], color='red', linestyle='--')
plt.title('Actual vs Predicted Prices')
plt.xlabel('Actual Prices')
plt.ylabel('Predicted Prices')
# 绘制特征重要性图
importance = model.coef_
plt.subplot(1, 2, 2)
sns.barplot(x=importance, y=poly.get_feature_names_out(), palette='viridis')
plt.title('Feature Importance from Polynomial Regression')
plt.xlabel('Importance')
plt.tight_layout()
plt.show()
实际 vs 预测图: 通过散点图展示实际值与预测值的关系,理想情况下应接近对角线。 特征重要性图: 显示各特征在多项式回归中的重要性,帮助理解特征的贡献。
最后
大家有问题可以直接在评论区留言即可~
推荐阅读
原创、超强、精华合集 100个超强机器学习算法模型汇总 机器学习全路线 机器学习各个算法的优缺点 7大方面,30个最强数据集 6大部分,20 个机器学习算法全面汇总 铁汁,都到这了,别忘记点赞呀~