0

好吧,伙计们,这很难。

这个问题的主题是基于欺诈数据、规则和付款——我认为用一点背景来描绘我正在尝试做的事情会更容易。

我有一个数据框,其中包含帐户 ID、金额、日期、欺诈等和一列称为规则的列。每个 accountid 可以触发许多独特的规则。

accountid    amount    date      rule   fraud
123          5         20191101  rule_1  fraud
123          10        20191102  rule_2  fraud
456          50        20191101  rule_1  nonfraud
456          50        20191101  rule_2  nonfraud
456          50        20191101  rule_3  nonfraud
456          50        20191101  rule_4  nonfraud

我的目标是创建一个函数,它遍历 2 个规则的每个组合(可能稍后 3 个),并有几个其他列来计算帐户 ID、计算欺诈和非欺诈帐户 ID、欺诈率等。结果如下所示:

rule_combo       count_acct     count_fraud   count_nonfraud    fraudrate
rule_1,rule_2    5              3             2                 .6
rule_2,rule_3    20             10            10                .5
rule_2,rule_4    50             10            40                .1
rule_1,rule_3    10             3             7                 .3

我有一个看起来像这样的函数,它可以做我想要的,但它使用列(标题):

def combo_cols(df,agg,cols,n,minrate=0)
    combos = list(itertools.combinations(cols,3))
    num_cols = ['col1','col2','col3']
    res = []
    for combo in combos:
        fr = fraudrate(df,agg,combo) #using another function
        accounts = df.groupby(combo).apply(lambda df:list(df.accountid.unique()))
        accounts.name = 'accounts'
        accounts = accounts.to_frame()
        fr = accounts.join(fr)
        fr = fr.reset_index()
        fr['naccts'] = fr.apply(lamda df: len(set(df.accounts)),axis=1)
        fr.columns = num_cols + ['accounts','naccts','fraud','nonfraud','fraudrate','fpr']
        fr = fr.assign(groupcols = ', '.join(combo))
        fr = fr.loc[fr.fraudrate.gt(minrate)]
        res.append(fr)
    return pd.concat(res).sort_values(by='fraudrate',ascending=False)

我一直无法理解如何编写一个可以为规则执行此操作的函数。感谢您对此的任何帮助。

4

1 回答 1

1

我不确定我是否在回答你的问题,所以请给我反馈,如果需要我会更新。

我的第一个赌注是 OneHotEncode 你拥有的那些功能。这是一个例子:

df = pd.get_dummies(df, columns=['rule', 'fraud'])

结果是:

accountid amount rule_rule_1 rule_rule_2 rule_rule_3 rule_rule_4 fraud_fraud fraud_nonfraud
0   123     5        1           0           0           0           1           0
1   123     10       0           1           0           0           1           0
2   456     50       1           0           0           0           0           1
3   456     50       0           1           0           0           0           1
4   456     50       0           0           1           0           0           1
5   456     50       0           0           0           1           0           1

然后你可以使用 itertools 来做这样的事情:

import itertools
for elt in itertools.combinations(list(df.columns[df.columns.str.startswith('rule')]), 2):
    tmp = df.groupby(list(elt))
    # Apply your aggregation functions here

希望这可以帮助!

于 2020-01-09T19:03:30.857 回答