您當前的位置:首頁 > 體育

特徵離散化(分箱)綜述

作者:由 馬東<em>什麼</e 發表于 體育時間:2019-09-23

菁華離散什麼意思

連續特徵的離散化:在什麼情況下將連續的特徵離散化之後可以獲得更好的效果?

這個是原文地址,查了一下百度,基本上csdn、部落格元上的相關答案都是抄襲的這一篇回答。

下面的內容還挺多的,所以除了放在特徵工程專欄裡也會放到面經的專欄裡。

首先from wiki給出一個標準的連續特徵離散化的定義:

在統計和機器學習中,離散化是指將連續屬性,特徵或變數轉換或劃分為離散或標稱屬性/特徵/變數/間隔的過程。這在建立機率質量函式時非常有用 - 正式地,在密度估計中。它是一種離散化的形式,也可以是分組,如製作直方圖。每當連續資料離散化時,總會存在一定程度的離散化誤差。目標是將數量減少到手頭的建模目的可忽略不計的水平。

在銀行風控模型的建模過程中常常涉及到連續特徵的離散化,一般來說比較常見的是使用線性迴歸、邏輯迴歸的時候常常會對連續特徵進行分箱,在建立分類模型時,常常需要對連續變數離散化,特徵離散化後,模型會更穩定,降低了模型過擬合的風險。比如在建立申請評分卡模型時用logsitic作為基模型就需要對連續變數進行離散化,離散化通常採用分箱法。下面來談談為什麼我們要進行連續特徵離散化。

離散特徵的增加和減少都很容易,易於模型的快速迭代,比如說我們當前訓練集的年齡是20~30歲,假設在20~30之間分了5個箱子離散化然後onehot展開,下一次訓練的時候如果出現超過30歲的特徵,那麼直接增加一列0-1特徵用來表示使用者是否超過30歲即可;

稀疏向量內積乘法運算速度快,計算結果方便儲存,容易擴充套件,稀疏矩陣可以使用稀疏矩陣的儲存方式,比如python中的csr_matrix模組,透過稀疏矩陣的儲存方式對原始資料進行了壓縮。

3。離散化後的特徵對異常資料有很強的魯棒性:比如一個特徵是年齡>30是1,否則0。如果特徵沒有離散化,一個異常資料“年齡300歲”會給模型造成很大的干擾;

4、特徵離散化後,模型會更穩定,比如如果對使用者年齡離散化,20-30作為一個區間,不會因為一個使用者年齡長了一歲就變成一個完全不同的人。當然處於區間相鄰處的樣本會剛好相反,所以怎麼劃分區間是門學問,很多時候涉及到業務知識層面的東西;

5。特徵離散化以後,起到了簡化了邏輯迴歸模型的作用,降低了模型過擬合的風險。 (當使用連續特徵時,一個特徵對應於一個權重,那麼,如果這個特徵權重較大,模型就會很依賴於這個特徵,這個特徵的一個微小變化可能會導致最終結果產生很大的變化,這樣子的模型很危險,當遇到新樣本的時候很可能因為對這個特徵過分敏感而得到錯誤的分類結果,也就是泛化能力差,容易過擬合。而使用離散特徵的時候,一個特徵變成了多個,權重也變為多個,那麼之前連續特徵對模型的影響力就被分散弱化了,從而降低了過擬合的風險。)

(補充:3、4兩點實際上都是在論述模型穩定性的問題,我們需要知道:

為什麼在模型訓練前一般要進行異常值的處理?

異常值實際上就是資料中的噪聲,一定程度上容易導致過擬合,噪聲的存在破壞了資料本身的正常分佈,模型為了擬合異常值常常會給模型的訓練結果帶來偏差。

異常值的問題在機器學習中也是一塊獨立的領域,後續有時間會把相應的經典教材搬上來。)

