目录

一、处理缺失值

删除(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')
plt.ylabel('numbers')
plt.title('The number of data for each category after removing empty data')
plt.show()# 显示图形

'''数据保存为excel文件'''
data_train = pd.concat([os_y_train,os_x_train],axis=1).sample(frac=1, random_state=4)#sample()方法用于DatoFrgme中賄机热
data_test = pd.concat([y_test_fill,x_test_fill],axis=1)#测试集不用传入模型训练,无需打乱顺序。

data_train.to_excel(r'temp_data//训练数据集[中位数填充].xlsx',index=False)
data_test.to_excel(r'temp_data//测试数据集[中位数填充].xlsx',index=False)

 

  1. 使用 pandas 的 read_excel 函数从 Excel 文件 "矿物数据.xls" 中读取数据到 DataFrame data

  2. 删除数据中特殊类别的记录,这里删除的是 'E' 类别,因为数据集中只有一个这样的记录。

  3. 使用 .isnull() 方法检测数据中的缺失值,返回一个布尔 DataFrame。

  4. 对每列的缺失值进行计数,存储在 null_total 变量中。

  5. 从数据中移除 '矿物类型' 和 '序号' 这两列,剩余的列为特征数据 X_whole

  6. 提取 '矿物类型' 列作为标签数据 y_whole

  7. 创建一个字典 label_dict,将 'A', 'B', 'C', 'D' 四种类型的矿物映射到整数标签。

  8. y_whole 中的矿物类型转换成对应的整数标签,并将结果存储回 y_whole

  9. 遍历 X_whole 的每一列,将非数值数据强制转换为数值数据,无法转换的会被设为 NaN。

  10. 使用 StandardScaler 对特征数据进行 Z-score 标准化,即减去均值并除以标准差。

  11. 使用 fit_transform 方法拟合并转换特征数据 X_whole,然后将其转换回 DataFrame 形式。

  12. 使用 train_test_split 函数将数据集分为训练集和测试集,其中测试集占总数据集的 30%,并设置随机种子以保证结果的可复现性。

  13. 调用 fill_data.lr_train_fillfill_data.lr_text_fill 函数来填充训练集和测试集中的缺失值。这通常意味着使用某种策略(如中位数填充)来填补缺失数据。

  14. 引入 SMOTE 算法,这是一种过采样技术,用于处理分类问题中数据不平衡的情况。k_neighbors 参数控制了用来生成新样本的最近邻数量,random_state 设定随机种子确保结果可复现。

  15. 使用 fit_resample 方法应用 SMOTE 算法来增加少数类的样本数量,从而平衡数据集。os_x_trainos_y_train 分别是经过 SMOTE 处理后的特征和标签。

  16. 统计并绘制处理后各类别数据的数量。首先将训练集和测试集的标签合并,然后计算每个类别的数量。接着创建一个条形图并为每个条形添加数值标签,最后显示图形。

  17. 将处理后的训练数据和测试数据保存为 Excel 文件。训练数据先通过 sample 方法进行随机排序,这是为了避免模型训练时可能存在的顺序效应;而测试数据则保持原样,因为它不会用于模型训练

处理缺失值函数

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

import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor

'''----------------删除空数据行---------------------------------'''
def cca_train_fill(train_data,train_label):
    data = pd.concat([train_data, train_label], axis = 1)
    data = data.reset_index(drop=True)
    df_filled = data.dropna()
    return df_filled.drop('矿物类型', axis=1), df_filled.矿物类型

def cca_test_fill(train_data,train_label,test_data,test_label):
    data = pd.concat([test_data, test_label], axis = 1)
    data = data.reset_index(drop=True)
    df_filled = data.dropna()
    return df_filled.drop('矿物类型', axis=1), df_filled.矿物类型


cca_train_fill 函数

这个函数接收训练数据 (train_data) 和对应的训练标签 (train_label) 作为输入参数。它执行以下操作:

  1. 使用 pd.concat 将特征数据和标签数据按列合并成一个新的 DataFrame。
  2. 调用 reset_index 方法重置 DataFrame 的索引,丢弃旧的索引,并创建新的默认整数索引。
  3. 使用 dropna 方法删除包含任何 NaN 或缺失值的行。
  4. 最后,函数返回两个值:一个是不包含 '矿物类型' 列的处理后的特征数据,另一个是处理后的标签数据(即 '矿物类型' 列)。

cca_test_fill 函数

这个函数与 cca_train_fill 类似,但处理的是测试数据和标签。它同样接收数据和标签,执行相同的合并、索引重置和缺失值删除步骤,然后返回处理后的测试特征数据和测试标签数据。

2.平均值填充

def mean_train_method(data):
    '''平均值的计算方法'''
    fill_values = data.mean()
    return data.fillna(fill_values)# 使用均值填充缺失值,pandas读取表格数据,数据清洗。

def mean_train_fill(train_data,train_label):
    '''使用平均值的方法对数据进行填充'''
    data = pd.concat([train_data, train_label], axis=1)
    data = data.reset_index(drop=True)
    A = data[data['矿物类型'] == 0]
    B = data[data['矿物类型'] == 1]
    C = data[data['矿物类型'] == 2]
    D = data[data['矿物类型'] == 3]

    A = mean_train_method(A)  # ,按照每个类别的数据进行填充
    B = mean_train_method(B)  # 按照每个类别的数据进行填充
    C = mean_train_method(C)  # ,按照每个类别的数据进行填充
    D = mean_train_method(D)  # 按照每个类别的数据进行填充

    df_filled = pd.concat([A, B, C, D])
    df_filled = df_filled.reset_index(drop=True)
    return df_filled.drop('矿物类型', axis=1), df_filled.矿物类型

def mean_test_method(train_data, test_data):
    '''根据训练集获取每个类别的平均值,并将训练集的每个类别平均值填充到测试中'''
    fill_values = train_data.mean()
    return test_data.fillna(fill_values)# 使用均值填充缺失值

def mean_test_fill(train_data,train_label, test_data,test_label):
    '''使用平均值的方法对数据进行填充'''
    train_data_all = pd.concat([train_data, train_label], axis = 1)
    train_data_all = train_data_all.reset_index(drop=True)
    test_data_all = pd.concat([test_data, test_label],axis = 1)
    test_data_all = test_data_all.reset_index(drop=True)

    A_train = train_data_all[train_data_all['矿物类型']== 0]
    B_train = train_data_all[train_data_all['矿物类型']== 1]
    C_train = train_data_all[train_data_all['矿物类型']== 2]
    D_train = train_data_all[train_data_all['矿物类型']== 3]

    A_test = test_data_all[test_data_all['矿物类型'] == 0]
    B_test = test_data_all[test_data_all['矿物类型'] == 1]
    C_test = test_data_all[test_data_all['矿物类型'] == 2]
    D_test = test_data_all[test_data_all['矿物类型'] == 3]

    A = mean_test_method(A_train,A_test)
    B = mean_test_method(B_train,B_test)
    C = mean_test_method(C_train,C_test)
    D = mean_test_method(D_train,D_test)

    df_filled = pd.concat([A,B,C,D])
    df_filled = df_filled.reset_index(drop=True)
    return df_filled.drop('矿物类型',axis = 1),df_filled.矿物类型

mean_train_method 函数

这个函数计算给定数据集所有数值列的平均值,并使用这些平均值来填充数据集中的缺失值。

mean_train_fill 函数

此函数首先将训练数据和标签数据合并,然后根据不同的 '矿物类型' 类别分割数据。对于每一个类别,它都会调用 mean_train_method 函数来计算该类别的平均值,并使用这些平均值填充该类别数据中的缺失值。最终,它会将所有处理过的数据段合并,并返回处理后的特征数据和标签数据。

mean_test_method 函数

这个函数接受训练数据和测试数据作为参数。它首先计算训练数据的平均值,然后使用这些平均值来填充测试数据中的缺失值。

mean_test_fill 函数

此函数首先分别将训练数据和测试数据与各自的标签数据合并,然后根据不同的 '矿物类型' 类别分割训练数据和测试数据。接下来,它为每一种类别调用 mean_test_method 函数,使用训练数据的平均值来填充相应测试数据类别中的缺失值。最后,它将所有处理过的测试数据段合并,并返回处理后的特征数据和标签数据。

3.中位数填充

'''-----------------------使用中位数的方法对数据进行填充-----------------'''
def median_train_method(data):
    '''平均值的计算方法'''
    fill_values = data.median()
    return data.fillna(fill_values)# 使用均值填充缺失值,pandas读取表格数据,数据清洗。

def median_train_fill(train_data,train_label):
    '''使用平均值的方法对数据进行填充'''
    data = pd.concat([train_data, train_label], axis=1)
    data = data.reset_index(drop=True)
    A = data[data['矿物类型'] == 0]
    B = data[data['矿物类型'] == 1]
    C = data[data['矿物类型'] == 2]
    D = data[data['矿物类型'] == 3]

    A = median_train_method(A)  # ,按照每个类别的数据进行填充
    B = median_train_method(B)  # 按照每个类别的数据进行填充
    C = median_train_method(C)  # ,按照每个类别的数据进行填充
    D = median_train_method(D)  # 按照每个类别的数据进行填充

    df_filled = pd.concat([A, B, C, D])
    df_filled = df_filled.reset_index(drop=True)
    return df_filled.drop('矿物类型', axis=1), df_filled.矿物类型

def median_test_method(train_data, test_data):
    '''根据训练集获取每个类别的平均值,并将训练集的每个类别平均值填充到测试中'''
    fill_values = train_data.median()
    return test_data.fillna(fill_values)# 使用均值填充缺失值

def median_test_fill(train_data,train_label, test_data,test_label):
    '''使用平均值的方法对数据进行填充'''
    train_data_all = pd.concat([train_data, train_label], axis = 1)
    train_data_all = train_data_all.reset_index(drop=True)
    test_data_all = pd.concat([test_data, test_label],axis = 1)
    test_data_all = test_data_all.reset_index(drop=True)

    A_train = train_data_all[train_data_all['矿物类型']== 0]
    B_train = train_data_all[train_data_all['矿物类型']== 1]
    C_train = train_data_all[train_data_all['矿物类型']== 2]
    D_train = train_data_all[train_data_all['矿物类型']== 3]

    A_test = test_data_all[test_data_all['矿物类型'] == 0]
    B_test = test_data_all[test_data_all['矿物类型'] == 1]
    C_test = test_data_all[test_data_all['矿物类型'] == 2]
    D_test = test_data_all[test_data_all['矿物类型'] == 3]

    A = median_test_method(A_train,A_test)
    B = median_test_method(B_train,B_test)
    C = median_test_method(C_train,C_test)
    D = median_test_method(D_train,D_test)

    df_filled = pd.concat([A,B,C,D])
    df_filled = df_filled.reset_index(drop=True)
    return df_filled.drop('矿物类型',axis = 1),df_filled.矿物类型

median_train_method 函数

此函数接收一个 DataFrame 数据,并计算所有数值列的中位数。然后,它使用这些中位数值来填充 DataFrame 中的缺失值。

median_train_fill 函数

这个函数首先将训练数据和标签数据合并,并根据不同的 '矿物类型' 分类数据。对于每一种类型的数据,它都会调用 median_train_method 函数,使用该类别的中位数来填充缺失值。之后,它将所有处理过的数据段重新组合,然后返回特征数据(去除 '矿物类型' 列)和标签数据。

median_test_method 函数

此函数接收训练数据和测试数据作为参数。它计算训练数据的中位数,并使用这些中位数值来填充测试数据中的缺失值。

median_test_fill 函数

此函数首先将训练数据和测试数据分别与各自的标签数据合并。然后,它根据 '矿物类型' 对训练数据和测试数据进行分类。接下来,它为每一种类型调用 median_test_method 函数,使用训练数据的中位数来填充测试数据中相应类别的缺失值。最后,它将所有处理过的测试数据段重新组合,并返回特征数据(去除 '矿物类型' 列)和标签数据。

4.众数填充

'''-----------------------使用众数的方法对数据进行填充-----------------'''
def mode_train_method(data):
    '''平均值的计算方法'''
    fill_values = data.apply(lambda x: x.mode().iloc[0] if len(x.mode()) > 0 else None)
    a = data.mode()
    return data.fillna(fill_values)# 使用均值填充缺失值,pandas读取表格数据,数据清洗。

def mode_train_fill(train_data,train_label):
    '''使用平均值的方法对数据进行填充'''
    data = pd.concat([train_data, train_label], axis=1)
    data = data.reset_index(drop=True)
    A = data[data['矿物类型'] == 0]
    B = data[data['矿物类型'] == 1]
    C = data[data['矿物类型'] == 2]
    D = data[data['矿物类型'] == 3]

    A = mode_train_method(A)  # ,按照每个类别的数据进行填充
    B = mode_train_method(B)  # 按照每个类别的数据进行填充
    C = mode_train_method(C)  # ,按照每个类别的数据进行填充
    D = mode_train_method(D)  # 按照每个类别的数据进行填充

    df_filled = pd.concat([A, B, C, D])
    df_filled = df_filled.reset_index(drop=True)
    return df_filled.drop('矿物类型', axis=1), df_filled.矿物类型

def mode_test_method(train_data, test_data):
    '''根据训练集获取每个类别的平均值,并将训练集的每个类别平均值填充到测试中'''
    fill_values =train_data.apply(lambda x: x.mode().iloc[0] if len(x.mode())> 0 else None)
    return test_data.fillna(fill_values)# 使用均值填充缺失值

def mode_test_fill(train_data,train_label, test_data,test_label):
    '''使用平均值的方法对数据进行填充'''
    train_data_all = pd.concat([train_data, train_label], axis = 1)
    train_data_all = train_data_all.reset_index(drop=True)
    test_data_all = pd.concat([test_data, test_label],axis = 1)
    test_data_all = test_data_all.reset_index(drop=True)

    A_train = train_data_all[train_data_all['矿物类型']== 0]
    B_train = train_data_all[train_data_all['矿物类型']== 1]
    C_train = train_data_all[train_data_all['矿物类型']== 2]
    D_train = train_data_all[train_data_all['矿物类型']== 3]

    A_test = test_data_all[test_data_all['矿物类型'] == 0]
    B_test = test_data_all[test_data_all['矿物类型'] == 1]
    C_test = test_data_all[test_data_all['矿物类型'] == 2]
    D_test = test_data_all[test_data_all['矿物类型'] == 3]

    A = mode_test_method(A_train,A_test)
    B = mode_test_method(B_train,B_test)
    C = mode_test_method(C_train,C_test)
    D = mode_test_method(D_train,D_test)

    df_filled = pd.concat([A,B,C,D])
    df_filled = df_filled.reset_index(drop=True)
    return df_filled.drop('矿物类型',axis = 1),df_filled.矿物类型

mode_train_method 函数

此函数接收一个 DataFrame 数据,并计算所有列的众数。如果某列有多个众数,它会选择第一个出现的众数。如果某列没有众数(所有值出现次数相等),则使用 None 替代。然后,它使用这些众数值来填充 DataFrame 中的缺失值。

mode_train_fill 函数

这个函数首先将训练数据和标签数据合并,并根据不同的 '矿物类型' 分类数据。对于每一种类型的数据,它都会调用 mode_train_method 函数,使用该类别的众数来填充缺失值。之后,它将所有处理过的数据段重新组合,然后返回特征数据(去除 '矿物类型' 列)和标签数据。

mode_test_method 函数

此函数接收训练数据和测试数据作为参数。它计算训练数据的众数,并使用这些众数值来填充测试数据中的缺失值。同样地,如果某列没有明显的众数,它会使用 None

mode_test_fill 函数

此函数首先将训练数据和测试数据分别与各自的标签数据合并。然后,它根据 '矿物类型' 对训练数据和测试数据进行分类。接下来,它为每一种类型调用 mode_test_method 函数,使用训练数据的众数来填充测试数据中相应类别的缺失值。最后,它将所有处理过的测试数据段重新组合,并返回特征数据(去除 '矿物类型' 列)和标签数据。

 5.逻辑回归

'''-------------------线性回归算法实现训练数据集、测试数据集的填充------------------'''
def lr_train_fill(train_data,train_label):
    train_data_all = pd.concat([train_data, train_label], axis=1)
    train_data_all = train_data_all.reset_index(drop=True)
    train_data_X = train_data_all.drop('矿物类型',axis = 1)
    null_num = train_data_X.isnull().sum()  # 查看每个特种中存在空数据的个数
    null_num_sorted = null_num.sort_values (ascending=True)#将空数据的类别从小到大进行排序

    filling_feature = []  # 用来存储需要传入模型的特征名称
    for i in null_num_sorted.index:
        filling_feature.append(i)
        if null_num_sorted[i] != 0:  # 当前特征是否有空缺的内容。用来判断是否开始训练模型
            X = train_data_X[filling_feature].drop(i, axis=1)  # 构建训练集
            y = train_data_X[i]  # 构建测试集
            row_numbers_mg_null = train_data_X[train_data_X[i].isnull()].index.tolist()  # 获取空数据对应行号
            X_train =X.drop(row_numbers_mg_null)# 非空的数据作为训练数据集
            y_train =y.drop(row_numbers_mg_null)#非空的标签作为训练标签
            X_test = X.iloc[row_numbers_mg_null]  # 空的数据作为测试数据集
            regr = LinearRegression()  # 创建线性回归模型
            regr.fit(X_train,y_train)  # 训练模型
            y_pred = regr.predict(X_test)  # 使用模型进行预测
            train_data_X.loc[row_numbers_mg_null, i] = y_pred  # pandas.loc[3,4]
            print('完成训练数据集中的’{}‘列数据的填充'.format(i))
    return train_data_X,train_data_all.矿物类型

def lr_text_fill(train_data,train_label,test_data,test_label):
    train_data_all = pd.concat([train_data, train_label], axis=1)
    train_data_all = train_data_all.reset_index(drop=True)
    test_data_all = pd.concat([train_data, train_label], axis=1)
    test_data_all = train_data_all.reset_index(drop=True)
    train_data_X = train_data_all.drop('矿物类型',axis = 1)
    test_data_X = train_data_all.drop('矿物类型', axis=1)
    null_num = test_data_X.isnull().sum()  # 查看每个特种中存在空数据的个数
    null_num_sorted = null_num.sort_values (ascending=True)#将空数据的类别从小到大进行排序

    filling_feature = []  # 用来存储需要传入模型的特征名称
    for i in null_num_sorted.index:
        filling_feature.append(i)
        if null_num_sorted[i] != 0:  # 当前特征是否有空缺的内容。用来判断是否开始训练模型
            X_train= train_data_X[filling_feature].drop(i, axis=1)  # 构建训练集
            y_train = train_data_X[i]  # 构建测试集
            row_numbers_mg_null = train_data_X[train_data_X[i].isnull()].index.tolist()  # 获取空数据对应行号
            X_test =X_test.iloc(row_numbers_mg_null)# 非空的数据作为训练数据集
              # 空的数据作为测试数据集
            regr = LinearRegression()  # 创建线性回归模型
            regr.fit(X_train,y_train)  # 训练模型
            y_pred = regr.predict(X_test)  # 使用模型进行预测
            train_data_X.loc[row_numbers_mg_null, i] = y_pred  # pandas.loc[3,4]
            print('完成训练数据集中的’{}‘列数据的填充'.format(i))
    return test_data_X,test_data_all.矿物类型

lr_train_fill 函数

此函数首先将训练数据和标签数据合并,然后分离出特征数据部分。接下来,它查找每列中缺失值的数量,并对这些数量进行排序,从缺失值最少的列开始处理。对于每列,如果发现存在缺失值,它会构建一个训练数据集和一个测试数据集,其中测试数据集就是缺失值所在行。然后,使用线性回归模型对这些缺失值进行预测,并将预测结果填入原始数据中。最后,返回处理后的特征数据和原始的标签数据。

lr_text_fill 函数

这个函数首先合并训练数据和标签数据,以及测试数据和标签数据,删除原始索引。从训练数据中移除标签列 '矿物类型',得到训练特征数据。然后从测试数据中移除标签列 '矿物类型',得到测试特征数据。检查测试数据中每列的缺失值数量,按缺失值数量升序排列。对于每列,如果存在缺失值,则:使用训练数据集构建线性回归模型。使用模型预测测试数据集中缺失值行的值。将预测值填入测试数据集中的相应位置。返回填充完缺失值的测试数据和原始的测试标签数据。

6.随机森林

'''-------------------随机森林算法实现训练数据集、测试数据集的填充------------------'''
def rf_train_fill(train_data,train_label):
    train_data_all = pd.concat([train_data, train_label], axis=1)
    train_data_all = train_data_all.reset_index(drop=True)
    train_data_X = train_data_all.drop('矿物类型',axis = 1)
    null_num = train_data_X.isnull().sum()  # 查看每个特种中存在空数据的个数
    null_num_sorted = null_num.sort_values (ascending=True)#将空数据的类别从小到大进行排序

    filling_feature = []  # 用来存储需要传入模型的特征名称
    for i in null_num_sorted.index:
        filling_feature.append(i)
        if null_num_sorted[i] != 0:  # 当前特征是否有空缺的内容。用来判断是否开始训练模型
            X = train_data_X[filling_feature].drop(i, axis=1)  # 构建训练集
            y = train_data_X[i]  # 构建测试集
            row_numbers_mg_null = train_data_X[train_data_X[i].isnull()].index.tolist()  # 获取空数据对应行号
            X_train =X.drop(row_numbers_mg_null)# 非空的数据作为训练数据集
            y_train =y.drop(row_numbers_mg_null)#非空的标签作为训练标签
            X_test = X.iloc[row_numbers_mg_null]  # 空的数据作为测试数据集
            regr = RandomForestRegressor()  # 创建随机森林模型
            regr.fit(X_train,y_train)  # 训练模型
            y_pred = regr.predict(X_test)  # 使用模型进行预测
            train_data_X.loc[row_numbers_mg_null, i] = y_pred  # pandas.loc[3,4]
            print('完成训练数据集中的’{}‘列数据的填充'.format(i))
    return train_data_X,train_data_all.矿物类型

def rf_text_fill(train_data,train_label,test_data,test_label):
    train_data_all = pd.concat([train_data, train_label], axis=1)
    train_data_all = train_data_all.reset_index(drop=True)
    test_data_all = pd.concat([train_data, train_label], axis=1)
    test_data_all = train_data_all.reset_index(drop=True)
    train_data_X = train_data_all.drop('矿物类型',axis = 1)
    test_data_X = train_data_all.drop('矿物类型', axis=1)
    null_num = test_data_X.isnull().sum()  # 查看每个特种中存在空数据的个数
    null_num_sorted = null_num.sort_values (ascending=True)#将空数据的类别从小到大进行排序

    filling_feature = []  # 用来存储需要传入模型的特征名称
    for i in null_num_sorted.index:
        filling_feature.append(i)
        if null_num_sorted[i] != 0:  # 当前特征是否有空缺的内容。用来判断是否开始训练模型
            X_train= train_data_X[filling_feature].drop(i, axis=1)  # 构建训练集
            y_train = train_data_X[i]  # 构建测试集
            row_numbers_mg_null = train_data_X[train_data_X[i].isnull()].index.tolist()  # 获取空数据对应行号
            X_test =X_test.iloc(row_numbers_mg_null)# 非空的数据作为训练数据集
              # 空的数据作为测试数据集
            regr = RandomForestRegressor()  # 创建随机森林模型
            regr.fit(X_train,y_train)  # 训练模型
            y_pred = regr.predict(X_test)  # 使用模型进行预测
            train_data_X.loc[row_numbers_mg_null, i] = y_pred  # pandas.loc[3,4]
            print('完成训练数据集中的’{}‘列数据的填充'.format(i))
    return test_data_X,test_data_all.矿物类型

 随机森林函数与逻辑回归函数相近,只是更改了创建模型函数,使用随机森林模型预测。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