使用sklearn进行数据挖掘系列文章:html
在使用机器算法以前,咱们先把数据作下预处理,先把特征和标签拆分出来算法
housing = strat_train_set.drop("median_house_value",axis=1) #原始数据集并未发生改变 housing_labels=strat_train_set["median_house_value"].copy()
大多数机器学习算法是不能在有缺失值的数据集上面运行的,而本数据集特征total_bedrooms
是存在数据缺失现象的,因此就须要想办法处理,有如下几个思路:数组
上面对应的操做:机器学习
housing.dropna(subset=["total_bedrooms"]) # 1.删除样本 housing.drop("total_bedrooms", axis=1) # 2.删除特征,注意参数的用法和1不同 median = housing["total_bedrooms"].median() housing["total_bedrooms"].fillna(median) # 3. 中值填充
若是采用的是方法3那么就须要将替换的值保存起来,在后续的工做中须要将它应用到测试集,以及可能添加的新数据。上面这个操做是使用pandas,sklearn提供了Imputer
,一样可以很好解决缺失值问题,下面其用法学习
from sklearn.preprocessing import Imputer imputer = Imputer(strategy="median") housing_num = housing.drop("ocean_proximity", axis=1) #去除非数值类特征 imputer.fit(housing_num)
imputer提供了如下几种填充策略测试
经过statistics_
查看填充的数值编码
>>imputer.statistics_ array([-118.51 , 34.26 , 29. , ..., 5.23228423, 0.20303137, 2.8176527 ])
再看一看pandas计算出来的中值code
>>housing_num.median().values array([-118.51 , 34.26 , 29. , ..., 5.23228423, 0.20303137, 2.8176527 ])
接下来就须要将计算获得的数值应用到数据集中orm
X = imputer.transform(housing_num) >>type(X) numpy.ndarray
最终获得的是结果是array类型,若是想转为pandas类型htm
housing_tr = pd.DataFrame(X, columns=housing_num.columns)
上面咱们把ocean_proximity
这一特征去掉,因此这些操做是处理数值类型的特征,那么非数值类型的该如何处理呢?
决策树、贝叶斯等分类器可以处理标签类特征,但不少算法是不能处理这类特征,须要转换为数值类型,sklearn提供了LabelEncoder
特征转换方法
from sklearn.preprocessing import LabelEncoder encoder = LabelEncoder() housing_cat = housing["ocean_proximity"] housing_cat_encoded = encoder.fit_transform(housing_cat) >>housing_cat_encoded array([0, 0, 4, ..., 1, 0, 3], dtype=int64)
上面是输出编码的结果,那么对应的0、1...是指的什么呢?
>>encoder.clases_ array(['<1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'], dtype=object)
经过类别号能够表示类别,还有一种方法可以表示类别---one hot
,该特征取的值位置为1,其他为0;固然sklearn也提供了实现方法OneHotEncoder
from sklearn.preprocessing import OneHotEncoder encoder = OneHotEncoder() housing_cat_1hot = encoder.fit_transform(housing_cat_encoded.reshape(-1,1))#返回的为稀疏矩阵 >>housing_cat_1hot.toarray() array([[ 1., 0., 0., 0., 0.], [ 1., 0., 0., 0., 0.], [ 0., 0., 0., 0., 1.], ..., [ 0., 1., 0., 0., 0.], [ 1., 0., 0., 0., 0.], [ 0., 0., 0., 1., 0.]])
note:housing_cat_encoded
返回的为1D 数组,fit_transform须要传入的为一个2D数组,须要先转为列向量。
能够将上面encoder
和one hot
过程合并为一个
from sklearn.preprocessing import LabelBinarizer encoder = LabelBinarizer() housing_cat_1hot=encoder.fit_transform(housing_cat) >>housing_cat_1hot #numpy array array([[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 0, 1], ..., [0, 1, 0, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 1, 0]])
尽管sklearn提供了强大的数据处理功能,有些时候咱们须要根据本身的需求自定义一些数据预处理方法,而且让咱们这些操做有着sklearnAPI类似的用法,咱们所须要作的就是继承BaseEstimator
类,并覆写三个方法fit
,transform
和fit_transform
,第三个方法是前两个的整合,若是不想覆写fit_transform
,能够继承TransformerMixin
(从类名称就能够看出其做用)这个类
from sklearn.base import BaseEstimator, TransformerMixin rooms_ix, bedrooms_ix, population_ix, household_ix = 3, 4, 5, 6 class CombinedAttributesAdder(BaseEstimator, TransformerMixin): 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: 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)
上面定义的类的功能是为原数据集添加新的特征,X[:,3]
表示的是第4列全部数据,np.c_
表示的是拼接数组。
另外sklearn是不能直接处理DataFrames
的,那么咱们须要自定义一个处理的方法将之转化为numpy类型
class DataFrameSelector(BaseEstimator,TransformerMixin): def __init__(self,attribute_names): #能够为列表 self.attribute_names = attribute_names def fit(self,X,y=None): return self def transform(self,X): return X[self.attribute_names].values #返回的为numpy array
机器学习算法在缩放尺度不同的数据效果比较差,比就如房价数据集total_bedrooms
的取值范围为16445,而`median_income`的范围是0.515,因此须要对特征进行缩放。
note:一般状况下Target特征不需缩放
有两种缩放数据的方法
MinMaxScaler(self, feature_range=(0, 1), copy=True)
StandardScaler(self, copy=True, with_mean=True, with_std=True)
目前在数据预处理阶段,咱们须要对缺失值进行处理、特征组合和特征缩放。每一步的执行都有着前后顺序,sklearn提供了Pipeline
帮助顺序完成转换。
num_attribs = list(housing_num)#返回的为列名[col1,col2,....] cat_attribs = ["ocean_proximity"] num_pipeline = Pipeline([ #数值类型 ('selector', DataFrameSelector(num_attribs)), ('imputer', Imputer(strategy="median")), ('attribs_adder', CombinedAttributesAdder()), ('std_scaler', StandardScaler()), ]) cat_pipeline = Pipeline([ #标签类型 ('selector', DataFrameSelector(cat_attribs)), ('cat_encoder', CategoricalEncoder(encoding="onehot-dense")), ])
上面定义的为分别处理数值类型和标签类型的转换流程,housing_num
为DataFrame
类型,list(DataFrame)
的结果会是什么?返回的为列名字,无论大家信不信,反正我是信了。pandas真是太强大了。上面着两个流程还能够再整合一块儿
from sklearn.pipeline import FeatureUnion full_pipeline = FeatureUnion(transformer_list=[ ("num_pipeline", num_pipeline), ("cat_pipeline", cat_pipeline), ]) housing_prepared = full_pipeline.fit_transform(housing)#最终的结果
今天就到这里把,工做了一天好困、眼疼,先发出去,明天再看看有没有什么错误。