1.上次的blog中说了说数据分割的方法,这次我想谢谢数据处理的过程,大多数的机器学习中原始数据集会出现数据缺失、数据异常等等问题,而我们在做机器学习中数据集的重要性不言而喻,所以在实验之前我们要对数据集进行一定的处理。
注:数据集还是使用的美国加利福利亚州各地的房价,这在我的上一篇blog中有点击打开链接
针对数据缺失我们可以有三种方法进行处理:
1)去掉对应的街区
2)去掉整个属性
3)进行填充(0、平均值、中位数等)
在pandas中则有dropna(),drop(),fillna()这三种方法进行处理:
median = housing["total_bedrooms"].median()
housing["total_bedrooms"].fillna(median)
其中,median就是中位数
这种方法需要计算数据集中每个属性的中位数,用中位数填充数据。在sklearn中Imputer可以较好的处理这个问题,代码如下:
from sklearn.preprocessing import Imputer
imputer = Imputer(strategy="median") # 这个strategy有三种median/mean/most_frequent
housing_num = housing.drop("ocean_proximity", axis=1) # 删除ocean_proximity这个参数因为它本身不是一个数值
imputer.fit(housing_num) # 重点的方法,fit()方法将实例拟合到训练数据中
all_median = imputer.statistics_ # 所有数据的中间值
第一行代码就是创建一个实例,总共有三种可选的策略
第二行代码因为ocean_proximity这个属性并不是数值所以我们要删除
第三行代码则是将数据集拟合到该实例中
第四行代码则是查看所有数据的中位数
X = imputer.transform(housing_num) # 重点的方法,transform()将中值补充进入缺失值,这是个数组
housing_tr = pd.DataFrame(X, columns=housing_num.columns)
第五行代码则是将中位数填充进去,返回的是一个numpy矩阵
第六行将矩阵数据转为DataFrame类型
2.处理文本
因为在数据集中处理数字外,可能还有文本数据。比如我们现在所用的数据集中“ocean_proximity”数据便是一个文本数据,sklearn中专门针对文本的处理方法:LabelEncoder/OneHotEncoder/LabelBinarizer等等,相应的代码:
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder() # 这个是用来将字符串编码为数字(数字的选取都在字符串的长度-1)
housing_cat = housing["ocean_proximity"]
housing_cat_encoded = encoder.fit_transform(housing_cat) # 这里有两个fit,fit+transform就等于fit_transform
print(housing_cat_encoded)
# 6.3 处理文本(使用one_hot)
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder()
# 注意这里要求使用reshape(1, -1),原因在于fit_transform()需要传入一个2D的数组
housing_cat_1hot = encoder.fit_transform(housing_cat_encoded.reshape(1, -1)) # 这个结果是一个稀疏矩阵
print(housing_cat_1hot)
print(housing_cat_1hot.toarray()) # 稀疏矩阵的展开
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()
housing_cat_1hot = encoder.fit_transform(housing_cat) # 一步转换
print(housing_cat_1hot)
第一种方法:LabelEncoder就是统计标签的数量然后用自然数0/1/2/3...对文本标签进行编号
第二种方法:OneHotEncoder则是利用onehot的方法对文本编码,这种方法考虑到了数据之间的联系,但这种方法返回的是一个稀疏矩阵
第三种方法:LabelBinarizer则是在第二种方法的基础上完成了稀疏矩阵的转换工作。
3.自定义转换器
除了sklearn中所提供的方法外我们还可以自己编写转换器,代码如下:
# 6.4 自定义文本转化器
from sklearn.base import BaseEstimator, TransformerMixin
rooms_ix, bedrooms_ix, population_ix, household_ix = 3, 4, 5, 6
class CombinedAttributesAdder(BaseEstimator, TransformerMixin):
'''
仔细看了下这个类,其实就是用来增加三个或者两个自定义的属性,便于分析
主要是将步骤5中的组合属性用到了这个地方
'''
def __init__(self, add_bedrooms_per_room = True): # no *args or **kargs
self.add_bedrooms_per_room = add_bedrooms_per_room
def fit(self, X, y=None):
return self # nothing else to do
def transform(self, X, y=None):
rooms_per_household = X[:, rooms_ix] / X[:, household_ix]
population_per_household = X[:, population_ix] / X[:, household_ix]
if self.add_bedrooms_per_room:
bedrooms_per_room = X[:, bedrooms_ix] / X[:, rooms_ix]
return np.c_[X, rooms_per_household, population_per_household,
bedrooms_per_room]
else:
# 用np.c_()将XX,YY拉平后的两个array按照列合并(此时是n*2的举证,有n个样本点,每个样本点有横纵2维),然后调用分类器集合的decision_function函数获得样本到超平面的距离。Z是一个n*1的矩阵(列向量),记录了n个样本距离超平面的距离。
return np.c_[X, rooms_per_household, population_per_household]
attr_adder = CombinedAttributesAdder(add_bedrooms_per_room=False)
housing_extra_attribs = attr_adder.transform(housing.values)
CombinedAttributesAdder这个类就是用来添加我们之前分析的关系属性,这个类中的方法我们主要要写transform(),fit()方法我们不用去动,这样我们就可以吧新的属性添加进去。注意这个返回值是一个矩阵。
4.数据的放缩处理
在做机器学习的过程中,数据的预处理中的标准化处理十分重要,这样我们可以减少异常数据的影响。主要有线性函数归一化与标准化这两种处理方式。
首先我们要引入流水线的概念,因为在机器学习中数据预处理的操作是一个线性流水线的过程,我们可以利用sklearn中pipeline方式对这些操作进行系统的处理。代码如下:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
'''
这里使用了相当重要的pipeline这个方法
pipeline就是一个流水线的作业方式
'''
num_pipeline = Pipeline([
('imputer', Imputer(strategy="median")),
('attribs_adder', CombinedAttributesAdder()),
('std_scaler', StandardScaler()),
])
housing_num_tr = num_pipeline.fit_transform(housing_num)
这个pipeline流水线中有三个操作:数据填充Imputer,属性添加CombinedAttributesAdder,标准化StandardScaler。这样通过流水线执行完后,我们可以得到一组经过数据预处理的数据。
2018年5月17号,关于数据放缩的处理特别是标准化的处理,我们在上面是进行了放缩但如何还原并没有讲。后来查阅相关的文档,我发现了一个放缩还原的方法,这样在我们进行了预测后,原本的预测结果是一种经过放缩的非原始数据,现在我们将其还原为原始的数据:
scaler = sklearn.preprocessing.StandardScaler().fit(train) # 将训练集数据进行拟合
test_S = scaler.transform(test) # 对测试集进行拟合
test1 = scaler.inverse_transform(test_S) # 还原测试集
通过以上的方法我们可以对预测结果进行还原