Python sklearn學習之數據預處理——非線性轉換
文章目錄
1. 兩種常見的非線性轉換
1.1 分位數轉換
- 基本公式
- 公式說明
- x:特徵
- F:特徵的累積分佈函數
- G^(-1):期望輸出值分佈G的分位數函數
- 目的:將所有特徵置於相同的期望分佈中
- 公式成立的事實說明
- 如果X是具有連續累積分佈函數F的隨機變量,那麼F(X)均勻分佈在[0,1]
- 如果U是在[0,1]上的隨機分佈,那麼G^(-1)(U)有分佈G.
累積分佈函數:是概率密度函數的積分
概率密度函數:表示瞬時幅值落在某指定範圍內的概率
設累積分佈函數爲F,概率密度函數爲f,則可表示如下:
- 分位數轉換優勢:平滑了異常分佈,並且比縮放方法受異常值的影響更小
- 分位數轉換缺點:使特徵間及特徵內的關聯和距離失真了
1.2 冪變換
本質是一組參數變換,其目的是將數據從任意分佈映射到接近高斯分佈的位置
2. sklearn中非線性變換的實現
2.1 映射到均勻分佈
sklearn 將數據集映射到均勻分佈的方式主要是通過分位數轉換的方式實現,通過類QuantileTransformer 類以及quantile_transform 函數實現。
2.1.1QuantileTransformer類
- 類定義
def __init__(self, n_quantiles=1000, output_distribution='uniform',
ignore_implicit_zeros=False, subsample=int(1e5),
random_state=None, copy=True):
-
參數說明
- n_quantiles : int,optional(默認值= 1000或n_samples)
- 要計算的分位數。它對應於用於離散累積分佈函數的標記的數量。如果n_quantiles大於樣本數,則n_quantiles被設置爲樣本數,因爲較大數量的分位數不能給出累積分佈函數估計器的更好近似。
- output_distribution :str,optional(default =‘uniform’)
- 轉換數據的邊際分佈。選擇是“uniform”(默認)或“normal”
- ignore_implicit_zeros :boolean,optional(默認值= False)
- 僅適用於稀疏矩陣。如果爲True,則丟棄矩陣的稀疏條目以計算分位數統計。如果爲False,則將這些條目視爲零
- subsample : int,optional(default = 1e5)
- 用於估計計算效率的分位數的最大樣本數。注意,對於值相同的稀疏矩陣和密集矩陣,子採樣過程可能不同
- random_state : int,RandomState實例或None,可選(默認=None)
- 如果是int,則random_state是隨機數生成器使用的種子; 如果是RandomState實例,則random_state是隨機數生成器; 如果爲None,則隨機數生成器是np.random使用的RandomState實例。請注意,這通過二次採樣和平滑噪聲來使用。
- copy :略
- n_quantiles : int,optional(默認值= 1000或n_samples)
-
對象屬性
-
n_quantiles_ : 用於離散累積分佈函數的實際分位數
-
quantiles_: 值與參考對應之間的分位數矩陣
-
references_:
n_samples = X.shape[0] # 數組維度元組,或者說是樣本數 self.n_quantiles_ = max(1, min(self.n_quantiles, n_samples)) # 得到樣本數與分數數較小的值,爲了防止傳入空數組,所以需保證大於1 self.references_ = np.linspace(0, 1, self.n_quantiles_,endpoint=True)
-
-
例子
X_train_trans = preprocessing.QuantileTransformer(random_state=0).fit_transform(X_train)
- quantile_transform 函數
一如既往,quantile_transform 函數只是本質上也是創建QuantileTransformer 轉換器
n = QuantileTransformer(n_quantiles=n_quantiles,
output_distribution=output_distribution,
subsample=subsample,
ignore_implicit_zeros=ignore_implicit_zeros,
random_state=random_state,
copy=copy)
if axis == 0:
return n.fit_transform(X)
elif axis == 1:
return n.fit_transform(X.T).T
else:
raise ValueError("axis should be either equal to 0 or 1. Got"
" axis={}".format(axis))
2.2 映射到高斯分佈
冪變換是一類參數化的單調變換, 其目的是將數據從任何分佈映射到儘可能接近高斯分佈,以便穩定方差和最小化偏斜。
PowerTransformer 類提供了兩種冪變換,Yeo-Johnson transform 和 the Box-Cox transform
2.2.1 Yeo-Johnson transform變換
2.2.2 the Box-Cox transform變換
2.2.3 類說明
def __init__(self, method='yeo-johnson', standardize=True, copy=True):
-
參數說明
- method :可選,接受一個字符串值,默認是 ‘yeo-johnson’ ,
- ’yeo-johnson’ :指明冪變換方式以 Yeo-Johnson transform 方式實現,此種方式下數據集可以含有正負值
- the Box-Cox transform :指明冪變換方式以the Box-Cox transform 方式實現,此種方式下數據集只能是正值,不允許有負值
- standardize :可選,接受一個boolean值,默認是 ‘True’ ,設置爲True可將零均值單位方差歸一化應用於變換後的輸出
- copy :略
- method :可選,接受一個字符串值,默認是 ‘yeo-johnson’ ,
-
屬性
- lambdas_ : 得到一個浮點數組,轉換過程中所選擇的參數
self.lambdas_ = np.array([optim_function(col) for col in X.T])
-
例子
power = preprocessing.PowerTransformer(method='box-cox', standardize=False, copy=True)
X_lognormal = np.random.RandomState(616).lognormal(size=(3, 3))
power.fit_transform(X_lognormal)
# 注意沒有下面這種使用方式
# power.fit(X_lognormal).transform(X_lognormal)
- power_transform 函數
本質上是構造 PowerTransformer 對象並調用 fit_transform 實現
pt = PowerTransformer(method=method, standardize=standardize, copy=copy)
return pt.fit_transform(X)
2.2.4 拓展
實際上,利用2.1.1中的 QuantileTransformer 類也可以講數據集轉換爲正態分佈(通過設置 output_distribution
=‘normal’)。