机器学习-数据处理(hands_on_Ml_with_Sklearn_and_TF)

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) # 还原测试集
通过以上的方法我们可以对预测结果进行还原

你可能感兴趣的:(机器学习-数据处理(hands_on_Ml_with_Sklearn_and_TF))