python用卡方检验,自动分箱,结果是否可靠有待验证

Python017

python用卡方检验,自动分箱,结果是否可靠有待验证,第1张

def calc_chiSquare(sampleSet, feature, target):

    '''

    计算某个特征每种属性值的卡方统计量

    params:

        sampleSet: 样本集

        feature: 目标特征

        target: 目标Y值 (0或1) Y值为二分类变量

    return:

        卡方统计量dataframe

        feature: 特征名称

        act_target_cnt: 实际坏样本数

        expected_target_cnt:期望坏样本数

        chi_square:卡方统计量

    '''

    # 计算样本期望频率

    target_cnt = sampleSet[target].sum()

    sample_cnt = len(sampleSet[target])

    expected_ratio = target_cnt * 1.0/sample_cnt

    # 对变量按属性值从大到小排序

    df = sampleSet[[feature, target]]

    col_value = list(set(df[feature])) 

    # 计算每一个属性值对应的卡方统计量等信息

    chi_list = []target_list = []expected_target_list = []

    for value in col_value:

        df_target_cnt = df.loc[df[feature] == value, target].sum()

        df_cnt = len(df.loc[df[feature] == value, target])

        expected_target_cnt = df_cnt * expected_ratio

        chi_square = (df_target_cnt - expected_target_cnt)**2 / expected_target_cnt

        chi_list.append(chi_square)

        target_list.append(df_target_cnt)

        expected_target_list.append(expected_target_cnt)

    # 结果输出到dataframe, 对应字段为特征属性值, 卡方统计量, 实际坏样本量, 期望坏样本量

    chi_stats = pd.DataFrame({feature:col_value, 'chi_square':chi_list,

                              'act_target_cnt':target_list, 'expected_target_cnt':expected_target_list})

    return chi_stats[[feature, 'act_target_cnt', 'expected_target_cnt', 'chi_square']]

def chiMerge_maxInterval(chi_stats, feature, maxInterval=5):

    '''

    卡方分箱合并--最大区间限制法

    params:

        chi_stats: 卡方统计量dataframe

        feature: 目标特征

        maxInterval:最大分箱数阈值

    return:

        卡方合并结果dataframe, 特征分割split_list

    '''

    group_cnt = len(chi_stats)

    split_list = [chi_stats[feature].min()]

    # 如果变量区间超过最大分箱限制,则根据合并原则进行合并

    while(group_cnt >maxInterval):

        min_index = chi_stats[chi_stats['chi_square']==chi_stats['chi_square'].min()].index.tolist()[0]

        # 如果分箱区间在最前,则向下合并

        if min_index == 0:

            chi_stats = merge_chiSquare(chi_stats, min_index+1, min_index)

        # 如果分箱区间在最后,则向上合并

        elif min_index == group_cnt-1:

            chi_stats = merge_chiSquare(chi_stats, min_index-1, min_index)

        # 如果分箱区间在中间,则判断与其相邻的最小卡方的区间,然后进行合并

        else:

            if chi_stats.loc[min_index-1, 'chi_square'] >chi_stats.loc[min_index+1, 'chi_square']:

                chi_stats = merge_chiSquare(chi_stats, min_index, min_index+1)

            else:

                chi_stats = merge_chiSquare(chi_stats, min_index-1, min_index)

        group_cnt = len(chi_stats)

    chiMerge_result = chi_stats

    split_list.extend(chiMerge_result[feature].tolist())

    return chiMerge_result, split_list