6。離散化在onehot展開之後還可以進行特徵交叉,這一系列增大特徵維度的方法都可以增強邏輯迴歸這種線性模型的非線性表達能力,根據計算學習理論的covar定理可得,一般來說特徵維度越高則線性可分或線性可擬合的機率越高,當然過擬合的機率也越大。

從直觀的角度上來看,這一篇文章給了很生動的解釋:

https://

blog。csdn。net/u01108636

7/article/details/52879531

我們假設決策面為y=x^2,且模型是隻具有一維特徵x的線性模型,即模型的表達形式為:y=kx+b,如下圖所示:

特徵離散化(分箱)綜述

顯然,模型不能很好地擬合決策面,那麼,假如將x離散化成多個0/1特徵(one-hot編碼):

0

s1

s2

。。。

則新的模型表達形式如下:

y=k1x1+k2x2+k3x2+。。。+knxn+b

這時候新的決策面的表達形式為:

0

s1

s2

。。。

那麼,如下圖所示:

特徵離散化(分箱)綜述

7。 可以將缺失作為獨立的一類帶入模型。對於缺失值的處理和類別型特徵一樣,用-1來代替表示缺失值,把“缺失”也當作一種特徵

8。將所有變數變換到相似的尺度上。

最近恰好看到了關於離散化綜述的好文,搬運記憶,以後說不定就用上。

https://

blog。csdn。net/CalCuLuSe

arch/article/details/52751218

http://www。

go-gddq。com/down/2012-0

3/12031520159066。pdf

文中內容基本來自上述兩篇綜述,侵刪 !!!!!!!!

最優離散化問題已經被證明是一個NP-hard問題

下面詳細介紹一下各種各樣的離散化方法,特徵離散化的方法有很多,不同的分類的標準也很多,有分為

有監督和無監督的,動態的和靜態的,全域性的和區域性的,分列式和合並式的,單變數和多變數的以及直接的和增量式的。

上面的部落格找到了很好的總結圖:

特徵離散化(分箱)綜述

這種思維導圖是真的很好,一目瞭然,我們常見的等頻等寬決策樹chimerge均包含在內了。整體來看,特徵離散化的方法分為自底向上的merging合併的方案以及從頂向下的分裂的方案,這兩種思路下面均有對應的有監督和無監督的解決方案。 。。

有監督與無監督的離散化方法:

是否使用標籤進行離散化(分箱)決定了有監督還是無監督的離散化方法。有監督的離散化方法又分為建立在錯誤率基礎上的、建立在熵值基礎上的或者建立在統計資訊基礎上的。

比較常見的有等頻、等寬、聚類離散化,這類方案的問題在於對於分佈不均勻的資料並不適用,等頻和等寬都不能很好的反應“尖頭”的資料,除非人工手動干涉,聚類本身對於這類問題的表現也並不穩定,經常可能出現的情況就是“尖頭”資料有一部分分到平緩分佈的資料裡去,導致最終的分箱結果沒有代表性:

特徵離散化(分箱)綜述

為了克服無監督的離散化方法 的這些缺陷,使用類資訊來進行離散化的有監督的離散化方法逐漸發展起來。對於迴歸問題如果要分箱。。。目前沒有看到。。貌似用到提前分箱的時候提到的方案都是針對分類問題,不要要針對迴歸問題分箱也是可以的,比如下面會提到的動態和靜態分箱。

動態與靜態分箱

所謂靜態分箱就是我們常見的在模型訓練前的預分箱處理,而動態分箱是在模型執行的過程中自動完成的,比如決策樹實際上在訓練的過程中就能夠進行自動的分箱操作。

全域性與區域性(global vs. local)

另一個分法(dichotomy)是全域性與區域性。區域性離散化方法是在例項空間(instance space/subset of instances)的區域性區域(localized region)進行的離散化。然而全域性離散化使用了全體例項空間進行離散化。當例項空間的一個區域被用來離散化時區域性方法通常與動態離散化方法有關。

這個思路很有意思,個人理解,這種區域性轉換的場景可能更多應用於存在異常值的情況,直接將異常值替換為某一個並不是那麼異常的值,例如:

