# 4.3. 預處理數據
校驗者:
[@if only](https://github.com/apachecn/scikit-learn-doc-zh)
翻譯者:
[@Trembleguy](https://github.com/apachecn/scikit-learn-doc-zh)
`sklearn.preprocessing` 包提供了幾個常見的實用功能和變換器類型,用來將原始特征向量更改為更適合機器學習模型的形式。
一般來說,機器學習算法受益于數據集的標準化。如果數據集中存在一些離群值,那么穩定的縮放或轉換更合適。不同縮放、轉換以及歸一在一個包含邊緣離群值的數據集中的表現在 [Compare the effect of different scalers on data with outliers](../auto_examples/preprocessing/plot_all_scaling.html#sphx-glr-auto-examples-preprocessing-plot-all-scaling-py) 中有著重說明。
## 4.3.1. 標準化,也稱去均值和方差按比例縮放
數據集的 **標準化** 對scikit-learn中實現的大多數機器學習算法來說是 **常見的要求** 。如果個別特征或多或少看起來不是很像標準正態分布(**具有零均值和單位方差**),那么它們的表現力可能會較差。
在實際情況中,我們經常忽略特征的分布形狀,直接經過去均值來對某個特征進行中心化,再通過除以非常量特征(non-constant features)的標準差進行縮放。
例如,在機器學習算法的目標函數(例如SVM的RBF內核或線性模型的l1和l2正則化),許多學習算法中目標函數的基礎都是假設所有的特征都是零均值并且具有同一階數上的方差。如果某個特征的方差比其他特征大幾個數量級,那么它就會在學習算法中占據主導位置,導致學習器并不能像我們說期望的那樣,從其他特征中學習。
函數 [`scale`](generated/sklearn.preprocessing.scale.html#sklearn.preprocessing.scale "sklearn.preprocessing.scale") 為數組形狀的數據集的標準化提供了一個快捷實現:
```
>>> from sklearn import preprocessing
>>> import numpy as np
>>> X_train = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
>>> X_scaled = preprocessing.scale(X_train)
>>> X_scaled
array([[ 0. ..., -1.22..., 1.33...],
[ 1.22..., 0. ..., -0.26...],
[-1.22..., 1.22..., -1.06...]])
```
經過縮放后的數據具有零均值以及標準方差:
```
>>> X_scaled.mean(axis=0)
array([ 0., 0., 0.])
>>> X_scaled.std(axis=0)
array([ 1., 1., 1.])
```
`預處理` 模塊還提供了一個實用類 [`StandardScaler`](generated/sklearn.preprocessing.StandardScaler.html#sklearn.preprocessing.StandardScaler "sklearn.preprocessing.StandardScaler") ,它實現了轉化器的API來計算訓練集上的平均值和標準偏差,以便以后能夠在測試集上重新應用相同的變換。因此,這個類適用于 [`sklearn.pipeline.Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 的早期步驟:
```
>>> scaler = preprocessing.StandardScaler().fit(X_train)
>>> scaler
StandardScaler(copy=True, with_mean=True, with_std=True)
>>> scaler.mean_
array([ 1. ..., 0. ..., 0.33...])
>>> scaler.scale_
array([ 0.81..., 0.81..., 1.24...])
>>> scaler.transform(X_train)
array([[ 0. ..., -1.22..., 1.33...],
[ 1.22..., 0. ..., -0.26...],
[-1.22..., 1.22..., -1.06...]])
```
縮放類對象可以在新的數據上實現和訓練集相同縮放操作:
```
>>> X_test = [[-1., 1., 0.]]
>>> scaler.transform(X_test)
array([[-2.44..., 1.22..., -0.26...]])
```
你也可以通過在構造函數 :class:StandardScaler 中傳入參數 `with_mean=False` 或者``with_std=False` 來取消中心化或縮放操作。
### 4.3.1.1. 將特征縮放至特定范圍內
一種標準化是將特征縮放到給定的最小值和最大值之間,通常在零和一之間,或者也可以將每個特征的最大絕對值轉換至單位大小。可以分別使用 [`MinMaxScaler`](generated/sklearn.preprocessing.MinMaxScaler.html#sklearn.preprocessing.MinMaxScaler "sklearn.preprocessing.MinMaxScaler") 和 [`MaxAbsScaler`](generated/sklearn.preprocessing.MaxAbsScaler.html#sklearn.preprocessing.MaxAbsScaler "sklearn.preprocessing.MaxAbsScaler") 實現。
使用這種縮放的目的包括實現特征極小方差的魯棒性以及在稀疏矩陣中保留零元素。
以下是一個將簡單的數據矩陣縮放到``\[0, 1\]``的例子:
```
>>> X_train = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
...
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5 , 0. , 1. ],
[ 1. , 0.5 , 0.33333333],
[ 0. , 1. , 0. ]])
```
同樣的轉換實例可以被用與在訓練過程中不可見的測試數據:實現和訓練數據一致的縮放和移位操作:
```
>>> X_test = np.array([[ -3., -1., 4.]])
>>> X_test_minmax = min_max_scaler.transform(X_test)
>>> X_test_minmax
array([[-1.5 , 0. , 1.66666667]])
```
可以檢查縮放器(scaler)屬性,來觀察在訓練集中學習到的轉換操作的基本性質:
```
>>> min_max_scaler.scale_
array([ 0.5 , 0.5 , 0.33...])
>>> min_max_scaler.min_
array([ 0. , 0.5 , 0.33...])
```
如果給 [`MinMaxScaler`](generated/sklearn.preprocessing.MinMaxScaler.html#sklearn.preprocessing.MinMaxScaler "sklearn.preprocessing.MinMaxScaler") 提供一個明確的 `feature_range=(min, max)` ,完整的公式是:
```
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std * (max - min) + min
```
類 [`MaxAbsScaler`](generated/sklearn.preprocessing.MaxAbsScaler.html#sklearn.preprocessing.MaxAbsScaler "sklearn.preprocessing.MaxAbsScaler") 的工作原理非常相似,但是它只通過除以每個特征的最大值將訓練數據特征縮放至 `[-1, 1]` 范圍內,這就意味著,訓練數據應該是已經零中心化或者是稀疏數據。 例子::用先前例子的數據實現最大絕對值縮放操作。
以下是使用上例中數據運用這個縮放器的例子:
```
>>> X_train = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
...
>>> max_abs_scaler = preprocessing.MaxAbsScaler()
>>> X_train_maxabs = max_abs_scaler.fit_transform(X_train)
>>> X_train_maxabs # doctest +NORMALIZE_WHITESPACE^
array([[ 0.5, -1. , 1. ],
[ 1. , 0. , 0. ],
[ 0. , 1. , -0.5]])
>>> X_test = np.array([[ -3., -1., 4.]])
>>> X_test_maxabs = max_abs_scaler.transform(X_test)
>>> X_test_maxabs
array([[-1.5, -1. , 2. ]])
>>> max_abs_scaler.scale_
array([ 2., 1., 2.])
```
在 [`scale`](generated/sklearn.preprocessing.scale.html#sklearn.preprocessing.scale "sklearn.preprocessing.scale") 模塊中進一步提供了方便的功能。當你不想創建對象時,可以使用如 [`minmax_scale`](generated/sklearn.preprocessing.minmax_scale.html#sklearn.preprocessing.minmax_scale "sklearn.preprocessing.minmax_scale") 以及 [`maxabs_scale`](generated/sklearn.preprocessing.maxabs_scale.html#sklearn.preprocessing.maxabs_scale "sklearn.preprocessing.maxabs_scale") 。
### 4.3.1.2. 縮放稀疏(矩陣)數據
中心化稀疏(矩陣)數據會破壞數據的稀疏結構,因此很少有一個比較明智的實現方式。但是縮放稀疏輸入是有意義的,尤其是當幾個特征在不同的量級范圍時。
[`MaxAbsScaler`](generated/sklearn.preprocessing.MaxAbsScaler.html#sklearn.preprocessing.MaxAbsScaler "sklearn.preprocessing.MaxAbsScaler") 以及 [`maxabs_scale`](generated/sklearn.preprocessing.maxabs_scale.html#sklearn.preprocessing.maxabs_scale "sklearn.preprocessing.maxabs_scale") 是專為縮放數據而設計的,并且是縮放數據的推薦方法。但是, [`scale`](generated/sklearn.preprocessing.scale.html#sklearn.preprocessing.scale "sklearn.preprocessing.scale") 和 [`StandardScaler`](generated/sklearn.preprocessing.StandardScaler.html#sklearn.preprocessing.StandardScaler "sklearn.preprocessing.StandardScaler") 也能夠接受 `scipy.sparse` 作為輸入,只要參數 `with_mean=False` 被準確傳入它的構造器。否則會出現 `ValueError` 的錯誤,因為默認的中心化會破壞稀疏性,并且經常會因為分配過多的內存而使執行崩潰。 [`RobustScaler`](generated/sklearn.preprocessing.RobustScaler.html#sklearn.preprocessing.RobustScaler "sklearn.preprocessing.RobustScaler") 不能適應稀疏輸入,但你可以在稀疏輸入使用 `transform` 方法。
注意,縮放器同時接受壓縮的稀疏行和稀疏列(參見 `scipy.sparse.csr_matrix` 以及 `scipy.sparse.csc_matrix` )。任何其他稀疏輸入將會 **轉化為壓縮稀疏行表示** 。為了避免不必要的內存復制,建議在上游(早期)選擇CSR或CSC表示。
最后,最后,如果已經中心化的數據并不是很大,使用 `toarray` 方法將輸入的稀疏矩陣顯式轉換為數組是另一種選擇。
### 4.3.1.3. 縮放有離群值的數據
如果你的數據包含許多異常值,使用均值和方差縮放可能并不是一個很好的選擇。這種情況下,你可以使用 [`robust_scale`](generated/sklearn.preprocessing.robust_scale.html#sklearn.preprocessing.robust_scale "sklearn.preprocessing.robust_scale") 以及 [`RobustScaler`](generated/sklearn.preprocessing.RobustScaler.html#sklearn.preprocessing.RobustScaler "sklearn.preprocessing.RobustScaler") 作為替代品。它們對你的數據的中心和范圍使用更有魯棒性的估計。
參考:
更多關于中心化和縮放數據的重要性討論在此FAQ中提及: [Should I normalize/standardize/rescale the data?](http://www.faqs.org/faqs/ai-faq/neural-nets/part2/section-16.html)
Scaling vs Whitening 有時候獨立地中心化和縮放數據是不夠的,因為下游的機器學習模型能夠對特征之間的線性依賴做出一些假設(這對模型的學習過程來說是不利的)。
要解決這個問題,你可以使用 [`sklearn.decomposition.PCA`](generated/sklearn.decomposition.PCA.html#sklearn.decomposition.PCA "sklearn.decomposition.PCA") 或 [`sklearn.decomposition.RandomizedPCA`](generated/sklearn.decomposition.RandomizedPCA.html#sklearn.decomposition.RandomizedPCA "sklearn.decomposition.RandomizedPCA") 并指定參數 `whiten=True` 來更多移除特征間的線性關聯。
在回歸中縮放目標變量
[`scale`](generated/sklearn.preprocessing.scale.html#sklearn.preprocessing.scale "sklearn.preprocessing.scale") 以及 [`StandardScaler`](generated/sklearn.preprocessing.StandardScaler.html#sklearn.preprocessing.StandardScaler "sklearn.preprocessing.StandardScaler") 可以直接處理一維數組。在回歸中,縮放目標/相應變量時非常有用。
### 4.3.1.4. 核矩陣的中心化
如果你有一個核矩陣  ,它計算由函數  定義的特征空間的點積,那么一個 [`KernelCenterer`](generated/sklearn.preprocessing.KernelCenterer.html#sklearn.preprocessing.KernelCenterer "sklearn.preprocessing.KernelCenterer") 類能夠轉化這個核矩陣,通過移除特征空間的平均值,使它包含由函數  定義的內部產物。
## 4.3.2. 非線性轉換
類似于縮放, [`QuantileTransformer`](generated/sklearn.preprocessing.QuantileTransformer.html#sklearn.preprocessing.QuantileTransformer "sklearn.preprocessing.QuantileTransformer") 類將每個特征縮放在同樣的范圍或分布情況下。但是,通過執行一個秩轉換能夠使異常的分布平滑化,并且能夠比縮放更少地受到離群值的影響。但是它的確使特征間及特征內的關聯和距離失真了。
[`QuantileTransformer`](generated/sklearn.preprocessing.QuantileTransformer.html#sklearn.preprocessing.QuantileTransformer "sklearn.preprocessing.QuantileTransformer") 類以及 [`quantile_transform`](generated/sklearn.preprocessing.quantile_transform.html#sklearn.preprocessing.quantile_transform "sklearn.preprocessing.quantile_transform") 函數提供了一個基于分位數函數的無參數轉換,將數據映射到了零到一的均勻分布上:
```
>>> from sklearn.datasets import load_iris
>>> from sklearn.model_selection import train_test_split
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
>>> quantile_transformer = preprocessing.QuantileTransformer(random_state=0)
>>> X_train_trans = quantile_transformer.fit_transform(X_train)
>>> X_test_trans = quantile_transformer.transform(X_test)
>>> np.percentile(X_train[:, 0], [0, 25, 50, 75, 100])
array([ 4.3, 5.1, 5.8, 6.5, 7.9])
```
這個特征是萼片的厘米單位的長度。一旦應用分位數轉換,這些元素就接近于之前定義的百分位數:
```
>>> np.percentile(X_train_trans[:, 0], [0, 25, 50, 75, 100])
...
array([ 0.00... , 0.24..., 0.49..., 0.73..., 0.99... ])
```
這可以在具有類似形式的獨立測試集上確認:
```
>>> np.percentile(X_test[:, 0], [0, 25, 50, 75, 100])
...
array([ 4.4 , 5.125, 5.75 , 6.175, 7.3 ])
>>> np.percentile(X_test_trans[:, 0], [0, 25, 50, 75, 100])
...
array([ 0.01..., 0.25..., 0.46..., 0.60... , 0.94...])
```
也可以通過設置 `output_distribution='normal'` 將轉換后的數據映射到正態分布:
```
>>> quantile_transformer = preprocessing.QuantileTransformer(
... output_distribution='normal', random_state=0)
>>> X_trans = quantile_transformer.fit_transform(X)
>>> quantile_transformer.quantiles_
array([[ 4.3..., 2..., 1..., 0.1...],
[ 4.31..., 2.02..., 1.01..., 0.1...],
[ 4.32..., 2.05..., 1.02..., 0.1...],
...,
[ 7.84..., 4.34..., 6.84..., 2.5...],
[ 7.87..., 4.37..., 6.87..., 2.5...],
[ 7.9..., 4.4..., 6.9..., 2.5...]])
```
這樣,輸入的中值稱為輸出的平均值,并且以0為中心。正常輸出被剪切,使得輸入的最小和最大值分別對應于1e-7和1-1e-7分位數——在變換下不會變得無限大。
## 4.3.3. 歸一化
**歸一化** 是 **縮放單個樣本以具有單位范數** 的過程。如果你計劃使用二次形式(如點積或任何其他核函數)來量化任何樣本間的相似度,則此過程將非常有用。
這個觀點基于 [向量空間模型(Vector Space Model)](https://en.wikipedia.org/wiki/Vector_Space_Model) ,經常在文本分類和內容聚類中使用.
函數 [`normalize`](generated/sklearn.preprocessing.normalize.html#sklearn.preprocessing.normalize "sklearn.preprocessing.normalize") 提供了一個快速簡單的方法在類似數組的數據集上執行操作,使用 `l1` 或 `l2` 范式:
```
>>> X = [[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]]
>>> X_normalized = preprocessing.normalize(X, norm='l2')
>>> X_normalized
array([[ 0.40..., -0.40..., 0.81...],
[ 1. ..., 0. ..., 0. ...],
[ 0. ..., 0.70..., -0.70...]])
```
`preprocessing` 預處理模塊提供的 [`Normalizer`](generated/sklearn.preprocessing.Normalizer.html#sklearn.preprocessing.Normalizer "sklearn.preprocessing.Normalizer") 工具類使用 `Transformer` API 實現了相同的操作(即使在這種情況下, `fit` 方法是無用的:該類是無狀態的,因為該操作獨立對待樣本).
因此這個類適用于 [`sklearn.pipeline.Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 的早期步驟:
```
>>> normalizer = preprocessing.Normalizer().fit(X) # fit does nothing
>>> normalizer
Normalizer(copy=True, norm='l2')
```
在這之后歸一化實例可以被使用在樣本向量中,像任何其他轉換器一樣:
```
>>> normalizer.transform(X)
array([[ 0.40..., -0.40..., 0.81...],
[ 1. ..., 0. ..., 0. ...],
[ 0. ..., 0.70..., -0.70...]])
>>> normalizer.transform([[-1., 1., 0.]])
array([[-0.70..., 0.70..., 0. ...]])
```
稀疏(數據)輸入
函數 [`normalize`](generated/sklearn.preprocessing.normalize.html#sklearn.preprocessing.normalize "sklearn.preprocessing.normalize") 以及類 [`Normalizer`](generated/sklearn.preprocessing.Normalizer.html#sklearn.preprocessing.Normalizer "sklearn.preprocessing.Normalizer") 接收 **來自scipy.sparse的密集類數組數據和稀疏矩陣** 作為輸入。
對于稀疏輸入,在被提交給高效Cython例程前,數據被 **轉化為壓縮的稀疏行形式** (參見 `scipy.sparse.csr_matrix` )。為了避免不必要的內存復制,推薦在上游選擇CSR表示。
## 4.3.4. 二值化
### 4.3.4.1. 特征二值化
**特征二值化** 是 **將數值特征用閾值過濾得到布爾值** 的過程。這對于下游的概率型模型是有用的,它們假設輸入數據是多值 [伯努利分布(Bernoulli distribution)](https://en.wikipedia.org/wiki/Bernoulli_distribution) 。例如這個例子 [`sklearn.neural_network.BernoulliRBM`](generated/sklearn.neural_network.BernoulliRBM.html#sklearn.neural_network.BernoulliRBM "sklearn.neural_network.BernoulliRBM") 。
即使歸一化計數(又名術語頻率)和TF-IDF值特征在實踐中表現稍好一些,文本處理團隊也常常使用二值化特征值(這可能會簡化概率估計)。
相比于 [`Normalizer`](generated/sklearn.preprocessing.Normalizer.html#sklearn.preprocessing.Normalizer "sklearn.preprocessing.Normalizer") ,實用程序類 [`Binarizer`](generated/sklearn.preprocessing.Binarizer.html#sklearn.preprocessing.Binarizer "sklearn.preprocessing.Binarizer") 也被用于 [`sklearn.pipeline.Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 的早期步驟中。因為每個樣本被當做是獨立于其他樣本的,所以 `fit` 方法是無用的:
```
>>> X = [[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]]
>>> binarizer = preprocessing.Binarizer().fit(X) # fit does nothing
>>> binarizer
Binarizer(copy=True, threshold=0.0)
>>> binarizer.transform(X)
array([[ 1., 0., 1.],
[ 1., 0., 0.],
[ 0., 1., 0.]])
```
也可以為二值化器賦一個閾值:
```
>>> binarizer = preprocessing.Binarizer(threshold=1.1)
>>> binarizer.transform(X)
array([[ 0., 0., 1.],
[ 1., 0., 0.],
[ 0., 0., 0.]])
```
相比于 [`StandardScaler`](generated/sklearn.preprocessing.StandardScaler.html#sklearn.preprocessing.StandardScaler "sklearn.preprocessing.StandardScaler") 和 [`Normalizer`](generated/sklearn.preprocessing.Normalizer.html#sklearn.preprocessing.Normalizer "sklearn.preprocessing.Normalizer") 類的情況,預處理模塊提供了一個相似的函數 [`binarize`](generated/sklearn.preprocessing.binarize.html#sklearn.preprocessing.binarize "sklearn.preprocessing.binarize") ,以便不需要轉換接口時使用。
稀疏輸入
[`binarize`](generated/sklearn.preprocessing.binarize.html#sklearn.preprocessing.binarize "sklearn.preprocessing.binarize") 以及 [`Binarizer`](generated/sklearn.preprocessing.Binarizer.html#sklearn.preprocessing.Binarizer "sklearn.preprocessing.Binarizer") 接收 **來自scipy.sparse的密集類數組數據以及稀疏矩陣作為輸入** 。
對于稀疏輸入,數據被 **轉化為壓縮的稀疏行形式** (參見 `scipy.sparse.csr_matrix` )。為了避免不必要的內存復制,推薦在上游選擇CSR表示。
## 4.3.5. 分類特征編碼
在機器學習中,特征經常不是數值型的而是分類型的。舉個例子,一個人可能有 `["male", "female"]` , `["from Europe", "from US", "from Asia"]` , `["uses Firefox", "uses Chrome", "uses Safari", "uses Internet Explorer"]` 等分類的特征。這些特征能夠被有效地編碼成整數,比如 `["male", "from US", "uses Internet Explorer"]` 可以被表示為 `[0, 1, 3]` , `["female", "from Asia", "uses Chrome"]` 表示為 `[1, 2, 1]` 。
這個的整數特征表示并不能在scikit-learn的估計器中直接使用,因為這樣的連續輸入,估計器會認為類別之間是有序的,但實際卻是無序的。(例如:瀏覽器的類別數據則是任意排序的)
一種將分類特征轉換為能夠被scikit-learn中模型使用的編碼是one-of-K或one-hot編碼,在 [`OneHotEncoder`](generated/sklearn.preprocessing.OneHotEncoder.html#sklearn.preprocessing.OneHotEncoder "sklearn.preprocessing.OneHotEncoder") 中實現。這個類使用 `m` 個可能值轉換為 `m` 值化特征,將分類特征的每個元素轉化為一個值。
考慮如下例子:
```
>>> enc = preprocessing.OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
handle_unknown='error', n_values='auto', sparse=True)
>>> enc.transform([[0, 1, 3]]).toarray()
array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])
```
默認情況下,每個特征使用幾維的數值由數據集自動推斷。當然,你也可以通過使用參數``n\_values``來精確指定。 在我們的例子數據集中,有兩個可能得性別類別,三個洲,四個網絡瀏覽器。接著,我們訓練編碼算法,并用來對一個樣本數據進行轉換。 在結果中,前兩個數值是性別編碼,緊接著的三個數值是洲編碼,最后的四個數值是瀏覽器編碼
注意,如果訓練集中有丟失的分類特征值,必須顯式地設置 `n_values` ,舉個例子,
```
>>> enc = preprocessing.OneHotEncoder(n_values=[2, 3, 4])
>>> # 注意到第二、三個特征是不全的
>>> # features
>>> enc.fit([[1, 2, 3], [0, 2, 0]])
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
handle_unknown='error', n_values=[2, 3, 4], sparse=True)
>>> enc.transform([[1, 0, 0]]).toarray()
array([[ 0., 1., 1., 0., 0., 1., 0., 0., 0.]])
```
參見 [從字典類型加載特征](feature_extraction.html#dict-feature-extraction) ,它對于分類特征代表一個dict,而不是整數。
## 4.3.6. 缺失值插補
因為各種各樣的原因,真實世界中的許多數據集都包含缺失數據,這類數據經常被編碼成空格、NaNs,或者是其他的占位符。但是這樣的數據集并不能scikit-learn學習算法兼容,因為大多的學習算法都默認假設數組中的元素都是數值,因而所有的元素都有自己的意義。 使用不完整的數據集的一個基本策略就是舍棄掉整行或整列包含缺失值的數據。但是這樣就付出了舍棄可能有價值數據(即使是不完整的 )的代價。 處理缺失數值的一個更好的策略就是從已有的數據推斷出缺失的數值。
[`Imputer`](generated/sklearn.preprocessing.Imputer.html#sklearn.preprocessing.Imputer "sklearn.preprocessing.Imputer") 類提供了估算缺失值的基本策略,使用缺失值所在的行/列中的平均值、中位數或者眾數來填充。這個類也支持不同的缺失值編碼。
以下代碼段演示了如何使用包含缺失值的列(軸0)的平均值來替換編碼為 `np.nan` 的缺失值:
```
>>> import numpy as np
>>> from sklearn.preprocessing import Imputer
>>> imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
>>> imp.fit([[1, 2], [np.nan, 3], [7, 6]])
Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
>>> X = [[np.nan, 2], [6, np.nan], [7, 6]]
>>> print(imp.transform(X))
[[ 4. 2. ]
[ 6. 3.666...]
[ 7. 6. ]]
```
[`Imputer`](generated/sklearn.preprocessing.Imputer.html#sklearn.preprocessing.Imputer "sklearn.preprocessing.Imputer") 類也支持稀疏矩陣:
```
>>> import scipy.sparse as sp
>>> X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]])
>>> imp = Imputer(missing_values=0, strategy='mean', axis=0)
>>> imp.fit(X)
Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0)
>>> X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]])
>>> print(imp.transform(X_test))
[[ 4. 2. ]
[ 6. 3.666...]
[ 7. 6. ]]
```
注意,缺失值被編碼為0,因此隱式地存儲在矩陣中。當缺失值比可觀察到的值多的時候,這種格式是合適的。
[`Imputer`](generated/sklearn.preprocessing.Imputer.html#sklearn.preprocessing.Imputer "sklearn.preprocessing.Imputer") 可以在 Pipeline 中用作構建支持插補的合成模型。參見 [Imputing missing values before building an estimator](../auto_examples/plot_missing_values.html#sphx-glr-auto-examples-plot-missing-values-py) 。
## 4.3.7. 生成多項式特征
在機器學習中,通過增加一些輸入數據的非線性特征來增加模型的復雜度通常是有效的。一個簡單通用的辦法是使用多項式特征,這可以獲得特征的更高維度和互相間關系的項。這在 [`PolynomialFeatures`](generated/sklearn.preprocessing.PolynomialFeatures.html#sklearn.preprocessing.PolynomialFeatures "sklearn.preprocessing.PolynomialFeatures") 中實現:
```
>>> import numpy as np
>>> from sklearn.preprocessing import PolynomialFeatures
>>> X = np.arange(6).reshape(3, 2)
>>> X
array([[0, 1],
[2, 3],
[4, 5]])
>>> poly = PolynomialFeatures(2)
>>> poly.fit_transform(X)
array([[ 1., 0., 1., 0., 0., 1.],
[ 1., 2., 3., 4., 6., 9.],
[ 1., 4., 5., 16., 20., 25.]])
```
X 的特征已經從  轉換為  。
在一些情況下,只需要特征間的交互項,這可以通過設置 `interaction_only=True` 來得到:
```
>>> X = np.arange(9).reshape(3, 3)
>>> X
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> poly = PolynomialFeatures(degree=3, interaction_only=True)
>>> poly.fit_transform(X)
array([[ 1., 0., 1., 2., 0., 0., 2., 0.],
[ 1., 3., 4., 5., 12., 15., 20., 60.],
[ 1., 6., 7., 8., 42., 48., 56., 336.]])
```
X的特征已經從  轉換為  。
注意,當使用多項的 [:ref:`svm\_kernels`時 ,多項式特征被隱式地使用在 `核函數(kernel methods) <https://en.wikipedia.org/wiki/Kernel\_method>`\_](#id14) 中(比如, [`sklearn.svm.SVC`](generated/sklearn.svm.SVC.html#sklearn.svm.SVC "sklearn.svm.SVC") , [`sklearn.decomposition.KernelPCA`](generated/sklearn.decomposition.KernelPCA.html#sklearn.decomposition.KernelPCA "sklearn.decomposition.KernelPCA") )。
創建并使用多項式特征的嶺回歸實例請見 [Polynomial interpolation](../auto_examples/linear_model/plot_polynomial_interpolation.html#sphx-glr-auto-examples-linear-model-plot-polynomial-interpolation-py) 。
## 4.3.8. 自定義轉換器
在機器學習中,想要將一個已有的 Python 函數轉化為一個轉換器來協助數據清理或處理。可以使用 [`FunctionTransformer`](generated/sklearn.preprocessing.FunctionTransformer.html#sklearn.preprocessing.FunctionTransformer "sklearn.preprocessing.FunctionTransformer") 從任意函數中實現一個轉換器。例如,在一個管道中構建一個實現日志轉換的轉化器,這樣做:
```
>>> import numpy as np
>>> from sklearn.preprocessing import FunctionTransformer
>>> transformer = FunctionTransformer(np.log1p)
>>> X = np.array([[0, 1], [2, 3]])
>>> transformer.transform(X)
array([[ 0. , 0.69314718],
[ 1.09861229, 1.38629436]])
```
使用一個 [`FunctionTransformer`](generated/sklearn.preprocessing.FunctionTransformer.html#sklearn.preprocessing.FunctionTransformer "sklearn.preprocessing.FunctionTransformer") 類來做定制化特征選擇的例子,請見 [Using FunctionTransformer to select columns](../auto_examples/preprocessing/plot_function_transformer.html#sphx-glr-auto-examples-preprocessing-plot-function-transformer-py) 。
- scikit-learn 0.19 中文文檔
- 用戶指南
- 1. 監督學習
- 1.1. 廣義線性模型
- 1.2. 線性和二次判別分析
- 1.3. 內核嶺回歸
- 1.4. 支持向量機
- 1.5. 隨機梯度下降
- 1.6. 最近鄰
- 1.7. 高斯過程
- 1.8. 交叉分解
- 1.9. 樸素貝葉斯
- 1.10. 決策樹
- 1.11. 集成方法
- 1.12. 多類和多標簽算法
- 1.13. 特征選擇
- 1.14. 半監督學習
- 1.15. 等式回歸
- 1.16. 概率校準
- 1.17. 神經網絡模型(有監督)
- 2. 無監督學習
- 2.1. 高斯混合模型
- 2.2. 流形學習
- 2.3. 聚類
- 2.4. 雙聚類
- 2.5. 分解成分中的信號(矩陣分解問題)
- 2.6. 協方差估計
- 2.7. 經驗協方差
- 2.8. 收斂協方差
- 2.9. 稀疏逆協方差
- 2.10. Robust 協方差估計
- 2.11. 新奇和異常值檢測
- 2.12. 密度估計
- 2.13. 神經網絡模型(無監督)
- 3. 模型選擇和評估
- 3.1. 交叉驗證:評估估算器的表現
- 3.2. 調整估計器的超參數
- 3.3. 模型評估: 量化預測的質量
- 3.4. 模型持久化
- 3.5. 驗證曲線: 繪制分數以評估模型
- 4. 數據集轉換
- 4.1. Pipeline(管道)和 FeatureUnion(特征聯合): 合并的評估器
- 4.2. 特征提取
- 4.3. 預處理數據
- 4.4. 無監督降維
- 4.5. 隨機投影
- 4.6. 內核近似
- 4.7. 成對的矩陣, 類別和核函數
- 4.8. 預測目標 (y) 的轉換
- 5. 數據集加載工具
- 6. 大規模計算的策略: 更大量的數據
- 7. 計算性能
- 教程
- 使用 scikit-learn 介紹機器學習
- 關于科學數據處理的統計學習教程
- 機器學習: scikit-learn 中的設置以及預估對象
- 監督學習:從高維觀察預測輸出變量
- 模型選擇:選擇估計量及其參數
- 無監督學習: 尋求數據表示
- 把它們放在一起
- 尋求幫助
- 處理文本數據
- 選擇正確的評估器(estimator)
- 外部資源,視頻和談話