def chiMerge_minChiSquare(chi_stats, feature, dfree=4, cf=0.1, maxInterval=5):

    '''

    卡方分箱合并--卡方阈值法

    params:

        chi_stats: 卡方统计量dataframe

        feature: 目标特征

        maxInterval: 最大分箱数阈值, default 5

        dfree: 自由度, 最大分箱数-1, default 4

        cf: 显著性水平, default 10%

    return:

        卡方合并结果dataframe, 特征分割split_list

    '''

    threshold = get_chiSquare_distuibution(dfree, cf)

    min_chiSquare = chi_stats['chi_square'].min()

    group_cnt = len(chi_stats)

    split_list = [chi_stats[feature].min()]

    # 如果变量区间的最小卡方值小于阈值,则继续合并直到最小值大于等于阈值

    while(min_chiSquare <threshold and group_cnt >maxInterval):

        min_index = chi_stats[chi_stats['chi_square']==chi_stats['chi_square'].min()].index.tolist()[0]

        # 如果分箱区间在最前,则向下合并

        if min_index == 0:

            chi_stats = merge_chiSquare(chi_stats, min_index+1, min_index)

        # 如果分箱区间在最后,则向上合并

        elif min_index == group_cnt-1:

            chi_stats = merge_chiSquare(chi_stats, min_index-1, min_index)

        # 如果分箱区间在中间,则判断与其相邻的最小卡方的区间,然后进行合并

        else:

            if chi_stats.loc[min_index-1, 'chi_square'] >chi_stats.loc[min_index+1, 'chi_square']:

                chi_stats = merge_chiSquare(chi_stats, min_index, min_index+1)

            else:

                chi_stats = merge_chiSquare(chi_stats, min_index-1, min_index)

        min_chiSquare = chi_stats['chi_square'].min()

        group_cnt = len(chi_stats)

    chiMerge_result = chi_stats

    split_list.extend(chiMerge_result[feature].tolist())

    return chiMerge_result, split_list

def get_chiSquare_distuibution(dfree=4, cf=0.1):

    '''

    根据自由度和置信度得到卡方分布和阈值

    params:

        dfree: 自由度, 最大分箱数-1, default 4

        cf: 显著性水平, default 10%

    return:

        卡方阈值

    '''

    percents = [0.95, 0.90, 0.5, 0.1, 0.05, 0.025, 0.01, 0.005]

    df = pd.DataFrame(np.array([chi2.isf(percents, df=i) for i in range(1, 30)]))

    df.columns = percents

    df.index = df.index+1

    # 显示小数点后面数字

    pd.set_option('precision', 3)

    return df.loc[dfree, cf]

def merge_chiSquare(chi_result, index, mergeIndex, a = 'expected_target_cnt',

                    b = 'act_target_cnt', c = 'chi_square'):

    '''

    params:

        chi_result: 待合并卡方数据

        index: 合并后的序列号

        mergeIndex: 需合并的区间序号

        a, b, c: 指定合并字段

    return:

        分箱合并后的卡方dataframe

    '''

    chi_result.loc[mergeIndex, a] = chi_result.loc[mergeIndex, a] + chi_result.loc[index, a]

    chi_result.loc[mergeIndex, b] = chi_result.loc[mergeIndex, b] + chi_result.loc[index, b]

    chi_result.loc[mergeIndex, c] = (chi_result.loc[mergeIndex, b] - chi_result.loc[mergeIndex, a])**2 /chi_result.loc[mergeIndex, a]

    chi_result = chi_result.drop([index])

    chi_result = chi_result.reset_index(drop=True)

    return chi_result

for col in bin_col:

    chi_stats = calc_chiSquare(exp_f_data_label_dr, col, 'label')

    chiMerge_result, split_list = chiMerge_maxInterval(chi_stats, col, maxInterval=5)

    print(col, 'feature maybe split like this:', split_list)

2018.08.02

R语言中有smbining可以进行最优分箱,python中分箱如果既要考虑箱体个数,分箱后信息量大小,也要考虑单调性等其他因素。

这里给出一种简单的通过IV值来选择如果分箱的方法。

下面是按照分位数来分的,还可以按照卡房分箱,决策树分箱等。

参照toad(由厚本金融开发的较标准的评分卡开发开源包)的分箱方式。

给定一个数据集waitakere.txt,该数据集中含有大量的噪音数据。具体操作要求:1)该数据集的偶数位均为噪音数据,判断偶数位是否为0,若为0,利用1替换。2)对转换后的数据集进行排序,利用分箱技术来光滑数据。假设有10个桶,实现“用箱均值光滑”、 “用箱中位数光滑”、“用箱边界光滑”三种技术。

waitakere.txt:

这只是一部分数据,只是为了示例噪音数据

1 0 3 2 0 3

4 0 1 0 0 0

0 0 0 1 0 0

0 0 0 0 7 0

0 8 9 0 9 0

0 6 0 5 0 3

6 0 7 0 1 0

......

登录后复制

解题思路:首先读入数据到列表里,然后对数据进行排序,将数据划分到10个箱中。对于箱均值光滑,箱中每一个值都被替换为箱中的均值。对于箱中位数光滑,箱中每一个值都被替换为箱中的中位数。对于箱边界光滑,箱中每一个值都被替换为最近的边界值。