特徵離散化(分箱)綜述

“尖頭”資料明顯是很異常的值,在取樣驗證和模型訓練的時候都會產生不利的影響,那麼可以將其賦值為附近的常規的數。

自頂向下與自底向上(splitting(top-down) vs. merging(bottom-up)):

離散化方法也可以根據自頂向下與自底向上進行劃分。自頂向下方法以一個空的分割點(cut-points/split-points)列表開始,在離散化程序中一直不斷的往這個列表中透過splitting intervals新增新的分割點。自底向上以完整的列表開始,該列表用所有的連續特徵值作為分割點,在離散化程序中一直不斷的給這個列表中透過merging intervals移除的分割點。

直接與增量(direct vs. incremental):

直接方法同時劃分K個間隔的範圍(例如equal-width,equal-frequency,K-means),需要一個額外的輸入來決定間隔的個數。增量方法以一個簡單的離散化開始,並伴隨著改善或者提純(refinement)過程,需要停止準則來終止下一步的離散化。

典型的離散化過程通常由以下4步組成:

1) sort對離散化的特徵的連續值進行排序;

2) evaluate對為了合併的劃分的或者鄰近的間隔,評估分割點;

3) split or merge透過一些準則,劃分或者合併連續值的間隔;

4) stop停止離散化。

特徵離散化(分箱)綜述

排序sorting

對特徵的連續值進行降序或者升序排序都可以。如果不關心在離散化時進行排序,那麼排序的計算代價將是非常昂貴的。對於所有的特徵,排序在離散化開始之前完成,這將是一個全域性處理(global treatment),適用於將整個例項空間離散化。如果排序在過程的每一次迭代時完成,這將是一個區域性處理(local treatment),僅對整個例項空間的一個區域進行離散化。

選擇分割點 choosing a cut-point

排序之後,離散化過程接下來的一步是尋找最好的分割點,對連續值的範圍進行劃分,或者尋找最好的一對鄰近的間隔進行合併。一個典型的評價函式用來決定一次劃分或者合併與類別標籤的關係

。文獻中提到很多評價函式,諸如:熵測量、統計測量

。關於評價函式與它們的應用將在下一小節進行討論。

劃分/合併Splitting/merging

正如我們所知,對自頂向下的方法,間隔是劃分;然而對於自底向上的方法,間隔是合併。對於劃分,需要評價分割點,選擇最好的一個,並將連續值範圍劃分成兩部分。分別對每一部分進行離散化直到滿足停止準則。對於合併,評估鄰近的間隔,找到最好的間隔進行合併。離散過程一直持續,間隔數隨之減少,直到滿足停止準則。

停止準則stopping criteria

停止準則是為了終止離散過程。

它經常被元數和精度的折中所支配,因為這兩個是正互相關的(positively correlated)

。我們可以將k作為離散化的結果的元數設定一個上界,事實上,上界k的設定是遠小於N的,假設沒有特徵連續值的副本,停止準則可能是非常簡單的,諸如在一開始固定間隔數,或者一個稍微複雜一些的如評價函式。在下一章節描述不同的停止準則。

離散化方法對比comparison of discretization methods

針對不同離散化方法獲得的離散化資料,哪一個更好呢?看起來是一個簡單的問題,卻很難用簡單的答案來回答。這是因為不同的方法之間的比較是一個複雜的問題,它依賴於使用者在某一個特殊應用的需求。說複雜是因為不同方法的評價可以從多個方面來進行。我們列舉了3個重要的維度:

(1)總的間隔數,直觀的,間隔點越少,離散化結果越好;但是強加於資料呈現是有限的。這導致第二個維度。(2)離散化引起的不一致性的個數。它不應該大於離散化之前原始資料的不一致數。如果最終結果是從資料訓練一個分類器,應該考慮另一個觀點。(3)預測精度-離散化對預測精度的改善。

簡言之,我們至少需要三個維度的考慮:

簡化(simplicity)、一致性(consistency)、精度(accuracy)

。理想情況下,最好的離散化結果在這三方面應都有最高的得分。但事實上,它是不可能達到的,或者不需要的。為不同的離散化方法在這三方面提供一個均衡的觀點也是本文的目標。

簡化(simplicity)使用分割點的總數來定義的。精確度(accuracy)在交叉驗證模式下執行分類器可以獲得。一致性(consistency)是最小的不一致性計數值,可以透過以下3步計算而來(下面的描述中,模式pattern指沒有類別標籤的例項):(1)

如果兩個例項有著相同的屬性值,但是類別標籤不一樣,則這兩個例項是不一致的

;例如,如果兩個例項是(0 1;0)和(0 1;1),它們就是不一致的。(2)一個模式的計數值是這個模式出現在資料中的次數減去最大的類別標籤數;例如,假設有n個例項與這個模式相匹配,其中label1的個數是c1, label2的個數是c2,label3的個數是c3,其中c1+c2+c3=n。如果c3是這三個中最大的,則該模式的不一致性計數值為(n-c3)。(3)總的不一致性計數是一個特徵集合中所有可能的模式的不一致性計數值之和。(這一段沒有太深刻的理解和體會其實。。。)

4。離散化框架discretization framework

文獻中提到很多離散化方法。正如上面所述的一樣,根據不同的維度可以對這些方法進行分類。即:監督與無監督(supervised vs, unsupervised);動態與靜態(dynamic vs。 static);全域性與區域性(global vs。 local);自頂向下與自底向上(splitting(top-down) vs。 merging(bottom-up));直接與增量(direct vs。 incremental)。可以根據這些維度的不同組合來對這些方法進行分組。我們希望構建一個系統的、可擴充套件的、能覆蓋現在所有方法的框架。文獻中提到的每一種離散化方法離散化一個特徵:或者對連續值劃分間隔;或者合併鄰近的間隔。劃分和合並根據是否使用分類資訊可進一步分組成監督與無監督。

鑑於這些方面的考慮,我們提出了層次化框架(hierarchical framework),如下圖所示。

特徵離散化(分箱)綜述

透過兩種方法:劃分和合並,描述了不同的離散化測量(level1)。接著我們考慮了方式是監督還是無監督(level2)。進一步我們將使用相同離散化度量方法的分組在一起(level3),例如分箱(binning)和熵(entropy)。如下圖所示,監督與無監督劃分決定了不同的度量方法。因此概念上有用的劃分將不再詳細講述。

我們將討論如下表所示的基於劃分和合並的分類方法的現存的不同的度量方式。

特徵離散化(分箱)綜述

在以下兩個小節,將選擇典型的方法進行深入討論(in-deep discussion)。它們相關的或者派生的(related or derived)度量方法也會簡要涉及。對每一個離散化度量方式,我們主要給出:

(1)。 度量方式的定義;

(2)。 在離散化方法中的應用;

(3)。 使用的停止準則;

(4)。 對Iris資料集的離散化結果:每一個屬性的分割點;

在小節的最後,出於對比目的,我們給出了所有離散化度量方式的結果列表:不一致性的個數、離散化的分割點。

4.1劃分方法splitting method

我們以用於劃分離散化方法的通用演算法開始。

特徵離散化(分箱)綜述

在離散化過程中劃分演算法(splitting algorithm)由4步組成,它們是:

(1). 對特徵值排序;

(2). 搜尋合適的分割點;

(3). 根據分割點劃分連續值的範圍;

(4). 當滿足停止準則的時候停止離散化否則繼續;

文獻中提到很多劃分離散化度量方法:

分箱(binning)、熵(entropy)、獨立性(dependency)、精確度(accuracy)

分箱binning

Equal width or frequency

1R

熵entropy

ID3 type

D2

Ent-MDLP

Mantaras distance

獨立性dependency

Zeta

精確度accuracy

adaptive quantizer

4.2合併方法merging method

