出家如初,成佛有余

R语言常用统计分布的蒙特卡洛模拟

Posted in 技术相关 by chuanliang on 2017/12/23

为加深对各种常用统计分布的理解,更好掌握R语言对应的各类分布的概率函数(d、p、q、r族)以及广义线性模型的使用,研究了一下常用统计分布数据的模拟生成方法,收获颇多。

各类常用统计分布蒙特卡洛模拟数据生成的大致思路:

1、构造自变量x的均匀分布
2、根据对应分布的均值函数,构造x变量对应的均值。(广义线性模型的link 函数参考
https://en.wikipedia.org/wiki/Generalized_linear_model#Link_function
3、将均值代入,R中对应分布的随机变量生成函数,得到因变量y(例如正态分布为rnorm、泊松分布为rpois)

代码:

#norm distribution simulation
set.seed(1234)
num=100
beta0=1
beta1=0.2
x=beta0+beta1*runif(n=num,-1,1)
y=rnorm(num,mean=x,sd=1)
model=glm(y~x,,family=gaussian(link=’identity’))

#possion distribution simulation
set.seed(1234)
num=100
beta0=1
beta1=0.2
x=beta0 + beta1*runif(n=num, min=0, max=5)
lambda=exp(x)
y=rpois(n=num, lambda=lambda)
model = glm(y~x, family=poisson(link = log))

#Exponential/Gamma distribution simulation
set.seed(1234)
num=100
beta0=1
beta1=0.2
x=beta0 + beta1*runif(n=num, min=0, max=5)
y=rexp(num,rate=exp(-x))
model=glm(y~x,,family=Gamma(link=’log’))
#使用nls模拟
df=data.frame(x,y)
model=nls(y~exp(a+b*x),data=df,start = list(a=0,b=0))

#logistic/probit distribution simulation
set.seed(1234)
num=100
beta0=1
beta1=0.2
x=beta0 + beta1*runif(n=num, min=0, max=5)
#logistic distribution logit=log(odds)=log(p/(1-p))
odds=exp(x)
probs=odds/(1+odds)
#probit distribution probit=Cumulative normal pdf
#probs=pnorm(x)

y=rbinom(n=num,size=1,prob=probs)
model=glm(y~x1+x2,family = binomial(link="logit"))

#bionimal/Categorical/Multinomial distribution simulation
library(nnet)
y=rbinom(n=num,size=3,prob=probs)
model <- multinom(y ~ x1 + x2)

代码下载


参考资料:《 Monte Carlo Simulation and Resampling Methods for Social Science》

https://www.sagepub.com/sites/default/files/upm-binaries/57233_Chapter_6.pdf

Advertisements

R中fitted()与predict()函数关系以及predict type参数解析

Posted in 技术相关 by chuanliang on 2017/12/17

R文档对fitted()、predict()函数以及predict函数type参数取值的具体含义说得很不清楚,网上也没有清晰的解释。总结一下。

一、说明

目的一、R中fitted和predict的关系
目的二、以logistic为例,解析predict中type参数不同取值的关系

1、R中fitted和predict的关系
fitted对无link函数模型(例如线性回归),fitted值和predict的值相同
对有link函数的模型(例如logistic、Binomial),
fitted是link函数作用前(或者link逆函数inverse of the link function作用后)的预测值
predict是link函数作用后(或link逆函数inverse of the link function作用前)的预测值
link function  https://en.wikipedia.org/wiki/Generalized_linear_modelLink_function

2、logistic中predict中type参数不同取值的关系
predict中type参数的可选项有:default, type="link",type="response",type="terms"

假设log(odds)=log(p/(1-p))=alpha+beta1*x1+beta2*x2+…+betan*xn
a.、type="link",type为缺省值
  type="link"为缺省值,给出logit线性函数预测值,link=alpha+beta1*x1+beta2*x2+…+betan*xn

b、 type="response"
  type="response" 给出概率预测值。
  response=predict(model,type = "response"),则
  log(response/(1-response))=alpha+beta1*x1+beta2*x2+…+betan*xn=link,或:link=exp(response)/(1+response)

c、type="terms"
  type="terms"表示各个变量的预测值(包括前面参数在模型中的值)。
  terms=predict(model, newdata = traindata,type = "terms")的结果为各个变量term的值
  term1=beta1*x1,term2=beta2*x2, …
  sum(term1,…,termn)+attr(terms,"constant")=log(odds)=log(response/(1-response))
  attr(terms,"constant")的含义 http://blog.minitab.com/blog/adventures-in-statistics-2/regression-analysis-how-to-interpret-the-constant-y-intercept

二、代码

代码下载

#fitted和predict的关系演示
#linear regression
#no link function
num=100
x1=rnorm(num)
x2=rnorm(num)
lr=1+2*x1+3*x2
model=lm(y~x+x2)

fit=fitted(model)
pred=predict(model)
print(all.equal(fit, pred))
#对无link函数的模型,fitted值与predict值相同

#possion
#link=log
num=100
x=rnorm(num)
y=rpois(num,lambda = exp(x))
model = glm(y~x, family="poisson")
fit=fitted(model)
pred=predict(model)
print(all.equal(log(fit),pred))
print(all.equal(fit,exp(pred)))
#对有link函数的模型,fitted值为link函数作用前的值,predict为link作用后的值

#logistic
#link=logit=log(p/(1-p))
num=100
x1=rnorm(num)
x2=rnorm(num)
lo=1+2*x1+3*x2
odds=exp(lo)
probs=odds/(1+odds)
y=rbinom(n=num,size=1,prob=probs)
model=glm(y~x1+x2,family = binomial(link="logit"))

fit=fitted(model)
pred=predict(model)
print(all.equal(log(fit/(1-fit)),pred))
print(all.equal(fit,exp(pred)/(1+exp(pred))))
#对有link函数的模型,fitted值为link函数作用前的值,predict为link作用后的值

#以logistic模型为例子,验证predict中type为缺省值,type="link",type="response",type="terms"关系
#predict中type="link"时的fitted及predict
link=predict(model,type="link")
print(link)
print(all.equal(pred,link))
#type=link为缺省值

#predict中type="response"时的fitted及predict
response=predict(model,type="response")
print(response)
print(all.equal(fit,response))
print(all.equal(pred,log(response/(1-response))))

#type="terms"时的fitted及predict
terms<- predict(model,type="terms")
term=terms[,1]+terms[,2]+attr(terms,"constant")
print(term)
print(all.equal(link,term))
print(all.equal(response,exp(term)/(1+exp(term))))

参考资料:

https://stackoverflow.com/questions/12201439/is-there-a-difference-between-the-r-functions-fitted-and-predict

资产端线上对接资金端系统?

Posted in 电子商务&互联网金融, 产品管理 by chuanliang on 2017/12/16

我在知乎关于提问“资产端线上对接资金端系统?” https://www.zhihu.com/question/67426957/answer/277256804  的回答。

虽然最近现金贷整顿,但此问题涉及的内容的应用场景挺多的,简单说一下思路。

资产端平台接入资金端平台时候,需要重点考虑两大部分的内容:

1、交易结构设计

由于合作双方监管合规性问题,交易结构设计主要解决资金端资金怎样以合规、安全的形式流转到资产端。这里的合规性,不单纯只是资产端或资金端,双方都涉及合规性。

在交易结构设计时候,涉及很多因素,例如:

a、资产端的资质,例如是P2P平台、互联网小贷平台、消费金融公司、助贷机构等的资金合规来源渠道并不同。

b、资金端的资质,例如是金融机构(银行、保险公司、融资性担保公司等)、P2P、互联网小贷、消费金融公司、企业、股东等的资金。

c、资产方的资产质量

d、实际放款方,资产最终归属。涉及放款资质,是否需要债权转让、ABS等

e、担保方式

f、资金放款、还款流转流程,支付/代扣渠道

g、资产端的保证金、杠杆、资金成本等

交易结构设计是整个合作最核心的内容,也是最难的地方,需要双方一起就双方实际情况探讨合规的合作模式。

交易结构设计影响了资产端、资金端合作模式、金融产品设计、平台对接的业务流等内容。

2、平台化设计

低成本、稳定、多元化的资金来源是资产端平台的核心竞争力,因此一般情况下,资产端都会尽量接入更多的资金端平台,以保证资金的持续供给。因此从平台建设角度来说,需要在设计时候考虑平台的扩展性、可运营性等因素,以满足多个资金端接入的需求。

在合作之初以验证合作模式为主,因此平台功能平台功能没必要设计得过于复杂。但随着业务规模扩大,低成本的运营能力成为平台的核心能力之一,可以说每一个资产端的资金对接平台最终都会演变成资产端、资金端的撮合路由平台。

一张图供参考

产品架构图

R语言信用评分卡模型(脑图、代码)

Posted in 技术相关 by chuanliang on 2017/12/13

在消费金融中,风险模型组(申请评分卡、行为评分卡、催收评分卡、失联概率、违约概率PD模型等)、营销模型组(客户分层模型、客户响应模型、客户流失模型)、反欺诈模型组等都涉及了信用评分卡模型的应用。关于信用评分卡模型的使用及代码实现,网上公开的完整资料较少,且大都写得语焉不详。基于R语言做了一个完整例子,算是对最近一段时间工作总结。

分为两部分:

1、评分卡模型使用总结脑图

2、评分卡模型R语言代码

1、评分卡模型使用总结脑图(完整脑图点击下载)

2017-12-13_205830

《评分卡模型使用总结脑图》下载

2、R语言代码

scorecard.r

使用docker来实现libreoffice并发转换docx文件为pdf

Posted in Uncategorized by chuanliang on 2017/06/08

由于libreoffice的soffice不支持多进程,只允许同时有一个进程来转换docx文件为pdf文件,因此无法多线程并发执行转换操作。

为实现并发转换操作,有两种方案:

方案一:将转换代码部署到不同的服务器上,此种方案需要单独服务器,对资源要求较高,部署也麻烦;

方案二:利用docker对资源的隔离特性,把libreoffice 放到docker中,然后启用多个libreoffice容器,java代码调用不同容器的soffice命令来并发转换docx文件。

1、安装docker相关程序

CentOS7已经缺省支持docker

yum install docker

service docker start

chkconfig docker on

简单的安装使用可以参考 https://linux.cn/article-4340-1.html

2、把缺省的docker镜像仓库换成国内的网易镜像

echo "DOCKER_OPTS=\"\$DOCKER_OPTS –registry-mirror=http://hub-mirror.c.163.com\"" >> /etc/default/docker

service docker restart

3、下载centos docker镜像

docker pull centos

4、启动centos的docker镜像

docker run -it centos /bin/bash

5、进入docker容器

docker run -it centos -v /root/install:/root/install  /bin/bash

由于生产镜像时候,可能需要与宿主主机共享一些文件,例如中文ttf文件,因此在run 时候使用了-v参数,用于宿主主机与docker container之间的共享目录。

假设docker 容器与宿主机的共享目录为/root/install 。

Docker容器和主机之间共享数据,可以参考 https://www.howtoing.com/how-to-share-data-between-the-docker-container-and-the-host/

6、安装libreoffice、中文字体库等所需的软件

yum install libreoffice-writer.x86_64

yum groupinstall "Fonts"

yum groupinstall "Input Methods"

7、生成安装了libreoffice、中文字体等软件的docker 镜像

docker commit CONTAINER_ID liang/libreoffice1

其中:

CONTAINER_ID是docker ps -a得到了容器id docker ps -a|grep "centos"|awk ‘{print $1}’

liang/libreoffice1 是我们生成的docker镜像

8、停掉刚才启动的centos容器

docker stop CONTAINER_ID

9、启动我们新生成的docker 镜像

根据并发转换docx为pdf文件的需要,基于我们自己生成的docker镜像,启动多个docker的容器,利用docker容器对资源的隔离,调用不同容器中的soffice来并发处理不同的pdf文件

docker run –name office1 -it -d -v /root/pdf1:/root/pdf1  liang/libreoffice1

docker run –name office2 -it -d -v /root/pdf1:/root/pdf1  liang/libreoffice1

镜像文件与宿主机的共享目录为/root/pdf1和/root/pdf2,在共享目录中放入要转换的docx文件

docker exec -it office1 /bin/bash

 

10、调用soffice命令行,将docx转为pdf

docker exec -it office1 /bin/soffice –headless  –invisible –norestore –nodefault –nolockcheck  –nofirststartwizard –convert-to pdf:writer_pdf_Export –outdir /root/pdf1 /root/pdf1/liang1.docx

docker exec -it office2 /bin/soffice –headless  –invisible –norestore –nodefault –nolockcheck  –nofirststartwizard –convert-to pdf:writer_pdf_Export –outdir /root/pdf2 /root/pdf2/liang2.docx

以上命令行放到java代码中,同时可以在多个线程中并发调用。

服务器部署Session Draining支持方案

Posted in 技术相关 by chuanliang on 2016/02/24

 

支付系统对账算法优化方案

Posted in 电子商务&互联网金融, 技术相关 by chuanliang on 2015/06/09

一、目前对账的算法:

1、从上游渠道(银行、银联等金融机构)获取对账文件,程序逐行解析入库

2、在存储过程中,以上游对账文件的表为基准,程序逐行读取并与我们系统的交易记录/账务记录(有账务系统情况下,合理方案应该是于账务记录)对比,查找出差异记录。

3、以我们系统的交易记录/账务记录为基准,程序逐行读取与上游对账文件对比,查找出差异记录

 

二、目前对账算法问题:

1、使用存储过程,对账过程都在数据库端完成,对数据库性能影响较大,而且对账逻辑扩展极为麻烦

2、逐行比对算法效率较低,但算法上并无好的优化余地。如果采用数据库INTERSECT、MINUS对数据库压力也高。

3、在业务量大的情况下(例如有上百家上游渠道需要对,每一家都有几十万条交易记录),对账服务器及数据库服务器负荷较高。即便采用读写分离,对账时候使用读库,压力一样很大。

4、导入批量文件,逐行入库效率较为低下(每一次都需要建立网络连接、关闭连接)

 

三、对账算法优化思路:

1、涉及网络传输的,尽量采用批量方式操作,减少网络消耗及时间消耗

2、使用Redis等NOSQL数据库,降低数据库服务器的压力。同时在扩展上也容易,一台Redis服务器不够,可以无限制增加用于对账用的服务器。

3、使用Redis的set集合的sdiff功能,利用Redis sdiff算法的高性能,比对上游记录和我方记录的差异

 

四、对账算法说明:

1、利用Oracle/Mysql的load data infile将对账文件批量导入到数据库

2、程序读取上游账务记录表,对上游账户记录执行select  concat(channel_id, “:” , order_id , “:” , HASH_MD5(channel_id , order_id , amount , status , timestamp1 , timestamp2 ,…) )  as hashid from table ,得到对应的SET集合。

这里思路是将需要对账的记录拼成格式为:channel_id:order_id:hashid形式的串,以便作为Redis SET集合的item。

其中channel_id和order_id用于标识对应的渠道及订单,只是例子,根据实际需要补充。之所以要在hashid前面带上channel_id和order_id,主要目的是在sdiff后,能够作为主键,根据set结合的item查找出对应的数据库记录。

3、对我方的交易记录表/账户历史表采用上一步的类似算法,得到对应的SET结合

4、采用Redis的pipeline功能(Redis的各种客户端,包括java客户端jedis 都提供此功能),将上游账务记录SET集合和我方的交易记录/账务历史记录SET集分别批量执行sadd插入Redis,得到两个SET集合。

由于单条记录sadd 插入Redis效率较差(每一次都涉及网络open、close、传输消耗),因此使用Redis的pipeline功能,已实现批量入库功能。

可以参考:http://redis.io/topics/mass-insert

5、利用redis的sdiff功能查找出上游账务集合与我方记录集合的差值

6、从sdiff 集合中channel_id:order_id:hash,定位对应的数据库记录,更新对账状态。

具体性能及实现可以在实现后测试对比一下,应该会有大幅的性能提升。

POS签购单上的授权号,凭证号,参考号,批次号,分别是什么?有什么作用

Posted in 电子商务&互联网金融 by chuanliang on 2015/04/18

我在知乎就问题《POS签购单上的授权号,凭证号,参考号,批次号,分别是什么?有什么作用》做的回答。

 

下面定义及术语参考了《中国银联POS终端规范》及《中国银联银行卡联网联合技术规范V2.1 第2部分 报文接口规范》两个规范。
批次号(Batch NO.):POS从签到起至结算、签退为止的交易为一批次,交易批次号标识一批交易。POS中心为每个POS的每个批次分配一个批次号,在签到响应报文中下传给POS终端。
对应银联ISO8583报文的报文头域7: 批次号(Batch Number)

序号(Ref. NO.):POS中心为交易分配的流水号,在响应报文中下传给POS终端作为对账参考号,并用于事后查证。
对应银联ISO8583报文的域37:检索参考号(Retrieval Reference Number)

授权号(Auth Code):授权标识应答码,简称“授权码”。是发卡行返回或银联CUPS代授权时返回的授权序号。
对应银联ISO8583报文的域38:授权标识应答码 Authorization Identification Response

查询号(Trace NO.):POS机为每一笔交易产生的顺序编号。POS每上送一次交易此号码增加1。 POS流水号为6位数字,值从1至999999循环使用。在自动冲正时,POS中心依据POS流水号作为确定被冲正交易的要素之一。
交 易发起方赋予交易的一组数字,与域7(交易传输时间 Transmission Date/Time)、域32(受理机构标识码 Acquiring Institution Identification Code)和域33(发送机构标识码 Forwarding Institution Identification Code)的组合值唯一标识一笔交易的编号。

凭证号(Voucher NO.):查询号(Trace NO. 也叫POS流水号)也作为交易凭证号(在签购单上打印为Voucher NO.),在进行撤销等交易时,输入原交易凭证号作为确定原交易的要素之一,并且必须上送原交易的凭证号。

要确认一笔交易,分为发卡行和收单方:
对发卡行来说:卡号+参考号+授权号,就能够确定一笔交易
对于收单方来说:凭证号+域7(对应签购单上的日期/时间)+域32(对应签购单上的收单机构)+33域(对应签购单上的发卡机构)能够唯一确定一笔交易
因此如果是向发卡行投诉,则需要提供卡号、参考号、授权号。
如果是向收单方投诉,则需要提供凭证号、交易日期时间、收单机构、发卡机构

知乎回答原文链接:http://www.zhihu.com/question/29519161/answer/45062087

如何开发一个好的普惠金融产品?

Posted in 电子商务&互联网金融, 产品管理 by chuanliang on 2015/04/18

我在知乎就问题《如何开发一个好的普惠金融产品?》做的回答。

 

这话题太庞大,只能尝试从自己角度回答一下。
1、互联网金融产品从产品属性属性来说分为两种:金融端产品、互联网端产品
其中金融端产品主要指传统金融提供的各种金融产品。究其原因在于目前金融监管限制,互联网金融还很难有真正意义上的金融端产品创新。
互联网端产品主要指依托互联网渠道的各种产品、服务等。

2、互联网金融产品产品度量指标:
金融端产品的度量指标:风险、收益、流动性
互联网端产品的度量指标:创新、用户体验、用户口碑、用户数/流量

3、互联网金融产品玩法:
a、金融产品端的玩法:
监管套利、信息不对称、资源重配置等。
对现有传统金融产品通过组合、移植、包装等方式,形成互联网金融的金融端产品。
b、互联网产品端的玩法:
去中介化/脱媒、口碑传播、流量及长尾效应、持续运营

4、普惠金融产品开发挑战:
a、团队磨合
由于涉及金融产品团队、互联网产品团队等不同角色,不同团队的文化氛围、管理模式、风格、关注点等都不尽相同,怎样让团队尽快磨合,协同作战。
b、口碑及信任感建立
互联网金融的价值之一在于可以利用互联网渠道的口碑传播,快速放大产品及公司品牌影响力,但由于互联网金融产品的金融属性,用户对平台的信任感是平台的核心竞争力。怎样让产品获得良好口碑,培育用户起对平台信任感成为优秀产品的核心任务。

5、产品开发模式
精益创业的MVP方法、Scrum等。

6、怎样开发一个好的互联网金融产品
1)、跨职能的项目团队搭建
2)、市场调研,定位目标用户群
3)、金融产品设计及定价
4)、互联网产品设计
5)、互联网产品开发
6)、种子期用户试点
由于互联网产品的研发有一个过程,如果业务模式允许,在系统未上线前可并行采用手工方式进行金融产品试点验证(MVP方法)。
7)、运营数据分析及产品策略分析
8)、产品完善(包括定价策略、营销策略、IT系统等)
9)、扩大试点范围(受众群、区域、渠道等)
10)、运营数据分析->产品完善->更大规模推广及运营