以下为python代码实现部分:

import numpy as np

def binning(filename,box_num):

my_list=[]

my_list1=[]

noise_data = open(filename)

for line in noise_data.readlines():

dataline=line.strip()

my_list.append(dataline)

for i in range(0,len(my_list)):

my_list[i]=int(my_list[i])

if (i+1) % 2==0 and my_list[i]==0:

my_list[i]=1

my_list1=sorted(my_list)

#print my_list1

box_list=[]

len_box=int(np.ceil(len(my_list1)/float(box_num)))

for i in range(0,10):

each_box=my_list1[i*len_box:(i+1)*len_box]

box_list.append(each_box)

return box_list

def box_mean_smooth(box_list):

for i in range(0,len(box_list)):

box_avg=int(np.average(box_list[i]))

for j in range(0,len(box_list[i])):

box_list[i][j]=box_avg

return box_list

def box_mid_smooth(box_list):

for i in range(0,len(box_list)):

box_mid=int(np.median(box_list[i]))

for j in range(0,len(box_list[i])):

box_list[i][j]=box_mid

return box_list

def box_boundary_smooth(box_list):

for i in range(0,len(box_list)):

left_bdy=box_list[i][0]

right_bdy=box_list[i][-1]

for j in range(0,len(box_list[i])):

if abs(box_list[i][j]-left_bdy)<abs(box_list[i][j]-right_bdy):

box_list[i][j]=left_bdy

else:

box_list[i][j]=right_bdy

return box_list

filename='waitakere.txt'

box_list=binning(filename,10)

print box_list

print box_mean_smooth(box_list)

print box_mid_smooth(box_list)

print box_boundary_smooth(box_list)

登录后复制

下图为实验结果截图:

由于数据较多,截图只是一部分

python

数据

银川旅游景点攻略,这个地方驴友必去之一!良心推荐

精选推荐

广告

python 等深分箱法(均值平滑技术、边界值平滑技术)

1.3W阅读·6评论·24点赞

2020年12月10日

数据挖掘概念与技术(第三版)课后答案——第三章

2.2W阅读·201评论·119点赞

2020年7月3日

python S-G (Savitzky–Golay filter) 平滑滤波和kalman滤波滤掉噪声实现实例,有可视化结果

357阅读·0评论·0点赞

2022年11月10日

R语言数据挖掘(2) 数据预处理

2292阅读·0评论·1点赞

2017年10月10日

数据认知与数据预处理--数据预处理

348阅读·0评论·0点赞

2022年6月23日

数据挖掘复习

815阅读·0评论·0点赞

2021年12月20日

美人鱼公主参加聚会装扮美人鱼游戏

精选推荐

广告

python 数据、曲线平滑处理

9904阅读·0评论·16点赞

2022年4月21日

数据挖掘如何分箱以及如何对每个箱子中的数据进行平滑处理

2.0W阅读·2评论·38点赞

2019年6月24日

数据挖掘概念与技术(原书第三版)范明 孟小峰译-----第三章课后习题答案

2.6W阅读·13评论·21点赞

2017年5月21日

python 数据可视化 -- 真实数据的噪声平滑处理

2779阅读·0评论·2点赞

2019年2月11日

【6】python生成数据曲线平滑处理——(Savitzky-Golay 滤波器、convolve滑动平均滤波)方法介绍,推荐玩强化学习的小伙伴收藏

2612阅读·2评论·3点赞

2021年8月12日

数据挖掘理论与算法笔记

368阅读·0评论·0点赞

2021年6月10日

《数据挖掘概念与技术》学习笔记-第三章

3957阅读·0评论·6点赞

2020年2月14日

这个神奇的库,可以将数据平滑化并找到异常点

135阅读·0评论·0点赞

2022年6月9日

python数据平滑处理,numpy之数据平滑处理

3253阅读·0评论·0点赞

2021年4月27日

python 数据平滑_数据平滑方法的原理和应用

1394阅读·0评论·0点赞

2020年12月9日

python使曲线变得平滑_如何在Python中平滑数据?

3234阅读·0评论·1点赞

2020年12月4日

numpy模块的使用(二)

257阅读·0评论·2点赞

2020年10月3日

去首页

看看更多热门内容

评论1

扣尼奇哇

写得好