我們以採用合併或者自底向上方法的離散化通用演算法開始。

特徵離散化(分箱)綜述

在離散化過程中合併演算法由4個重要步驟組成,它們是:

(1)。 對值進行排序;

(2)。 找到最好的兩個相鄰間隔;

(3)。 把這一對合併成一個間隔;

(4)。 滿足停止條件時終止。

merge合併的方案:

chi-square measure

ChiMerge

chi2

4.3討論discussion

我們已經回顧了在劃分和合並歸類情況下的典型離散化方法。大部分方法是基於劃分方法的。我們使用Iris資料集作為一個例子展示了不同的離散化方法的結果。兩種度量方式(number of inconsistencies and number of cut-points)直覺上的關係是:分割點越多,不一致計數越少。仔細觀察表明(closer look)讓兩個計數值都少可能有一個妥協(middle ground)的方法。因此,我們應該旨在去讓兩個數值(number of inconsistencies and number of cut-points)都小。我們確實發現對於Iris資料一些方法比其他方法要好:

Ent-MDLP是劃分方法裡邊最好的;chi2是合併方法裡邊最好的。Chi2也表明,透過考慮一定程度的不一致性,在兩種度量方式之間達到折中也是可能的。除離散化之外(in addition to),Chi2也移除了具有一定程度的不一致性的特徵

在section2,我們透過5種不同的維度回顧了監督與無監督(supervised vs, unsupervised);動態與靜態(dynamic vs。 static);全域性與區域性(global vs。 local);自頂向下與自底向上(splitting(top-down) vs。 merging(bottom-up));直接與增量(direct vs。 incremental)的離散化方法。在多維觀點(muti-dimensional view)下我們又得到了另外一種型別的分組。如下表所示:

特徵離散化(分箱)綜述

對於上述分箱方法的細緻分類

很可惜,博主更新完這一篇之後沒有再寫了,下面的就我來完善一下

Splitting

1、我們首先來看splitting下的無監督的分箱方法,它是最早期的一種較為簡單的分箱方法,包括等頻、等距、聚類以及人工根據先驗來自定義分箱,除了人工自定義方法根據使用者經驗的好壞影響分箱結果的好壞之外,其它三種自動化的分箱方法的優勢在於

簡單好理解,並且無監督的方法不需要引入目標值

,但是也都都存在著較大的缺陷:

對不均勻的資料不適用,並且對異常值很敏感

,先說等寬分箱,如果資料分佈極端,兩邊資料多,中間資料很少,那麼很容易出現不少箱子裡面沒有資料,等頻雖然可以保證每個箱子裡的樣本數量大致相等,但是有可能出現不同箱子之間跨度太大的情況,比如上述出現異常值的情況,可能最終分箱的結果是一部分箱子的區間長度為10,另一部分箱子的區間長度為1000,同樣,對於聚類的方法,不均勻樣本和異常樣本的存在會導致聚類中心的向極端值偏移從而影響分箱結果,這三種分箱方法sklearn都已經做好了感動哭了。

sklearn。preprocessing。KBinsDiscretizer - scikit-learn 0。21。2 documentation

>>> X = [[-2, 1, -4, -1],

。。。 [-1, 2, -3, -0。5],

。。。 [ 0, 3, -2, 0。5],

。。。 [ 1, 4, -1, 2]]

>>> est = KBinsDiscretizer(n_bins=3, encode=‘ordinal’, strategy=‘uniform’)

>>> est。fit(X)

KBinsDiscretizer(。。。)

>>> Xt = est。transform(X)

>>> Xt

array([[ 0。, 0。, 0。, 0。],

[ 1。, 1。, 1。, 0。],

[ 2。, 2。, 2。, 1。],

[ 2。, 2。, 2。, 2。]])

sklearn的0。21版中的KBinsDiscretizer 目前支援等頻、等寬和聚類分箱。

另外還有提到的1R的分箱方案:

回家。。。有空再繼續寫。。。

