Python版scorecardpy庫woebin函數使用

scorecardpy 是一款專門用于評分卡模型開發的 Python 庫,由謝士晨博士開發,該軟件包是R軟件包評分卡的Python版本。量級較輕,依賴更少,旨在簡化傳統信用風險計分卡模型的開發過程,使這些模型的構建更加高效且易于操作。

本文主要講解?scorecardpy 庫的變量分箱 woebin 函數的使用,讓你了解函數中每個入參的使用姿勢,快速高效地進行評分卡建模分析。分箱的原理在之前的?sklearn-邏輯回歸-制作評分卡 中有講過,可自行跳轉了解。

目錄

scorecardpy安裝

scorecardpy提供的功能

woebin 函數定義

woebin?函數參數解析

參數1:dt

參數2:y

check_y 函數對標簽值進行檢測

代碼解析

參數3:x

參數4:var_skip

參數5:breaks_list

參數6:special_values

參數7:count_distr_limit

參數8:stop_limit

IV增長率

卡方值

參數9:bin_num_limit

參數10:positive

positive?參數的設置

參數11:no_cores

參數12:print_step

參數取值詳解

使用建議

參數13:method

支持的分箱方法

1、tree(決策樹分箱)?:

?2、chimerge(卡方分箱)?:

使用建議

參數14:ignore_const_cols

參數15:ignore_datetime_cols

參數16:check_cate_num

參數17:replace_blank

參數18:save_breaks_list


scorecardpy安裝

使用 Python 包管理器 pip 進行安裝

pip install scorecardpy

scorecardpy提供的功能

為了使評分卡建模流程更加便捷,scorecardpy 庫對建模過程中的關鍵步驟都封裝好了函數,在不同環節可以調用不同的函數

  • 數據集劃分?:通過split_df函數將數據集分割成訓練集和測試集?
  • 變量篩選?:使用var_filter函數根據變量的缺失率、IV值、同值性等因素進行篩選
  • 變量分箱?:提供woebin函數進行變量分箱,并可以生成分箱的可視化圖表?
  • 評分轉換?:使用scorecard函數進行評分轉換?
  • 效果評估?:包括性能評估(perf_eva)和PSI(Population Stability Index)評估(perf_psi)?

woebin 函數定義

