超级实用!如何为机器学习算法准备数据?
點擊上方“AI有道”,選擇“星標”公眾號
重磅干貨,第一時間送達
本文為《Scikit-Learn 和 TensorFlow 機器學習指南》的第二章的第 3 講:為機器學習算法準備數據。
1. 使用實際數據
2. 整體規劃
3. 獲取數據
4. 發現、可視化數據,增加直觀印象
5. 為機器學習準備數據
6. 選擇模型并進行訓練
7. 調試模型
8. 部署、監控、維護系統
第二章前 2 講的地址如下:
如何入手第一個機器學習項目?
如何從數據可視化中發現數據規律?
筆記盡量突出重點,提煉關鍵知識點。正文開始!
數據清洗(處理缺失值)
對于數據集中出現缺失值的情況,需要對其進行處理。對缺失值常用的三種方法是:
丟棄有缺失值的樣本
丟棄有缺失值的整個特征
對缺失值進行填充(補零、均值填充或中位數填充等)
三種方法相應的代碼如下:
housing.dropna(subset=["total_bedrooms"]) ? ?# option 1 housing.drop("total_bedrooms", axis=1) ? ? ? # option 2 median = housing["total_bedrooms"].median() housing["total_bedrooms"].fillna(median, inplace=True) # option 3一般 option 3 應用更為廣泛。值得注意的是,應該保留訓練樣本的 median 值,測試樣本中的缺失值將以此 median 值進行填充。
在 Scikit-Learn 中提供了 Imputer 類,進行缺失值處理。示例代碼如下:
from sklearn.preprocessing import Imputer imputer = Imputer(strategy="median") housing_num = housing.drop('ocean_proximity', axis=1) imputer.fit(housing_num) X = imputer.transform(housing_num) housing_tr = pd.DataFrame(X, columns=housing_num.columns)處理文字或類別屬性
本章的波士頓房價問題中,ocean_proximity 屬性是非數值的字符屬性,因此無法進行中位數填充。該屬性如下所示:
['<1H OCEAN' 'INLAND' 'ISLAND' 'NEAR BAY' 'NEAR OCEAN']
你可以直接使用下面代碼,將字符屬性轉換成數值屬性:
更方便地,還可以直接將字符屬性轉換為 one-hot 編碼:
自定義轉換器
雖然 Scikit-Learn 已經提供了許多有用的轉換器,但是你仍然可以編寫自己的轉換器,例如特定屬性組合。自定義轉換器很簡單,只需要創建一個類,然后實現以下三個方法:fit()(返回自身)、transform()、fit_transform()。如果添加 TransformerMixin 作為基類,就可以直接得到最后一個方法。同時,如果添加 BaseEstimator 作為基類(并在構造函數中避免 *args 和 **kargs),你還能額外獲得兩個非常有用的自動調整超參數的方法 get_params()和 set_params()。
下面是自定義轉換器,添加組合屬性的例子:
from sklearn.base import BaseEstimator, TransformerMixin# column index rooms_ix, bedrooms_ix, population_ix, household_ix = 3, 4, 5, 6class CombinedAttributesAdder(BaseEstimator, TransformerMixin):def __init__(self, add_bedrooms_per_room = True): # no *args or **kargsself.add_bedrooms_per_room = add_bedrooms_per_roomdef fit(self, X, y=None):return self ?# nothing else to dodef 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)特征縮放
不同的特征屬性范圍不一,容易給訓練造成困難,增加訓練時間。因此,一般會對不同特征進行同尺度縮放。常用的兩種方式是歸一化和標準化。
歸一化很簡單:將值重新縮放于 0 到 1 之間。實現方法是將值減去最小值并除以最大值和最小值的差。對此,Scikit-Learn 提供了一個名為 MinMaxScaler 的轉換器。如果希望范圍不是 0~1,可以通過調整超參數 feature_range 進行更改。
標準化的做法是首先減去平均值(所以標準化值的均值總是零),然后除以方差。不同于歸一化,標準化不將值綁定到特定范圍,對某些算法而言,這可能是個問題(例如,神經網絡期望的輸入值范圍通常是0到1)。但是標準化的方法受異常值的影響更小。Scikit-Learn 提供了一個標準化的轉換器 StandadScaler。
管道 Pipeline
我們可以把機器學習算法中許多轉換操作使用管道 pipeline 統一順序進行。Scikit-Learn 正好提供了 Pipeline 來支持這樣的轉換。下面是一個數值屬性的流水線例子:
from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScalernum_pipeline = Pipeline([('imputer', Imputer(strategy="median")),('attribs_adder', CombinedAttributesAdder()),('std_scaler', StandardScaler()),])housing_num_tr = num_pipeline.fit_transform(housing_num)以上是數值型的 Pipeline 處理過程。對于非數值型的字符屬性,可以建立一個新的完整的 Pipeline,將上面的 num_pipeline 和字符屬性的轉換整合到一個 Pipeline 中,如下所示:
from sklearn.compose import ColumnTransformernum_attribs = list(housing_num) cat_attribs = ["ocean_proximity"]full_pipeline = ColumnTransformer([("num", num_pipeline, num_attribs),("cat", OneHotEncoder(), cat_attribs),])housing_prepared = full_pipeline.fit_transform(housing)【推薦閱讀】
干貨 | 公眾號歷史文章精選(附資源)
我的深度學習入門路線
我的機器學習入門路線圖
總結
以上是生活随笔為你收集整理的超级实用!如何为机器学习算法准备数据?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员应具有的素质
- 下一篇: 学习C/C++:伴随我成长的编程书!