7、好的互联网金融产品评价标准
可以参考 互联网金融运营需要关注的数据有哪些呢? – 梁川的回答

知乎回答原文链接:http://www.zhihu.com/question/29358993/answer/44781757

如何搭建二维码支付系统?

Posted in 电子商务&互联网金融, 移动互联网 by chuanliang on 2015/04/18

我在知乎就问题《如何搭建二维码支付系统?》做的回答。

1、如果是在线交易,要支持扫码支付,只需要在将原有交易过程的支付链接及信息生成对应的二维码即可。
2、如果是线下交易,要支持二维码支付,主要问题在于考虑怎样让传统线下收银机、POS机支持扫码支付。
目前业内的主流做法:
a、铺设定制终端设备,串接在收银机、打印机之间,抓取收银机、打印机之间的通信协议,将传统的小票信息改造成支持二维码的小票。消费者使用银行/商户/第三方支付的APP对着打印出来的小票扫码完成支付。
b、铺设支持二维码的POS机或收银机,例如微信POS机。消费者对着POS或收银机或打印出的小票扫码完成支付。
1、2中,在支付环节,与传统在线支付/移动支付并无太大差异。
在安全上,与传统在线支付的商户收款链接的安全处理类似,最核心的问题是:怎样保证支付链接地址不是钓鱼地址。

 

知乎回答原文链接地址:http://www.zhihu.com/question/29325751/answer/43978310