上面的方案都是屬於無監督分箱,下面我們介紹下有監督分箱

下面用sklearn的api和sklearn的決策樹簡單做了一個基於cart tree的決策樹分箱,實現了sklearn原生的cart tree和lgb以及xgb tree分箱的功能,不知道效果如何。

from

sklearn。base

import

BaseEstimator

TransformerMixin

class

supervised_bins_Transformer

BaseEstimator

TransformerMixin

):

#我們這裡寫一個分箱的方法

def

__init__

self

task

=

‘Classification’

method

=

‘xgboost_tree’

):

self

task

=

task

self

method

=

method

#method 支援4種類型,一種是xgboost tree,一種是lightgbm tree,一種是sklearn tree

#一種是chimerge

def

fit

self

X

=

None

y

=

None

):

if

self

method

==

‘xgboost_tree’

if

self

task

==

‘Classification’

clf

=

xgb

XGBClassifier

n_estimators

=

1

else

clf

=

xgb

XGBRegressor

n_estimators

=

1

clf

fit

X

y

if

self

method

==

‘lightgbm_tree’

if

self

task

==

‘Classification’

clf

=

lgb

LGBMClassifier

n_estimators

=

1

else

clf

=

lgb

LGBMRegressor

n_estimators

=

1

clf

fit

X

values

reshape

-

1

1

),

y

if

self

method

==

‘sklearn_tree’

if

self

task

==

‘Classification’

clf

=

tree

DecisionTreeClassifier

()

else

clf

=

tree

DecisionTreeRegressor

()

clf

fit

X

values

reshape

-

1

1

),

y

tree_rules

=

clf

tree_

threshold

self

tree_rules

=

tree_rules

tree_rules

!=-

2

#sklearn 中的tree用-2判斷葉節點,-2不是一個分裂閾值要刪除

def

transform

self

X

):

return

np

digitize

X

self

tree_rules

Merging

說實話,好多給出的分箱方案我都沒聽說過,資料也找不到太多,emmm,一般來說一項技術如果市面上的資料太多,大機率是3種可能的結果:1、技術太新;2、技術缺陷太多;3、技術不錯但應用太窄價值不高 ,所以我還是挑比較常見的演算法來學習吧。。。看一大堆名字都不清楚啥意思的演算法我就不浪費時間再去研究了。。。。

https://

mp。weixin。qq。com/s?

__biz=MzIxNzc1NDgzMw==&mid=2247483991&idx=1&sn=158037a76cb356643a12ea926e827afe&chksm=97f5bfe9a08236ff1d5f9ddd4c604028f7953dda20a4986991faf884fad932a40f5826ff95c0&scene=21#wechat_redirect

https://

mp。weixin。qq。com/s?

__biz=MzA5Njc1MDA2Ng%3D%3D&idx=1&mid=2651650083&sn=a24381efa404500ae96ccfcc3716a614

關於卡方分佈、卡方分箱上面的兩個連結介紹的很直觀了,這裡就總結一下了,前人栽樹後人乘涼哈哈哈:

卡方分佈(chi-square distribution, χ2-distribution)是機率統計裡常用的一種機率分佈,也是統計推斷裡應用最廣泛的機率分佈之一,在假設檢驗與置信區間的計算中經常能見到卡方分佈的身影。

卡方分佈的定義如下:

若k個獨立的隨機變數Z1, Z2,。。。, Zk 滿足標準正態分佈 N(0,1) , 則這k個隨機變數的平方和:

特徵離散化(分箱)綜述

為服從自由度為k的卡方分佈,記作:

特徵離散化(分箱)綜述

卡方檢驗即χ2檢驗是以χ2分佈為基礎的一種假設檢驗方法,主要用於分類變數之間的獨立性檢驗。其基本思想是根據樣本資料推斷總體的分佈與期望分佈是否有顯著性差異,或者推斷兩個分類變數是否相關或者獨立。一般可以設原假設為 :

觀察頻數與期望頻數沒有差異,或者兩個變數相互獨立不相關。

