运行环境:Google Colab
处理缺失数据可简单分为两种方法:1. 删除具有缺失值的列 2. 填充
!git clone https://github.com/JeffereyWu/Housing-prices-data.git
import pandas as pd
from sklearn.model_selection import train_test_split
X_full = pd.read_csv('/content/Housing-prices-data/train.csv', index_col='Id')
X_test_full = pd.read_csv('/content/Housing-prices-data/test.csv', index_col='Id')
- 读取数据
index_col='Id'
是为了将数据框的索引列设置为’Id’列。
X_full.dropna(axis=0, subset=['SalePrice'], inplace=True)
y = X_full.SalePrice
X_full.drop(['SalePrice'], axis=1, inplace=True)
- SalePrice 是我们尝试预测的目标变量。
- 删除训练数据中带有缺失目标值(‘SalePrice’)的行。
- 将目标值(‘SalePrice’)存储在变量y中,并从特征中删除。
X = X_full.select_dtypes(exclude=['object'])
X_test = X_test_full.select_dtypes(exclude=['object'])
- 将特征数据限制为仅包含数值型特征
select_dtypes
函数用于根据数据类型(在这里是’object’,即非数值型)选择特定类型的列。
X_train, X_valid, y_train, y_valid = train_test_split(X, y, train_size=0.8, test_size=0.2,
random_state=0)
- 使用
train_test_split
函数将训练数据X和目标值y分成训练集和验证集。train_size参数指定了训练集的比例(80%),test_size参数指定了验证集的比例(20%),random_state参数用于控制随机分割的种子,以确保每次运行代码时分割结果都一样。
1. 了解训练数据的形状和每列数据中缺失值的数量
print(X_train.shape)
missing_val_count_by_column = (X_train.isnull().sum())
print(missing_val_count_by_column[missing_val_count_by_column > 0])
- 首先使用
.isnull()
方法将每个单元格是否为缺失值进行检查,然后使用.sum()
方法计算每列中缺失值的总数。
- 最后,它打印出那些包含至少一个缺失值的列的缺失值数量。
- 这段代码可以帮助你了解哪些特征(列)在训练数据中存在缺失值,以便在数据预处理过程中采取适当的措施来处理这些缺失值,例如填充它们或者删除相关的特征。
考虑到数据中缺失值的数量并不是很多,如果我们删除带有缺失值的列,那么就会丢失掉很多有用的信息。因此,更好的做法是对缺失值进行填充(imputation),以尽量保留数据的完整性。填充缺失值通常可以采用一些方法,如用平均值、中位数或者其他相关数据来替代缺失值,这样可以更好地保留数据的特征和信息,提高模型的性能。
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error
def score_dataset(X_train, X_valid, y_train, y_valid):
model = RandomForestRegressor(n_estimators=100, random_state=0)
model.fit(X_train, y_train)
preds = model.predict(X_valid)
return mean_absolute_error(y_valid, preds)
RandomForestRegressor
是一个随机森林回归模型,用于机器学习中的回归问题。mean_absolute_error
是一个评估回归模型性能的函数,它用于计算预测值与实际值之间的平均绝对误差。
- 函数的目的是通过比较不同数据集处理方法的分数来评估哪种方法在机器学习任务中效果最好。
cols_with_missing = [col for col in X_train.columns
if X_train[col].isnull().any()]
reduced_X_train = X_train.drop(cols_with_missing, axis=1)
reduced_X_valid = X_valid.drop(cols_with_missing, axis=1)
- 创建了一个列表
cols_with_missing
,用于存储训练数据X_train
中具有缺失值的列名。
- 遍历
X_train
的每一列,使用.isnull().any()
来检查每列是否包含任何缺失值。如果某列中至少有一个缺失值,就将其列名添加到cols_with_missing
列表中。
- 使用
.drop()
方法从训练数据X_train
和验证数据X_valid
中删除具有缺失值的列。cols_with_missing
列表中包含了所有具有缺失值的列名,通过axis=1
参数,可以指定删除列而不是行。
print("MAE (Drop columns with missing values):")
print(score_dataset(reduced_X_train, reduced_X_valid, y_train, y_valid))
2. 数据填充
from sklearn.impute import SimpleImputer
my_imputer = SimpleImputer()
imputed_X_train = pd.DataFrame(my_imputer.fit_transform(X_train))
imputed_X_valid = pd.DataFrame(my_imputer.transform(X_valid))
imputed_X_train.columns = X_train.columns
imputed_X_valid.columns = X_valid.columns
- 导入了Scikit-learn库中的
SimpleImputer
类,该类用于处理缺失值,它可以用于填充数据中的缺失值。
- 分别使用
fit_transform
方法来对训练数据X_train
和验证数据X_valid
进行缺失值填充。
- 在训练过程中,模型需要学习如何处理缺失值以及其他特征,因此使用
fit_transform
方法对训练数据进行预处理。
- 使用
transform
方法对验证数据进行数据预处理,包括填充缺失值。在验证过程中,模型不应该再次拟合填充器,因为这会导致信息泄露。模型在实际应用中不会在新的数据上重新拟合填充器,而是使用在训练数据上学到的填充策略。
- 将填充后的数据框中的列名恢复为原始数据
X_train
和X_valid
的列名。这是因为在填充数据时,列名可能被丢失。
print("MAE (Imputation):")
print(score_dataset(imputed_X_train, imputed_X_valid, y_train, y_valid))
这里我们可以看到,填充的方法没有删除的方法成效好。由于数据集中缺失值很少,所以通常来说,使用填充方法来处理缺失值应该比完全删除带有缺失值的列更好。但是在实际情况中,填充的方式也需要谨慎选择,不一定每次都使用均值填充就是最佳选择。具体的填充策略需要根据数据的特点和背后的含义来确定,可能需要尝试不同的填充方式以找到最合适的方法。同时,一些填充方式可能会导致糟糕的结果,因此需要谨慎评估和选择。
3. 对训练数据和验证数据进行最终的数据预处理
final_imputer = SimpleImputer(strategy='median')
final_X_train = pd.DataFrame(final_imputer.fit_transform(X_train))
final_X_valid = pd.DataFrame(final_imputer.transform(X_valid))
final_X_train.columns = X_train.columns
final_X_valid.columns = X_valid.columns
- 设置填充策略为’
median
’(中位数)。这意味着缺失值将会使用每列的中位数值来进行填充。
model = RandomForestRegressor(n_estimators=100, random_state=0)
model.fit(final_X_train, y_train)
preds_valid = model.predict(final_X_valid)
print("MAE (Your approach):")
print(mean_absolute_error(y_valid, preds_valid))
final_X_test = pd.DataFrame(final_imputer.transform(X_test))
final_X_test.columns = X_test.columns
preds_test = model.predict(final_X_test)
output = pd.DataFrame({'Id': X_test.index,
'SalePrice': preds_test})
output.to_csv('submission.csv', index=False)