条件分案

分析建模,日常问题整理(二十七)


2019.7.31~2019.8.5

'''
目标:
对催收人员进行考核时
指标为回收金额
对分案人员应进行公平分配
公平的标准包括金额一致、户数一致、难度一致
以下分配主要保证户数相差不大,金额尽可能一致
难度一致打算进行数据建模
以是否回收为y
以产品信息、个人信息等为x
对案件打分
根据分数公平分配

解决:
利用排序
每次分案都是按上次从小到大的排序
对本次的金额从大到小的分配

存在问题:
不能达到金额一致的公平
因上班天数越多
分的案件金额越大
不能达到天平均金额一致
因案件量大时没有来上班参与分案
案件量小时却参与了
那平均分得的案件和平均金额也会变少
'''
def Allocation(history,his_loannum ,cases,todayname,date_):
    '''
    input:
    历史每天分案总额
    历史每天分案单号
    当前案件
    当前分案人员
    日期
    output:
    每天分案总额
    每天分案单号
    '''
    assert type(history) == type(pd.DataFrame())
    assert type(cases) == type(pd.DataFrame())
    num_cases = len(cases)
    cases.columns=[0,1]
    today_hm = history[history['人员'].isin(todayname)].reset_index(drop=True)
    tem_l = [ i for i in todayname if i not in history['人员'].tolist()]
    tem_n = [ i for i in todayname if i in history['人员'].tolist()]
    for k in tem_l:
        today_hm.loc[today_hm.shape[0]] = [k]+[0]*(history.shape[1]-1)
    if len(tem_n)!=0:
        for m in today_hm.columns[1:]:
            t_m = today_hm[m].sum()/(today_hm[m]!=0).sum()  # 将0填充为均值
            today_hm[m] = today_hm[m].replace(0,t_m)      
            
    num_people = len(today_hm)
    residue = num_people-num_cases%num_people   # 要补上的0的个数
    epoc = int(num_cases/num_people)+1  # 每人应当分配的案件量
    loan_num = pd.DataFrame(today_hm['人员'])
    loan_num = loan_num.set_index('人员')
    
    for gap in range(residue):
        cases.loc[num_cases+gap] = 0  # 在loan_no:应还总额的数据中添加要补上的0的n行

    cases = cases.sort_values(cases.columns[1], ascending=False).reset_index(drop=True)  ##对金额排序
    # del cases['index']
    for i in range(epoc):  # 每人要分配epoc个案件,按顺序分,分epoc次
        today_hm = today_hm.sort_index()
        today_hm['sum']  = today_hm.apply(lambda x:sum(x[1:]),axis=1) # 每次分配都要重新排序
        today_hm = today_hm.sort_values('sum', ascending = True)
        loan_num = loan_num.ix[today_hm['人员']]
        loan_num['idx_{}'.format(i)] = cases.iloc[i*num_people:(i+1)*num_people,0].values  #将这一次分配的loan_no保存
        today_hm['amt_{}'.format(i)] = cases.iloc[i*num_people:(i+1)*num_people,1].values   ##将这一次分配的repay_amt保存
        del today_hm['sum']
        
    today_hm = today_hm.sort_index()
    today_hm[date_]  = today_hm.apply(lambda x:sum(x[-epoc:]),axis=1) 
    today_hm.drop(today_hm.columns.tolist()[-(epoc+1):-1],axis=1,inplace=True)   

    loan_num = loan_num.reset_index()
    loan_num[date_] = loan_num.apply(lambda x:[x for x in x[1:].values.tolist() if x!=0],axis=1)
    loan_num.drop(loan_num.columns.tolist()[-(epoc+1):-1],axis=1,inplace=True)
    # res2.set_index('人员')['loan_lst'].to_dict()
    loan_num = loan_num.merge(his_loannum,on='人员',how='outer').fillna(0)
    today_hm = today_hm[['人员',date_]].merge(history,on='人员',how='outer').fillna(0)
    return today_hm,loan_num

from sympy import *
def assiged_random(dat,name_lst,date_):
    '''
    第一天随机分配
    初始化
    如果固定某一天则可以自动化实现
    '''
    assiged_dic = OrderedDict()
    his_amt=  pd.DataFrame()
    his_no = pd.DataFrame()
    loan_ = []
    n=len(name_lst)
    dat['REPAY_AMT'] = dat['REPAY_AMT'].astype(float)
    x,y = Symbol('x'),Symbol('y')
    a = int(dat.shape[0]/n)
    b = int(dat.shape[0]/n+1)
    solve_ = solve([a* x+b*y-dat.shape[0], x + y - n],[x, y])
    for i in range(0,n):
        if i

你可能感兴趣的:(条件分案)