分析建模,日常问题整理(二十七)
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<solve_[x]:
dat_ix = random.sample(dat['ID_'].tolist(),a)
loan_.extend(dat_ix)
tem = dat[dat.ID_.isin(dat_ix)][['ID_','REPAY_AMT']]
assiged_dic.update({name_lst[i]:{'ID_':dat_ix,'REPAY_AMT':tem['REPAY_AMT'].tolist()}})
dat = dat[~dat.ID_.isin(loan_)].reset_index(drop = True)
else :
dat_ix = random.sample(dat['ID_'].tolist(),b)
loan_.extend(dat_ix)
tem = dat[dat.ID_.isin(dat_ix)][['ID_','REPAY_AMT']]
assiged_dic.update({name_lst[i]:{'ID_':dat_ix,'REPAY_AMT':tem['REPAY_AMT'].tolist()}})
dat = dat[~dat.ID_.isin(loan_)].reset_index(drop = True)
his_amt = pd.DataFrame([[k,sum(assiged_dic[k]['REPAY_AMT'])] for k in assiged_dic.keys()],columns=['人员',date_])
his_no = pd.DataFrame([[k,assiged_dic[k]['ID_']] for k in assiged_dic.keys()],columns=['人员',date_])
return assiged_dic,his_amt,his_no
# 这一步之前要先初始化分配
hm = pd.DataFrame([['a',3,2],['b',4,3],['c',5,5],['d',6,1],['e',7,2]],columns=['人员','20190706','20190707'])
cs = pd.DataFrame([['A',3],['B',4],['C',5],['D',6],['E',7],['F',2],['G',8],['H',4],['I',6],['J',1],['K',9]])
res1,res2 = Allocation(hm, pd.DataFrame([['a','AA'],['b','BB'],['c','CC'],['d','DD'],['e','EE']],columns=['人员','20190707']),cs,hm['人员'].tolist()+['n'],'21090708')
res1['sum'] = res1.apply(lambda x:sum(x[1:-1]),axis=1)
res1['sum_averge'] = res1.apply(lambda x:sum(x[1:])/((x!=0).sum()-1),axis=1)
res2['sum'] = res2.iloc[:,1:].apply(lambda x:sum(list(map(lambda y:len(y) if y!=0 else 0,x))),axis=1)
网友评论