使用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)#最終的結果
今天就到這裏把,工做了一天好睏、眼疼,先發出去,明天再看看有沒有什麼錯誤。