好的,接着上一部分,继续第二部分–缺失值处理。
几乎对每一个复杂数据集,都存在缺失或是错误的数据,这就像人类的死亡,还有上税。一些预测模型本身就能够处理缺失的数据(如神经网络),然而其他模型则需要单独处理缺失值。scikit-learn库中的 RandomForestClassifier模型内部并不能处理缺失值,所以在训练模型之前我们需要一些不同的方法来为缺失值分配具体数据。以下是几种处理缺失值的方法:
1)直接舍弃–实际上,我并不提倡这种处理方式,但如果已经获取大量没有缺失任何值的数据,直接舍弃当然就成了最快捷简便的处理方式了。
2)分配数值以取代缺失值–处理分类变量(下一部分详解)时尤其管用。我会在实际处理过程中尽可能地使用这种处理方式,因为事实上,所被缺失的值往往富含很有用的信息。然而,这种方式处理连续型变量的时候,效果并不是最佳的。
# Replace missing values with "U0"
df['Cabin'][df.Cabin.isnull()] = 'U0'
3)分配为平均值–由于过程简单,并且处理非重要变量时效果足够好,因此是普遍使用的一种处理方式。值得注意的是,处理分类变量的时候,众数可以替代统计平均数。
# Take the median of all non-null Fares and use that for all missing values
df['Fare'][ np.isnan(df['Fare']) ] = df['Fare'].median()
-or-
# Replace missing values with most common port
df.Embarked[ df.Embarked.isnull() ] = df.Embarked.dropna().mode().values
4)用回归或其他简单模型预测缺失值–我在处理titanic数据集中的年龄变量时所采用的就是这一方式,原因在于,年龄似乎是比较重要的一个变量,用模型预测理应会比用平均值效果更好。普遍方式是选取任何其他可获取的特征,并利用该变量中的确切值作为样本构建模型,然后为其余值进行预测 。以下代码使用RandomForestClassifier模型填补年龄变量的缺失值,实际上线性回归也许已经足够好。
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
### Populate missing ages using RandomForestClassifier
def setMissingAges(df):
# Grab all the features that can be included in a Random Forest Regressor
age_df = df[['Age','Embarked','Fare', 'Parch', 'SibSp', 'Title_id','Pclass','Names','CabinLetter']]
# Split into sets with known and unknown Age values
knownAge = age_df.loc[ (df.Age.notnull()) ]
unknownAge = age_df.loc[ (df.Age.isnull()) ]
# All age values are stored in a target array
y = knownAge.values[:, 0]
# All the other values are stored in the feature array
X = knownAge.values[:, 1::]
# Create and fit a model
rtr = RandomForestRegressor(n_estimators=2000, n_jobs=-1)
rtr.fit(X, y)
# Use the fitted model to predict the missing values
predictedAges = rtr.predict(unknownAge.values[:, 1::])
# Assign those predictions to the full data set
df.loc[ (df.Age.isnull()), 'Age' ] = predictedAges
return df