def woebin(dt, y, x=None, var_skip=None, breaks_list=None, special_values=None, stop_limit=0.1, count_distr_limit=0.05, bin_num_limit=8, # min_perc_fine_bin=0.02, min_perc_coarse_bin=0.05, max_num_bin=8, positive="bad|1", no_cores=None, print_step=0, method="tree",ignore_const_cols=True, ignore_datetime_cols=True, check_cate_num=True, replace_blank=True, save_breaks_list=None, **kwargs):pass

woebin 函數適用于對特征進行分箱(bining)和權重證據轉換(weight of evidence)的工具,它使用決策樹分箱或者卡方分箱的方法對變量進行最佳分箱。

默認 woe 計算是 ln(Distr_Bad_i/Distr_Good_i),如果需要實現 ln(Distr_Good_i/Distr_Bad_i),需要將入參 positive 設置為想反的值,比如 0 或者 'good'。

woebin?函數參數解析

參數1:dt

類型是?pandas.DataFrame,包含要分箱的特征和標簽變量 y 的 DataFrame

參數2:y

標簽值的變量名稱

傳入的 dt 中,標簽 y 列的取值不能有空的情況,如果檢測到空,對應的行將會被刪除,同時會提示?“There are NaNs in \'{}\' column”

    # remove na in yif dat[y].isnull().any():warnings.warn("There are NaNs in \'{}\' column. The rows with NaN in \'{}\' were removed from dat.".format(y,y))dat = dat.dropna(subset=[y])# dat = dat[pd.notna(dat[y])]

check_y 函數對標簽值進行檢測

check_y() 函數會對傳入數據的 y 值進行檢測,確保都是合理的,入參包含?dat, y, positive.

代碼解析
def check_y(dat, y, positive):""":param dat: 數據集,pd.DataFrame 類型:param y: 標簽y列名,string 類型,或者只有1個元素的 list 類型:param positive: 目標變量,string 類型:return: 數據集 dat"""positive = str(positive)# 數據集 dat 必須屬于 pd.DataFrame 類型數據,且至少有2列,(一列特征,一列標簽)if not isinstance(dat, pd.DataFrame):raise Exception("Incorrect inputs; dat should be a DataFrame.")elif dat.shape[1] <= 1:raise Exception("Incorrect inputs; dat should be a DataFrame with at least two columns.")# 如果 y 入參是 string 類型,在這里會被處理成只有1個元素的 list 類型數據y = str_to_list(y)# y 入參必須是只有1個元素,即一個數據集只能有一個標簽列if len(y) != 1:raise Exception("Incorrect inputs; the length of y should be one")y = y[0]# y 標簽列必須出現在數據集中if y not in dat.columns:raise Exception("Incorrect inputs; there is no \'{}\' column in dat.".format(y))# 如果有數據的標簽取值為空,則該數據會被刪除,不參與分箱評分if dat[y].isnull().any():warnings.warn("There are NaNs in \'{}\' column. The rows with NaN in \'{}\' were removed from dat.".format(y, y))dat = dat.dropna(subset=[y])# y 列數據轉換成 int 類型數據if is_numeric_dtype(dat[y]):dat.loc[:, y] = dat[y].apply(lambda x: x if pd.isnull(x) else int(x))  # dat[y].astype(int)# y 的取值枚舉必須是2中,否則拋出異常unique_y = np.unique(dat[y].values)if len(unique_y) == 2:# unique_y 存儲了y取值的枚舉,  positive 傳值必須有一個值屬于 unique_y 的某一個枚舉# re.search() 函數第一個入參是正則表達式,第二個入參是要搜索的字符串# positive 默認值為 'bad|1',表示搜索字符串中的 "bad" 或 "1"。# 假如 unique_y 取值為 [0, 1],positive取默認值,if 條件即判斷 True 是否包含在[False, True] 中if True in [bool(re.search(positive, str(v))) for v in unique_y]:y1 = dat[y]# re.split() 函數第一個入參是分隔符,第二個入參是字符串,代表使用分隔符將字符串分成一個列表# 因為 '|'是特殊字符,代表'或',因此前面要加轉義字符'\'# lambda 接收一個 dat[y] 中的取值,判斷這個取值是否出現在 positive 列表中,出現則為1,否則為0y2 = dat[y].apply(lambda x: 1 if str(x) in re.split('\|', positive) else 0)# y1 和 y2 兩個Series對象中的每個對應元素是否不相等。# 如果至少有一個元素不相等,.any()方法會返回True;如果所有元素都相等,則返回Falseif (y1 != y2).any():# 如果有不相等的,則將 y2 賦值給 dat[y] 列# loc() 函數接受兩個參數:第一個參數是行的選擇器,第二個參數是列的選擇器# [:, y]:這是.loc[]屬性中的選擇器參數。冒號:表示選擇所有的行,而y表示選擇名為y的列dat.loc[:, y] = y2  # dat[y] = y2warnings.warn("The positive value in \"{}\" was replaced by 1 and negative value by 0.".format(y))else:raise Exception("Incorrect inputs; the positive value in \"{}\" is not specified".format(y))else:raise Exception("Incorrect inputs; the length of unique values in y column \'{}\' != 2.".format(y))return dat

參數3:x

要分箱的特征列表,默認值是 None,如果該參數不傳,將會默認 dt 中所有的除了y的列,都會參與分箱

參數4:var_skip

不參與分箱的特征列表,如果傳入的是 string 類型,會自動轉換成一個元素的 list 類型,并參與分箱特征的排除

參數5:breaks_list

分箱的邊界值,是個 list 類型,默認一般是 None,如果該參數傳入了值,則會根據傳入的邊界值進行分箱。假設傳入的是 [0,10,20,30],使用左開右閉進行分箱,則會被分成 4 個箱子,即 (0,10],(10,20],(20,30],(30,+∞)

參數6:special_values

特殊值列表,默認是 None。如果傳入該參數,那么取值在該參數列表中的元素,將會被分到獨立的箱子中

假設傳入 [-90,-9999],那個取值為-90,-9999的都會在一個特殊箱子里

參數7:count_distr_limit

每個箱內的樣本數量占總樣本數量的最小占比,默認值是 0.05,即最小占比 5%

該參數可以確保分箱結果更加合理和實用,特別是在要處理不平衡數據集或需要嚴格控制復雜度時

通過限制每個箱內的最小樣本數,可以減少過擬合的風險,并提高模型在新數據上的泛化能力

需要注意的是,該參數的具體行為和效果可能受到其它參數(如分箱方法,分箱數量等)的影響,在使用時需要合理設置

參數8:stop_limit

控制分箱停止條件的參數,當統計量(比如IV增長率,卡方值)的增長率小于設置的 stop_limit 參數時,停止繼續分箱,取值范圍是 0-0.5,默認值是 0.1

該參數主要用于決定何時停止進一步的分箱操作,以避免過擬合或生成過多不必要的箱

該參數默認值設置為0.1,是一個比較小的數值,這意味著只有當統計量的增長率顯著時,分箱才會繼續。通過調整?stop_limit?的值,用戶可以在分箱的數量和模型的復雜度之間找到平衡。

需要注意的是,該參數只是控制分箱停止條件的參數之一,在使用時需要合理結合設置,以確保分箱既有效又高效。

IV增長率

如果?woebin?函數使用信息值(IV)作為分箱的依據,stop_limit?可以設定為一個閾值,當相鄰兩次分箱后IV值的增長率小于這個閾值時,分箱停止

卡方值

在一些實現中,stop_limit?也可能與卡方值相關。當卡方值小于某個基于?stop_limit?計算出的臨界值時,分箱也會停止

參數9:bin_num_limit

整數類型,可以分的最大箱子數量,默認值是 8

該參數是限制分箱算法可以生成的最大箱子數量,從而避免過度分箱導致的模型復雜度過高或數據過擬合問題。

當?woebin?函數對變量進行分箱時,它會考慮這個限制,并嘗試在不超過?bin_num_limit?設定的箱數的前提下,找到最優的分箱方案

  • 如果?bin_num_limit?設定為一個較小的值,分箱算法會傾向于生成較少的、包含較多樣本的箱,這可能會簡化模型并減少過擬合的風險。

  • 如果?bin_num_limit?設定為一個較大的值,分箱算法則有更多的自由度來生成更多的、包含較少樣本的箱,這可能會提高模型的精細度,但同時也可能增加模型的復雜度和過擬合的風險

在使用?bin_num_limit?參數時,需要根據具體的數據集和建模需求來選擇合適的值。如果數據集較大且變量分布復雜,可能需要更多的箱來捕捉數據的細節特征;而如果數據集較小或變量分布相對簡單,則較少的箱可能就足夠了

該參數與 stop_limit 參數、count_distr_limit參數結合控制分箱數量,以共同控制分箱的過程和結果

參數10:positive

用于指定目標變量是好類別的標簽,通過該參數的設置,用來檢測 dt 中的 y 列取值是否規范,如果不規范,將會被check函數檢測出來,拋出異常終止建模。

該入參默認值是 "bad|1"

在信用評分卡建模中,這通常指的是那些我們希望模型能夠識別并預測出的正面事件,比如客戶會償還貸款(即“好”客戶)的情況

positive?參數的設置

positive?參數應該設置為目標變量中代表正面事件的唯一值或值的列表。這個參數對于函數來說很重要,因為它決定了如何計算諸如好壞比率(Good/Bad Ratio)、信息值(IV)等關鍵指標,這些指標在信用評分卡的開發中至關重要。

  • 如果目標變量是二元的(比如,只有“好”和“壞”兩種可能),positive?參數就應該設置為表示“好”類別的那個值。
  • 如果目標變量有多個類別,但其中只有一個被視為正面事件,那么positive?參數同樣應該設置為那個代表正面事件的值。
  • 在某些情況下,如果目標變量使用了不同的編碼方式(比如,用1表示“好”,用0表示“壞”),那么positive?參數就應該設置為對應的編碼值。

參數11:no_cores

并發的CPU核數。默認值是None,如果該參數傳的是None,會看 x 特征變量的數量,如果小于10個特征,則使用 1 核 CPU,如果大于等于 10 個特征,則使用全部的 CPU。

參數12:print_step

該參數控制函數在執行分箱(binning)過程中的信息打印級別

默認值為 0 或者 False

參數取值詳解

  • 當?print_step?= 0 或 False 時?:

    • 函數將不會打印任何分箱過程中的步驟信息。
    • 這適用于不希望看到詳細執行過程,只關心最終結果的用戶。
  • ?當?print_step?> 0 或 True 時?:

    • 函數將打印分箱過程中的一些關鍵步驟信息,如每個變量的分箱結果、每個分箱的壞賬率(Bad Rate)、權重(Weight of Evidence, WoE)等。
    • 打印的信息量可能隨著?print_step?值的增加而增加,但具體行為取決于函數的實現。
    • 這對于調試、理解分箱過程或查看中間結果非常有用。

使用建議

  • 在初次使用?woebin?函數或對新數據進行分箱時,可以將?print_step?設置為一個大于 0 的值或 True,以便查看分箱過程中的詳細信息,確保分箱結果符合預期。
  • 如果已經熟悉分箱過程,并且只關心最終結果,可以將?print_step?設置為 0 或 False,以減少不必要的輸出信息。
  • 該參數的使用根據個人實際情況即可。

參數13:method

用于指定分箱的方法,默認值為 tree

支持的分箱方法

1、tree(決策樹分箱)?:
  • 決策樹分箱是一種基于決策樹算法的分箱方法。它通過遞歸地劃分數據集來生成最優的分箱結果。
  • 決策樹分箱的優點是能夠處理連續型變量和類別型變量,并且通常能夠生成較為均衡的分箱結果。
  • 缺點是計算復雜度較高,可能需要較長的計算時間,尤其是在處理大數據集時。
def woebin2_tree(dtm, init_count_distr=0.02, count_distr_limit=0.05,stop_limit=0.1, bin_num_limit=8, breaks=None, spl_val=None):# initial binningbin_list = woebin2_init_bin(dtm, init_count_distr=init_count_distr, breaks=breaks, spl_val=spl_val)initial_binning = bin_list['initial_binning']binning_sv = bin_list['binning_sv']if len(initial_binning.index) == 1:return {'binning_sv': binning_sv, 'binning': initial_binning}# initialize parameterslen_brks = len(initial_binning.index)bestbreaks = NoneIVt1 = IVt2 = 1e-10IVchg = 1  ## IV gain ratiostep_num = 1# best breaks from three to n+1 binsbinning_tree = Nonewhile (IVchg >= stop_limit) and (step_num + 1 <= min([bin_num_limit, len_brks])):binning_tree = woebin2_tree_add_1brkp(dtm, initial_binning, count_distr_limit, bestbreaks)# best breaksbestbreaks = binning_tree.loc[lambda x: x['bstbrkp'] != float('-inf'), 'bstbrkp'].tolist()# information valueIVt2 = binning_tree['total_iv'].tolist()[0]IVchg = IVt2 / IVt1 - 1  ## ratio gainIVt1 = IVt2# step_numstep_num = step_num + 1if binning_tree is None: binning_tree = initial_binning# return return {'binning_sv': binning_sv, 'binning': binning_tree}
?2、chimerge(卡方分箱)?:
  • 卡方分箱是一種基于卡方統計量的分箱方法。它通過合并相鄰的區間來減少區間數量,直到滿足某個停止條件為止。
  • 卡方分箱的優點是能夠處理連續型變量,并且生成的分箱結果通常具有較好的單調性。
  • 缺點是可能無法處理類別型變量,并且需要指定分箱的數量或停止條件。

卡方算法參考文獻:

ChiMerge算法詳解:數據離散化與應用-CSDN博客

ChiMerge:Discretization of numeric attributs

def woebin2_chimerge(dtm, init_count_distr=0.02, count_distr_limit=0.05, stop_limit=0.1, bin_num_limit=8, breaks=None, spl_val=None):# chisq = function(a11, a12, a21, a22) {#   A = list(a1 = c(a11, a12), a2 = c(a21, a22))#   Adf = do.call(rbind, A)##   Edf =#     matrix(rowSums(Adf), ncol = 1) %*%#     matrix(colSums(Adf), nrow = 1) /#     sum(Adf)##   sum((Adf-Edf)^2/Edf)# }# function to create a chisq column in initial_binningdef add_chisq(initial_binning):chisq_df = pd.melt(initial_binning, id_vars=["brkp", "variable", "bin"], value_vars=["good", "bad"],var_name='goodbad', value_name='a')\.sort_values(by=['goodbad', 'brkp']).reset_index(drop=True)###chisq_df['a_lag'] = chisq_df.groupby('goodbad')['a'].apply(lambda x: x.shift(1))#.reset_index(drop=True)chisq_df['a_rowsum'] = chisq_df.groupby('brkp')['a'].transform(lambda x: sum(x))#.reset_index(drop=True)chisq_df['a_lag_rowsum'] = chisq_df.groupby('brkp')['a_lag'].transform(lambda x: sum(x))#.reset_index(drop=True)###chisq_df = pd.merge(chisq_df.assign(a_colsum = lambda df: df.a+df.a_lag), chisq_df.groupby('brkp').apply(lambda df: sum(df.a+df.a_lag)).reset_index(name='a_sum'))\.assign(e = lambda df: df.a_rowsum*df.a_colsum/df.a_sum,e_lag = lambda df: df.a_lag_rowsum*df.a_colsum/df.a_sum).assign(ae = lambda df: (df.a-df.e)**2/df.e + (df.a_lag-df.e_lag)**2/df.e_lag).groupby('brkp').apply(lambda x: sum(x.ae)).reset_index(name='chisq')# returnreturn pd.merge(initial_binning.assign(count = lambda x: x['good']+x['bad']), chisq_df, how='left')# initial binningbin_list = woebin2_init_bin(dtm, init_count_distr=init_count_distr, breaks=breaks, spl_val=spl_val)initial_binning = bin_list['initial_binning']binning_sv = bin_list['binning_sv']# return initial binning if its row number equals 1if len(initial_binning.index)==1: return {'binning_sv':binning_sv, 'binning':initial_binning}# dtm_rowsdtm_rows = len(dtm.index)    # chisq limitfrom scipy.special import chdtrichisq_limit = chdtri(1, stop_limit)# binning with chisq columnbinning_chisq = add_chisq(initial_binning)# parambin_chisq_min = binning_chisq.chisq.min()bin_count_distr_min = min(binning_chisq['count']/dtm_rows)bin_nrow = len(binning_chisq.index)# remove brkp if chisq < chisq_limitwhile bin_chisq_min < chisq_limit or bin_count_distr_min < count_distr_limit or bin_nrow > bin_num_limit:# brkp needs to be removedif bin_chisq_min < chisq_limit:rm_brkp = binning_chisq.assign(merge_tolead = False).sort_values(by=['chisq', 'count']).iloc[0,]elif bin_count_distr_min < count_distr_limit:rm_brkp = binning_chisq.assign(count_distr = lambda x: x['count']/sum(x['count']),chisq_lead = lambda x: x['chisq'].shift(-1).fillna(float('inf'))).assign(merge_tolead = lambda x: x['chisq'] > x['chisq_lead'])# replace merge_tolead as Truerm_brkp.loc[np.isnan(rm_brkp['chisq']), 'merge_tolead']=True# order select 1strm_brkp = rm_brkp.sort_values(by=['count_distr']).iloc[0,]elif bin_nrow > bin_num_limit:rm_brkp = binning_chisq.assign(merge_tolead = False).sort_values(by=['chisq', 'count']).iloc[0,]else:break# set brkp to lead's or lag'sshift_period = -1 if rm_brkp['merge_tolead'] else 1binning_chisq = binning_chisq.assign(brkp2  = lambda x: x['brkp'].shift(shift_period))\.assign(brkp = lambda x:np.where(x['brkp'] == rm_brkp['brkp'], x['brkp2'], x['brkp']))# groupby brkpbinning_chisq = binning_chisq.groupby('brkp').agg({'variable':lambda x:np.unique(x),'bin': lambda x: '%,%'.join(x),'good': sum,'bad': sum}).assign(badprob = lambda x: x['bad']/(x['good']+x['bad']))\.reset_index()# update## add chisq to new binning dataframebinning_chisq = add_chisq(binning_chisq)## parambin_nrow = len(binning_chisq.index)if bin_nrow == 1:breakbin_chisq_min = binning_chisq.chisq.min()bin_count_distr_min = min(binning_chisq['count']/dtm_rows)# format init_bin # remove (.+\\)%,%\\[.+,)if is_numeric_dtype(dtm['value']):binning_chisq = binning_chisq\.assign(bin = lambda x: [re.sub(r'(?<=,).+%,%.+,', '', i) if ('%,%' in i) else i for i in x['bin']])\.assign(brkp = lambda x: [float(re.match('^\[(.*),.+', i).group(1)) for i in x['bin']])# return return {'binning_sv':binning_sv, 'binning':binning_chisq}

使用建議

在選擇分箱方法時,應根據數據的類型(連續型或類別型)、數據的特點(如分布情況、缺失值情況等)以及具體的業務需求來進行選擇

  • 如果數據中包含較多的連續型變量,并且希望分箱結果具有較好的單調性,可以考慮使用卡方分箱(chimerge)。
  • 如果數據中包含較多的類別型變量,或者希望分箱過程能夠自動處理不同類型的數據,可以考慮使用決策樹分箱(tree

參數14:ignore_const_cols

用于控制是否忽略常量列的分箱處理,參數類型為 bool

默認值:True,即忽略常量列的分箱處理

常量列指在整個數據集中所有行的值都相同的列,這些列對于建模通常沒有提供有用的信息,因此可以忽略,從而減少不必要的計算,提高分箱的效率。

參數15:ignore_datetime_cols

用于控制是否忽略日期時間列的分箱處理,參數類型為 bool

默認值:True,即忽略日期時間列的分箱處理

日期時間列通常包含時間戳、日期或時間信息,這些信息對于某些類型的分析可能是有用的,但在分箱過程中可能需要特殊的處理。

當需要對日期時間列進行分箱處理,即ignore_datetime_cols?=?False?時?,這可能需要對日期時間列進行額外的預處理,例如將它們轉換為數值型特征或提取特定的日期時間組件(如年、月、日等)。

參數16:check_cate_num

用于控制在對類別型變量(categorical variables)進行分箱時,是否檢查并限制每個類別中的樣本數量,并在必要時進行合并或處理,參數類型為 bool

默認值:True

如果類別型變量的類別數量超過50,即會給出提示,由用戶判斷是否繼續分箱。如果樣本中有很多類別型變量,并且每個變量枚舉值都非常多,那么也會非常影響建模效率。

def check_cateCols_uniqueValues(dat, var_skip = None):# character columns with too many unique valueschar_cols = [i for i in list(dat) if not is_numeric_dtype(dat[i])]if var_skip is not None: char_cols = list(set(char_cols) - set(str_to_list(var_skip)))char_cols_too_many_unique = [i for i in char_cols if len(dat[i].unique()) >= 50]if len(char_cols_too_many_unique) > 0:print('>>> There are {} variables have too many unique non-numberic values, which might cause the binning process slow. Please double check the following variables: \n{}'.format(len(char_cols_too_many_unique), ', '.join(char_cols_too_many_unique)))print('>>> Continue the binning process?')print('1: yes \n2: no')cont = int(input("Selection: "))while cont not in [1, 2]:cont = int(input("Selection: "))if cont == 2:raise SystemExit(0)return None

參數17:replace_blank

用于控制如何處理數據中的空白(或缺失)值,參數類型為 bool

默認值:True

def rep_blank_na(dat): # cant replace blank string in categorical value with nan# 如果有重復的索引,則重置索引if dat.index.duplicated().any():dat = dat.reset_index(drop = True)warnings.warn('There are duplicated index in dataset. The index has been reseted.')blank_cols = [i for i in list(dat) if dat[i].astype(str).str.findall(r'^\s*$').apply(lambda x:0 if len(x)==0 else 1).sum()>0]if len(blank_cols) > 0:warnings.warn('There are blank strings in {} columns, which are replaced with NaN. \n (ColumnNames: {})'.format(len(blank_cols), ', '.join(blank_cols)))
#        dat[dat == [' ','']] = np.nan
#        dat2 = dat.apply(lambda x: x.str.strip()).replace(r'^\s*$', np.nan, regex=True)dat.replace(r'^\s*$', np.nan, regex=True)return dat

參數18:save_breaks_list

用于控制是否將分箱后的斷點(或稱為區間邊界)保存為一個列表。這個參數對于后續的分箱處理、模型訓練或結果分析可能非常重要,因為它決定了分箱的具體方式和每個箱子的邊界

默認值:None

如果該參數不為 None,傳入的是 String 類型數據,則會用于文件名,將分箱信息保存在文件中。具體由 bins_to_breaks 函數實現

def bins_to_breaks(bins, dt, to_string=False, save_string=None):if isinstance(bins, dict):bins = pd.concat(bins, ignore_index=True)# x variablesxs_all = bins['variable'].unique()# dtypes of  variablesvars_class = pd.DataFrame({'variable': xs_all,'not_numeric': [not is_numeric_dtype(dt[i]) for i in xs_all]})# breakslist of binsbins_breakslist = bins[~bins['breaks'].isin(["-inf","inf","missing"]) & ~bins['is_special_values']]bins_breakslist = pd.merge(bins_breakslist[['variable', 'breaks']], vars_class, how='left', on='variable')bins_breakslist.loc[bins_breakslist['not_numeric'], 'breaks'] = '\''+bins_breakslist.loc[bins_breakslist['not_numeric'], 'breaks']+'\''bins_breakslist = bins_breakslist.groupby('variable')['breaks'].agg(lambda x: ','.join(x))if to_string:bins_breakslist = "breaks_list={\n"+', \n'.join('\''+bins_breakslist.index[i]+'\': ['+bins_breakslist[i]+']' for i in np.arange(len(bins_breakslist)))+"}"if save_string is not None:brk_lst_name = '{}_{}.py'.format(save_string, time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time())))with open(brk_lst_name, 'w') as f:f.write(bins_breakslist)print('[INFO] The breaks_list is saved as {}'.format(brk_lst_name))return return bins_breakslist

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/84159.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/84159.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/84159.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

英語寫作中“假設”suppose, assume, presume 的用法

一、suppose 是給出推理的前提&#xff0c;與事實無關&#xff0c;例如&#xff1a; Suppose x >0. Then the square root of x is a real number. &#xff08;假設x大于0&#xff0c;則x的平方根是實數。&#xff09; Suppose Jack and Alice share a private channel. …

CAD標注樣式如何設置?詳細教程來了

CAD中有很多的標注&#xff0c;比如線性標注&#xff0c;對齊標注&#xff0c;坐標標注&#xff0c;面積標注&#xff0c;直徑標注&#xff0c;弧長標注等等&#xff0c;標注的種類多&#xff0c;標注的樣式也多&#xff0c;今天來給大家介紹一下浩辰CAD看圖王中如何設置不同的…

vscode include總是報錯

VSCode 的 C/C 擴展可以通過配置 c_cpp_properties.json 來使用 compile_commands.json 文件中的編譯信息&#xff0c;包括 include path、編譯選項等。這樣可以確保 VSCode 的 IntelliSense 與實際編譯環境保持一致。 方法一&#xff1a;直接指定 compile_commands.json 路徑…

自動化立體倉庫WCS與PLC通訊設計規范

導語 大家好&#xff0c;我是社長&#xff0c;老K。專注分享智能制造和智能倉儲物流等內容。歡迎大家使用我們的倉儲物流技術AI智能體。 新書《智能物流系統構成與技術實踐》 新書《智能倉儲項目出海-英語手冊&#xff0c;必備&#xff01;》 完整版文件和更多學習資料&#xf…

【window QT開發】簡易的對稱密鑰加解密工具(包含圖形應用工具和命令行工具)

前言 項目開發時&#xff0c;配置文件中某些信息不適合直接明文顯示&#xff0c;本文提供基于對稱密鑰的AES-256算法的加解密工具&#xff0c;可集成到項目中。 AES講解 以下是我分享的一個在國產信創系統(Linux)下使用openssl實現AES加解密的博文 對稱加密--AES加解密 本文…

「極簡」扣子(coze)教程 | 小程序UI設計進階(二)!讓系統動起來,“禁用”,“加載”狀態設置

大家好&#xff0c;上一期大師兄通過一個例子來介紹一下扣子界面中“可見性”的應用。今天大師兄想再進一步介紹控件中的其他一些重要的屬性。 扣子&#xff08;coze&#xff09;編程 「極簡」扣子(coze)教程 | 小程序UI設計進階&#xff01;控件可見性設置 「極簡」扣子(coze…

前端三件套之html詳解

目錄 一 認識 二 標簽的分類 三 標簽 body標簽 標題標簽 段落標簽 換行標簽 水平分割線 文本格式化標簽 圖片標簽 音頻標簽 鏈接標簽 列表標簽 表格標簽 表單標簽 input標簽 下拉菜單標簽 textarea文本域標簽 label標簽 語義化標簽 button標簽 字符實體 …

Google Play 賬號創建及材料準備

1&#xff1a;注冊一個關聯Google Play賬號的Google賬號&#xff0c;關聯郵箱進行自動轉發 2&#xff1a;準備一張Visa、Master、JCB、運通卡或Discover等美國信用卡或全球付虛擬信用卡&#xff0c;用來支付25美金的GP賬號注冊費 3&#xff1a;為避免出現關聯原因被封&#x…

Pycharm和Flask的學習心得(4和5)

一&#xff1a;認識路由&#xff1a; &#xff08;1&#xff09;&#xff1a;接受請求的類型&#xff1a; app.route(hello ,methods [GET ,POST]) 請求類型主要有兩種(常用)&#xff1a;GET 和 POST ; GET: 直接輸入的網址&#xff08;url訪問的就是GET請求&#xff09; …

DeepSeek 賦能智能電網:從技術革新到全場景應用實踐

目錄 一、智能電網的發展現狀與挑戰二、DeepSeek 技術解析2.1 DeepSeek 技術原理2.2 DeepSeek 技術優勢 三、DeepSeek 在智能電網中的具體應用3.1 設備管理智能化3.2 電網運行優化3.3 客戶服務提升3.4 規劃建設智能化3.5 經營管理高效化3.6 辦公輔助便捷化 四、DeepSeek 在智能…

MFC 編程中 OnInitDialog 函數

核心作用 對話框初始化入口 &#xff1a;創建完成后第一個執行的函數。是對話框的起點。控件操作安全期 &#xff1a;此時所有控件已創建完成。可以安全地進行控件的初始化、屬性設置等操作。界面布局最佳時機 &#xff1a;窗口顯示前完成初始化設置。可以進行布局調整、數據初…

前端地圖數據格式標準及應用

前端地圖數據格式標準及應用 坐標系EPSGgeojson標準格式基于OGC標準的地圖服務shapefile文件3D模型數據常見地圖框架 坐標系EPSG EPSG&#xff08;European Petroleum Survey Group&#xff09;是一個國際組織&#xff0c;負責維護和管理地理坐標系統和投影系統的標準化編碼 E…

Python爬蟲(35)Python爬蟲高階:基于Docker集群的動態頁面自動化采集系統實戰

目錄 一、技術演進與行業痛點二、核心技術棧深度解析2.1 動態渲染三件套2.2 Docker集群架構設計2.3 自動化調度系統 三、進階實戰案例3.1 電商價格監控系統1. 技術指標對比2. 實現細節 3.2 新聞聚合平臺1. WebSocket監控2. 字體反爬破解 四、性能優化與運維方案4.1 資源消耗對比…

04-jenkins學習之旅-java后端項目部署實踐

1、創建被管理項目 2、構建流程說明 jenkins其實就是將服務部署拆分成了&#xff1a; 1、拉取代碼(git) 2、打包編譯 3、自定義腳本(jar復制、執行啟動腳本) 4、部署成功后的一些通知等 3、demo配置 3.1、General 3.2 源碼管理 添加用戶名密碼方式如下圖 3.2.1 常見錯誤(r…

科研經驗貼:AI領域的研究方向總結

一、數據集&#xff08;Dataset&#xff09; 定義&#xff1a; 用于訓練、驗證和測試模型的樣本集合&#xff0c;通常包含輸入特征&#xff08;如圖像、文本&#xff09;和對應標簽&#xff08;如類別、回歸值&#xff09;。 關鍵作用&#xff1a; 數據劃分&#xff1a; 訓練…

Android 網絡全棧攻略(四)—— 從 OkHttp 攔截器來看 HTTP 協議一

上一篇我們詳解了 OkHttp 的眾多配置&#xff0c;本篇來看 OkHttp 是如何通過責任鏈上的內置攔截器完成 HTTP 請求與響應的&#xff0c;目的是更好地深入理解 HTTP 協議。這仍然是一篇偏向于協議實現向的文章&#xff0c;重點在于 HTTP 協議的實現方法與細節&#xff0c;關于責…

免費AI工具整理

1、NVIDIA models ALL&#xff1a;Try NVIDIA NIM APIs example&#xff1a;llama-3.1-405b-instruct Model by Meta | NVIDIA NIM 2、文心一言 文心一言 3、納米AI 納米AI搜索 4、其他 ChatGPT 鏡像網址&#xff08;5月持續更新&#xff09; - 最優網址

C++ std::find() 函數全解析

std::find()是C標準庫中用于線性查找的基礎算法&#xff0c;屬于<algorithm>頭文件&#xff0c;可應用于任何支持迭代器的容器。 一、函數原型與參數 template< class InputIt, class T > InputIt find( InputIt first, InputIt last, const T& value );??…

MySQL--day6--單行函數

&#xff08;以下內容全部來自上述課程&#xff09; 單行函數 1. 內置函數及分類 單行函數聚合函數&#xff08;或分組函數&#xff09; 1.1 單行函數特點 操作數據對象接受參數返回一個結果只對一行進行變換每行返回一個結果可以嵌套參數可以是一列或一個值 2. 數值函…

GO語言學習(九)

GO語言學習&#xff08;九&#xff09; 上一期我們了解了實現web的工作中極為重要的net/http抱的細節講解&#xff0c;大家學會了實現web開發的一些底層基礎知識&#xff0c;在這一期我來為大家講解一下web工作的一個重要方法&#xff0c;&#xff1a;使用數據庫&#xff0c;現…