机器学习——数据清洗之处理缺失值
目录
一、处理缺失值
处理数据集中的缺失值是数据清洗的重要组成部分,缺失值的存在会影响数据分析和机器学习模型的准确性和性能。缺失值处理的方法取决于缺失值的性质和数据集的具体情况。以下是一些常见的处理缺失值的策略:
-
删除(Drop)
- 删除带有缺失值的行:如果数据集足够大,且缺失值的行占比不大,可以考虑直接删除这些行。但是,这可能会导致信息损失,尤其是在缺失值比例较高的情况下。
- 删除带有缺失值的列:如果某列的缺失值过多,而这一列又不是特别关键,可以考虑删除整个列。
-
填充(Imputation)
- 平均值/中位数/众数填充:对于数值型数据,可以用列的均值、中位数或众数填充缺失值。
- 基于模型的预测:可以使用其他特征或外部数据预测缺失值,例如使用回归模型、决策树、随机森林或其他机器学习模型。
- KNN 插补:使用 K 近邻算法来预测缺失值。
- 基于业务逻辑的填充:根据领域知识或业务逻辑来推测合理的值填充。
-
使用专门的插补方法
- 多重插补(Multiple Imputation):这是一种统计学方法,通过多次随机抽样生成多个数据集,然后对每个数据集进行分析,最后汇总结果。
-
特征工程
- 创建指示变量:可以为缺失值创建一个新的二进制特征,表示该特征是否存在缺失值。
- 预测模型:构建一个单独的模型来预测缺失值,这可以是一个回归或分类模型,取决于缺失值的类型。
-
使用特定库的功能
- 在 Python 的 pandas 库中,可以使用
fillna()方法填充缺失值。 - 在 scikit-learn 中,可以使用
SimpleImputer类来处理缺失值,支持多种填充策略。
- 在 Python 的 pandas 库中,可以使用
在选择处理缺失值的方法时,需要考虑缺失值的模式(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)
-
使用 pandas 的
read_excel函数从 Excel 文件"矿物数据.xls"中读取数据到 DataFramedata。 -
删除数据中特殊类别的记录,这里删除的是 'E' 类别,因为数据集中只有一个这样的记录。
-
使用
.isnull()方法检测数据中的缺失值,返回一个布尔 DataFrame。 -
对每列的缺失值进行计数,存储在
null_total变量中。 -
从数据中移除 '矿物类型' 和 '序号' 这两列,剩余的列为特征数据
X_whole。 -
提取 '矿物类型' 列作为标签数据
y_whole。 -
创建一个字典
label_dict,将 'A', 'B', 'C', 'D' 四种类型的矿物映射到整数标签。 -
将
y_whole中的矿物类型转换成对应的整数标签,并将结果存储回y_whole。 -
遍历
X_whole的每一列,将非数值数据强制转换为数值数据,无法转换的会被设为 NaN。 -
使用
StandardScaler对特征数据进行 Z-score 标准化,即减去均值并除以标准差。 -
使用
fit_transform方法拟合并转换特征数据X_whole,然后将其转换回 DataFrame 形式。 -
使用
train_test_split函数将数据集分为训练集和测试集,其中测试集占总数据集的 30%,并设置随机种子以保证结果的可复现性。 -
调用
fill_data.lr_train_fill和fill_data.lr_text_fill函数来填充训练集和测试集中的缺失值。这通常意味着使用某种策略(如中位数填充)来填补缺失数据。 -
引入
SMOTE算法,这是一种过采样技术,用于处理分类问题中数据不平衡的情况。k_neighbors参数控制了用来生成新样本的最近邻数量,random_state设定随机种子确保结果可复现。 -
使用
fit_resample方法应用 SMOTE 算法来增加少数类的样本数量,从而平衡数据集。os_x_train和os_y_train分别是经过 SMOTE 处理后的特征和标签。 -
统计并绘制处理后各类别数据的数量。首先将训练集和测试集的标签合并,然后计算每个类别的数量。接着创建一个条形图并为每个条形添加数值标签,最后显示图形。
-
将处理后的训练数据和测试数据保存为 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) 作为输入参数。它执行以下操作:
- 使用
pd.concat将特征数据和标签数据按列合并成一个新的 DataFrame。 - 调用
reset_index方法重置 DataFrame 的索引,丢弃旧的索引,并创建新的默认整数索引。 - 使用
dropna方法删除包含任何 NaN 或缺失值的行。 - 最后,函数返回两个值:一个是不包含 '矿物类型' 列的处理后的特征数据,另一个是处理后的标签数据(即 '矿物类型' 列)。
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.矿物类型
随机森林函数与逻辑回归函数相近,只是更改了创建模型函数,使用随机森林模型预测。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)