實際應用中,我們先假設原假設成立,計算出卡方的值,卡方表示觀察值與理論值間的偏離程度。

卡方值的計算公式為:

特徵離散化(分箱)綜述

其中A為實際頻數,E為期望頻數。卡方值用於衡量實際值與理論值的差異程度,這也是卡方檢驗的核心思想。

卡方值包含了以下兩個資訊:

1.實際值與理論值偏差的絕對大小。

2.差異程度與理論值的相對大小。

上述計算的卡方值服從卡方分佈。根據卡方分佈,卡方統計量以及自由度,可以確定在原假設成立的情況下獲得當前統計量以及更極端情況的機率p。如果p很小,說明觀察值與理論值的偏離程度大,應該拒絕原假設。否則不能拒絕原假設。

根據上面連線裡給的原始碼寫了一個sklearn api形式的卡方分箱:

import numpy as np

import pandas as pd

from numba import jit,guvectorize,int64

from scipy。stats import chi2

import xgboost as xgb

import lightgbm as lgb

from sklearn import tree

from sklearn。base import BaseEstimator, TransformerMixin

class Chi2_Bins_Transformer(BaseEstimator,TransformerMixin):

def __init__(self,target,max_groups=-1,threshold=None,):

self。max_groups=max_groups

self。threshold=threshold

if self。max_groups ==-1:

if self。threshold is None:

cls_num = np。unique(target)。shape[0]

self。threshold = chi2。isf(0。05,df= cls_num - 1) ##透過查表設定卡方閾值

@staticmethod

def Chi2(arr):

#計算每行總頻數

R_N = arr。sum(axis=1)

#每列總頻數

C_N = arr。sum(axis=0)

#總頻數

N = arr。sum()

# 計算期望頻數 C_i * R_j / N。

E = np。ones(arr。shape)* C_N / N

E = (E。T * R_N)。T

square = (arr-E)**2/ E

#期望頻數為0時,做除數沒有意義,不計入卡方值

square[E==0] = 0

#卡方值

return square。sum()

@staticmethod

# @guvectorize([“(int64[:,:], float64[:],int64,float64)”], ‘(m,n),(m),(),()’,cache=True, \

# nopython=True)

def ChiMerge(freq,cutoffs,max_groups,threshold):

while True:

minvalue=None

minidx=None

for i in range(freq。shape[0]-1):

v=Chi2_Bins_Transformer。Chi2(freq[i:i+2])

if minvalue is None or minvalue>v:

minvalue=v

minidx=i

if (max_groups !=-1 and max_groups

or (threshold is not None and minvalue < threshold):

tmp=freq[minidx]+freq[minidx+1]

freq[minidx]=tmp

freq=np。delete(freq,minidx+1,0)

cutoffs = np。delete(cutoffs,minidx+1,0)

else:

break

def fit(self,data,col,target):

freq_tab = pd。crosstab(data[col],target)

freq = freq_tab。values

cutoffs = freq_tab。index。values

Chi2_Bins_Transformer。ChiMerge(freq,cutoffs,self。max_groups,self。threshold)

self。cutoffs=cutoffs

def transform(self,X):

return np。digitize(X,self。cutoffs)

本來想用numba來做加速的,發現numba針對於class的侷限性確實還是蠻大的,另外numba一般支援numpy的純數學運算的,對於一些邏輯運算(比如true,false之類的會報錯),也就是說我們用numba的nopython模式編譯的時候基本要保證函數里面的所有資料(包括臨時變數等)都要為number型,總之剛開始用坑還是蠻多的,而且除錯很麻煩,另外用object的模式編譯真的基本沒什麼加速有時候反而還會更慢坑爹。比較適合一些小而精簡的函式的最佳化比如:

特徵離散化(分箱)綜述

差不多離散化介紹到這裡吧,其它的連續值離散化的演算法接觸不多,就不費心去研究了。

標簽: 離散  分箱  方法  特徵  tree