机器学习——数据清洗之处理缺失值

目录

一、处理缺失值

删除(Drop)

填充(Imputation)

使用专门的插补方法

特征工程

使用特定库的功能

二、代码示例 

 主函数

处理缺失值函数

 1.删除含有缺失值的记录(行)

2.平均值填充

3.中位数填充

4.众数填充

 5.逻辑回归

6.随机森林


一、处理缺失值

处理数据集中的缺失值是数据清洗的重要组成部分,缺失值的存在会影响数据分析和机器学习模型的准确性和性能。缺失值处理的方法取决于缺失值的性质和数据集的具体情况。以下是一些常见的处理缺失值的策略:

  1. 删除(Drop)

    • 删除带有缺失值的行:如果数据集足够大,且缺失值的行占比不大,可以考虑直接删除这些行。但是,这可能会导致信息损失,尤其是在缺失值比例较高的情况下。
    • 删除带有缺失值的列:如果某列的缺失值过多,而这一列又不是特别关键,可以考虑删除整个列。
  2. 填充(Imputation)

    • 平均值/中位数/众数填充:对于数值型数据,可以用列的均值、中位数或众数填充缺失值。
    • 基于模型的预测:可以使用其他特征或外部数据预测缺失值,例如使用回归模型、决策树、随机森林或其他机器学习模型。
    • KNN 插补:使用 K 近邻算法来预测缺失值。
    • 基于业务逻辑的填充:根据领域知识或业务逻辑来推测合理的值填充。
  3. 使用专门的插补方法

    • 多重插补(Multiple Imputation):这是一种统计学方法,通过多次随机抽样生成多个数据集,然后对每个数据集进行分析,最后汇总结果。
  4. 特征工程

    • 创建指示变量:可以为缺失值创建一个新的二进制特征,表示该特征是否存在缺失值。
    • 预测模型:构建一个单独的模型来预测缺失值,这可以是一个回归或分类模型,取决于缺失值的类型。
  5. 使用特定库的功能

    • 在 Python 的 pandas 库中,可以使用 fillna() 方法填充缺失值。
    • 在 scikit-learn 中,可以使用 SimpleImputer 类来处理缺失值,支持多种填充策略。

在选择处理缺失值的方法时,需要考虑缺失值的模式(MCAR, MAR, MNAR)和数据集的特点。例如,如果缺失值是随机的(Missing Completely At Random,MCAR),那么删除带有缺失值的记录可能是一个合理的选择。然而,如果缺失值的出现与某个未观察的变量有关(Missing Not At Random,MNAR),则需要更复杂的处理策略,如多重插补或预测模型。

处理缺失值的目标是尽可能减少信息损失,同时避免引入偏差。因此,在实际操作中,可能需要结合多种方法,并根据实际情况灵活选择最合适的策略。下面我会展示删除和填充的代码示例。

二、代码示例 

 主函数

import pandas as pd
import matplotlib.pyplot as plt
import fill_data

data = pd.read_excel("矿物数据.xls")
data = data[data['矿物类型'] != 'E']#删除特殊的类别E。整个数据集中只存在1个E数据。
null_num = data.isnull()
#.isnull()会返回一个相同形状的DataFrame,但其中的元素是布尔值(True或False)。
# 如果原始DataFrame中的某个位置是缺失值(通常是NaN,即“Nota Number”),
# 则对应位置在返回的DataFrame中会被标记为True;否则,标记为False。
# #注:还有空自处也是nan,isnull未包含空自处。
null_total = null_num.sum()#检测每列中的缺失值

X_whole = data.drop('矿物类型',axis=1).drop('序号',axis=1)#获取全部特征数据
y_whole = data.矿物类型                               #获取全部标签数据

label_dict = {"A":0,"B":1,"C":2,"D":3}#将数据中的中文标签转换为字符
encoded_labels = [label_dict[label] for label in y_whole]
y_whole = pd.Series(encoded_labels,name='矿物类型')#将列表转换为Pandas Series

for column_name in X_whole.columns:
    X_whole[column_name]= pd.to_numeric(X_whole[column_name], errors='coerce')

"""数据标准化:Z标准化"""
from sklearn.preprocessing import StandardScaler
scaler =StandardScaler()
X_whole_Z= scaler.fit_transform(X_whole)
X_whole = pd.DataFrame(X_whole_Z,columns=X_whole.columns)#

"""数据集的切分"""
from sklearn.model_selection import train_test_split
x_train_w,x_test_w,y_train_w,y_test_w=train_test_split(X_whole,y_whole,test_size = 0.3,random_state = 50000)

"""数据存在空缺,进行填充"""
#1.只保留完整数据集
# x_train_fill,y_train_fill = fill_data.cca_train_fill(x_train_w,y_train_w)#
# x_test_fill,y_test_fill = fill_data.cca_test_fill(x_train_fill,y_train_fill,x_test_w,y_test_w)

# 2、使用平均值的方法对数据进行填充
# x_train_fill,y_train_fill = fill_data.mean_train_fill(x_train_w,y_train_w)
# #测试集的填充
# x_test_fill,y_test_fill = fill_data.mean_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)

#3、使用中位数的方法对数据进行填充
x_train_fill,y_train_fill = fill_data.median_train_fill(x_train_w,y_train_w)
#测试集的填充
x_test_fill,y_test_fill = fill_data.median_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)

# 4、使用众数的方法对数据进行填充
# x_train_fill,y_train_fill = fill_data.mode_train_fill(x_train_w,y_train_w)
# #测试集的填充
# x_test_fill,y_test_fill = fill_data.mode_test_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)

#5.逻辑回归
# x_train_fill,y_train_fill = fill_data.lr_train_fill(x_train_w,y_train_w)
# #测试集的填充
# x_test_fill,y_test_fill = fill_data.lr_text_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)

#6.随机森林
# x_train_fill,y_train_fill = fill_data.rf_train_fill(x_train_w,y_train_w)
# #测试集的填充
# x_test_fill,y_test_fill = fill_data.rf_text_fill(x_train_fill, y_train_fill, x_test_w, y_test_w)

'''smote算法实现数据集的拟合'''
from imblearn.over_sampling import SMOTE
oversampler = SMOTE(k_neighbors=1,random_state=42)
os_x_train, os_y_train = oversampler.fit_resample(x_train_fill,y_train_fill)#

# 绘制每个类别的数据个数图
y_whole = pd.concat([os_y_train,y_test_fill])
labels_count = pd.value_counts(y_whole)#统计data['矿物类型']中每类的个数
fig, ax = plt.subplots()# 创建一个条形图
bars = ax.bar(labels_count.index,labels_count.values)# 绘制条形图
for bar in bars:    # 遍历每个条形
    yval = bar.get_height()#用于获取条形图 中某个具体条形的高度
    # 在条形上添加文本,使用bar.get_x() + bar.get_width() / 2获取条形的中心
    ax.text(bar.get_x() + bar.get_width() / 2, yval,
            round(yval, 2),  # 你可以在这里选择保留的小数位数
            va='bottom',  # 垂直对齐
            ha='center',  # 水平对齐
            fontsize=10,  # 字体大小
            color='black')  # 字体颜色
plt.xlabel('lables')
p
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值