Blog Archives

用R语言实现数据离散化

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员/Quant: Java,R,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-discretization

前言

在做数据挖掘模型的时候,我们有时会需要把连续型变量转型离散变量,这种转换的过程就是数据离散化,分箱就是离散化常用的一种方法。

数据离散化处理属于数据预处理的一个过程,R语言在数据处理上有天然的优势,也有直接用于离散化计算的包,无监督的离散化可以用infotheo包,有监督的离散化可以用discretization包来处理复杂的离散化操作。

目录

  1. 数据离散化的需求
  2. 无监督的数据离散化
  3. 有监督的数据离散化

1. 数据离散化的需求

数据离散化,教课书上面的定义是,把无限空间中有限的个体映射到有限的空间中。数据离散化操作,大多是针对连续型变量进行的,处理之后数据从连续型变量转变为离散型变量。

离散化处理的特点:

  • 快速迭代,离散化的过程,离散特征增加和减少都很容易,易于扩展。
  • 高效计算,稀疏向量内积乘法运算速度快,计算结果方便存储。
  • 适应性,有些分类模型适合用离散化数据做为数据指标,比如决策树虽然支持输入连续型变量,但决策树模型本身会先将连续型变量转化为离散型变量,做逻辑回归时,也通常会先把连续型特征变量离散化,变成0或1。
  • 鲁棒性,数据离散化会让特征变化不是特别明显,特别是对于降低异常数据干扰。
  • 稳定性,牺牲了数据的微小变化,但保证了模型的稳定性。
  • 过拟合,减少的数据信息,降低了过拟合的风险。
  • 业务性,业务上已经定义出了离散值的含义,需要做离散化处理。

离散化处理通常对连续型变量进行处理,但同时也可以对离散型变量再进行离散化,适用于数据聚合或重新分组。

2. 无监督的数据离散化

我们可以无监督的数据离散化方法,进行数据的分箱操作,包括等宽分箱法、等频分箱法、通过kmeans分箱法等。

  • 等宽分箱法,将观察点均匀划分成n等份,每份的间距相等。
  • 等频分箱法,将观察点均匀分成n等份,每份的观察点数相同。
  • kmeans分箱法,先给定中心数,将观察点利用欧式距离计算与中心点的距离进行归类,再重新计算中心点,直到中心点不再发生变化,以归类的结果做为分箱的结果。

接下来,我们用R语言来实现上面提到的几种分箱的操作。

2.1 准备数据

本文所使用的系统环境

  • Win10 64bit
  • R: 3.2.3 x86_64-w64-mingw32/x64 b4bit

首先,生成一组数据,这组织通过3个正态分布的随机数进行叠加,主要用于体现分箱的不同特征。


# 设置随机数种子,生成符合正态分布N(0,1)的数据1000个点
> set.seed(0)
> a1<-rnorm(1000)

> set.seed(1)
> a2<-rnorm(300,0,0.2)

> set.seed(2)
> a3<-rnorm(300,3,0.5)

# 按顺序,合并3种数据
> aa<-c(a1,a2,a3)

# 查看数据
> head(aa,30)
 [1]  1.26295 -0.32623  1.32980  1.27243  0.41464 -1.53995 -0.92857 -0.29472 -0.00577  2.40465  0.76359
[12] -0.79901 -1.14766 -0.28946 -0.29922 -0.41151  0.25222 -0.89192  0.43568 -1.23754 -0.22427  0.37740
[23]  0.13334  0.80419 -0.05711  0.50361  1.08577 -0.69095 -1.28460  0.04673

画出数据的散点图,x轴为索引序号,y轴为值。


> plot(aa)

查看数据的分布形状,x轴为值,y轴为这个值出现的次数。


# 画出数据的直方图
> hist(aa,200)

通过散点图和直方图,就可以很明显的看到数据的特征,数据有倾斜的,值在0和3附近是比较多的。

2.2 infotheo包使用

在R语言中,我们可以使用infotheo包,来做等宽分箱和等频分箱。

项目主页:https://cran.r-project.org/web/packages/infotheo/

安装infotheo包,是非常简单的,只需要一条命令。


~ R
> install.packages("infotheo")
> library(infotheo)

进行等宽分箱,将观察点均匀划分成n等份,每份的间距相等。


> d1<-discretize(aa,"equalwidth",5)
> table(d1)
d1
  1   2   3   4   5 
 40 467 703 217 173 

# 可视化分箱
> plot(aa,col=d1$X)

分为5组,第一组最少,第三组最多,每组值的区间是一样的。

进行等频率分箱,将观察点均匀分成n等份,每份的观察点数相同。


> d2<-discretize(aa,"equalfreq",5)
> table(d2)
d2
  1   2   3   4   5 
320 320 320 320 320 

# 可视化分箱
> plot(aa,col=d2$X)

分为5组,每组的数量都相同。

kmeans分箱法,先给定中心数为5。


> d3<-kmeans(aa,5)
> table(d3$cluster)
  1   2   3   4   5 
121 258 303 267 651 

# 5个中心
> d3$centers
     [,1]
1 -1.6196
2  1.2096
3  3.0436
4 -0.7228
5  0.0736

# 可视化分箱
> plot(aa,col=d3$cluster)

5组聚类的结果。

每一种方法,对于分箱的离散化的结果都是不同的,使用哪一种方法,最好都有业务上的解释,不能随便乱用。

3. 有监督的数据离散化方法

有监督的离散化的方法,可以用R语言中discretization包来操作。discretization包,是一个用来做有监督离散化的工具集,主要用于卡方分箱算法,它提供了几种常用的离散化工具函数,可以按照自上而下或自下而上,实施离散化算法。

项目主页:https://cran.r-project.org/web/packages/discretization/

安装discretization包是非常简单的,只需要一条命令。


~ R
> install.packages("discretization")
> library(discretization)

discretization提供了几个主要的离散化的工具函数:

  • chiM,ChiM算法进行离散化
  • chi2, Chi2算法进行离散化
  • mdlp,最小描述长度原理(MDLP)进行离散化
  • modChi2,改进的Chi2方法离散数值属性
  • disc.Topdown,自上而下的离散化
  • extendChi2,扩展Chi2算法离散数值属性

3.1 卡方分箱

卡方分箱是依赖于卡方检验的分箱方法,在统计指标上选择卡方统计量(chi-Square)进行判别。卡方分箱的基本思想是判断相邻的两个区间是否有分布差异,如果两个相邻的区间具有非常类似的分布,则这两个区间可以合并;否则,它们应当保持分开。基于卡方统计量的结果进行自下而上的合并,直到满足分箱的限制条件为止。

卡方分箱的实现步骤:

1. 预先设定一个卡方的阈值。以这个阈值为标准,我们对数据进行卡方检验,通过显著性水平和自由度,计算出数据的卡方值与这个阈值进行比较。

  • 显著性水平,当置信度90%时显著性水平为10%,ChiMerge算法推荐使用置信度为0.90、0.95、0.99。
  • 自由度,比分类数量小1。例如:有3类,自由度为2。

类别和属性独立时,有90%的可能性,计算得到的卡方值会小于4.6。大于阈值4.6的卡方值就说明属性和类不是相互独立的,不能合并。如果阈值选的大,区间合并就会进行很多次,离散后的区间数量少、区间大。

2. 初始化:根据要离散化的数据对实例进行排序,每个实例属于一个区间
3. 合并区间:
1) 计算每一个对相邻区间的卡方值
2) 将卡方值最小的一对区间合并

卡方统计量衡量了区间内样本的频数分布与整体样本的频数分布的差异性,在做分箱处理时可以使用两种限制条件:

  • 分箱个数:限制最终的分箱个数结果,每次将样本中具有最小卡方值的区间与相邻的最小卡方区间进行合并,直到分箱个数达到限制条件为止。
  • 卡方阈值:根据自由度和显著性水平得到对应的卡方阈值,如果分箱的各区间最小卡方值小于卡方阈值,则继续合并,直到最小卡方值超过设定阈值为止。

4.评估指标

分为箱之后需要评估,常用的评估手段是计算出WOE和IV值。对于WOE和IV值的含义,参考文章:https://blog.csdn.net/kevin7658/article/details/50780391

3.2 数据准备

有监督的离散化算法,只少需要数据为2列,一列用于离散化的向量数据,一列是分类的评价标准数据,所以我们需要重新选择一个数据集,具有分类标准的数据。

我们使用一个系统自带的数据集iris,这个着名的Fisher的鸢尾花数据。iris包含150个记录,和5个变量的数据框,名为Sepal.Length(萼片的长度),Sepal.Width(萼片的宽度),Petal.Length(花瓣的长度),Petal.Width(花瓣的长度)和Species(种类,setosa,versicolor和virginica)。

查看数据集


> data(iris)
> head(iris,10)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
3           4.7         3.2          1.3         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa
5           5.0         3.6          1.4         0.2  setosa
6           5.4         3.9          1.7         0.4  setosa
7           4.6         3.4          1.4         0.3  setosa
8           5.0         3.4          1.5         0.2  setosa
9           4.4         2.9          1.4         0.2  setosa
10          4.9         3.1          1.5         0.1  setosa

接下来,我们分别用不同的算法,把这个数据集进行离散化处理。

3.3 chiM算法进行离散化

ChiM()函数,使用ChiMerge算法基于卡方检验进行自下而上的合并。通过卡方检验判断相邻阈值的相对类频率,是否有明显不同,或者它们是否足够相似,从而合并为一个区间。

chiM(data,alpha)函数解读。

  • 第一个参数data,是输入数据集,要求最后一列是分类属性。
  • 第二个参数alpha,表示显著性水平。
  • 自由度,通过数据计算获得是2,一共3个分类减去1。

下面使用chiM()进行计算。


# 离散化计算
> chi1<-chiM(iris,alpha=0.05)

# 查看前10条结果
> head(chi1$Disc.data,10)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1             1           3            1           1  setosa
2             1           2            1           1  setosa
3             1           2            1           1  setosa
4             1           2            1           1  setosa
5             1           3            1           1  setosa
6             1           3            1           1  setosa
7             1           3            1           1  setosa
8             1           3            1           1  setosa
9             1           1            1           1  setosa
10            1           2            1           1  setosa

chi2算法的结果解读,从输出结果可以看出,Sepal.Length Sepal.Width Petal.Length Petal.Width,这几个变量被自动地离散化处理了。

查看这4个列的离散化情况。


> apply(chi1$Disc.data,2,table)
$Sepal.Length
 1  2  3  4 
52 21 65 12 

$Sepal.Width
 1  2  3 
57 56 37 

$Petal.Length
 1  2  3  4 
50 45 21 34 

$Petal.Width
 1  2  3 
50 54 46 

$Species
    setosa versicolor  virginica 
        50         50         50 

再查看每个列的阈值。


# 查看分组阈值
> chi1$cutp
[[1]]
[1] 5.45 5.75 7.05

[[2]]
[1] 2.95 3.35

[[3]]
[1] 2.45 4.75 5.15

[[4]]
[1] 0.80 1.75

以第一组Sepal.Length举例,被分为4类,当源数据Sepal.Length列的值,小于 5.45值为1类,大于5.45同时小于5.75为2类,大于5.75同时小于7.05为3类,大于7.05为4类。

我们把离散化后的数据,与源数据进行合并进行观察。第一列是离散化后的数据,第二列是源数据。


> chi1df<-cbind(chi1$Disc.data$Sepal.Length,iris$Sepal.Length)
> head(chi1df,20)
      [,1] [,2]
 [1,]    1  5.1
 [2,]    1  4.9
 [3,]    1  4.7
 [4,]    1  4.6
 [5,]    1  5.0
 [6,]    1  5.4
 [7,]    1  4.6
 [8,]    1  5.0
 [9,]    1  4.4
[10,]    1  4.9
[11,]    1  5.4
[12,]    1  4.8
[13,]    1  4.8
[14,]    1  4.3
[15,]    3  5.8
[16,]    2  5.7
[17,]    1  5.4
[18,]    1  5.1
[19,]    2  5.7
[20,]    1  5.1

这样就完成了卡方分箱的操作,接下来的其他几个函数的使用,与chiM()的算法类似,就不再过多讨论了。

3.4 其他算法

chi2()算法,查看分组阈值。


> chi2<-chi2(iris,alp=0.5,del=0.05)
> chi2$cutp
[[1]]
[1] 3.5 4.5 6.5

[[2]]
[1] 3.5 4.5

[[3]]
[1] 1.5 2.5 3.5

[[4]]
[1] 1.5 3.5

modChi2()算法,查看分组阈值。


> chi3<-modChi2(iris,alp=0.5)
> chi3$cutp
[[1]]
[1] 1.5 2.5

[[2]]
[1] 2.5

[[3]]
[1] 1.5 2.5

[[4]]
[1] 1.5 2.5

extendChi2()算法,查看分组阈值。


> chi4<-extendChi2(iris,alp = 0.5)
> chi4$cutp
[[1]]
[1] 1.5 2.5

[[2]]
[1] 1.5 2.5

[[3]]
[1] 1.5 2.5

[[4]]
[1] 1.5 2.5

> m1<-mdlp(iris)
> m1$cutp
[[1]]
[1] 5.55 6.15

[[2]]
[1] 2.95 3.35

[[3]]
[1] 2.45 4.75

[[4]]
[1] 0.80 1.75

disc.Topdown()算法,查看分组阈值。


> d1<-disc.Topdown(iris,method=1)
> d1$cutp
[[1]]
[1] 4.30 5.55 6.25 7.90

[[2]]
[1] 2.00 2.95 3.05 4.40

[[3]]
[1] 1.00 2.45 4.75 6.90

[[4]]
[1] 0.10 0.80 1.75 2.50

最后,分箱需要注意的是,分完箱之后,某些箱区间里可能数据分布比例极不均匀,那么这样子会直接导致后续计算WOE时出现inf无穷大的情况,这是不合理的。这种情况,说明分箱太细,需要进一步缩小分箱的数量。

本文详细地介绍了无监督的离散化方法和有监督的离散化方法,针对不同的场景,我们可以选择不同的方法进行使用。R语言中,包提供了各种离散化的工具函数,使用起来很方便,可以大幅提供数据处理过程的效率。

转载请注明出处:
http://blog.fens.me/r-discretization

打赏作者

HiBlock社区:区块链链上数据的认知与探索

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹(Conan), 程序员/Quant: Java,R,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-hiblock-20180826

前言

数字货币百花齐放,数字货币开发是区块链开发者的必修课也是入门课,通过ERC20智能合约很快就可以掌握开发技巧,但数字货币的安全如何保障?数字货币交易过程中产生了大量的数据,资金流转规律、操盘方式、筹码分布等等,通过数据预测数字货币价格走势也不是没有可能,除此之外区块链产生的数据还有什么价值?

本次的沙龙2个主题,一个是安全,一个是数据。

目录

  1. 我的演讲主题:区块链链上数据的认知与探索
  2. 会议体验和照片分享

1. 我的演讲主题:区块链链上数据的认知与探索

本次的沙龙2个主题,一个是安全,一个是数据,都是技术流!!所以,来听的也都是技术流,很少人,但很聊的来。

我本次分享的主题为:区块链链上数据的认知与探索,PPT下载,主要内容来自我的1篇博客文篇:区块链链上数据的认知与探索(未发布)。

分享主题的目录大纲如下:

  1. 认识区块链
  2. 区块浏览器
  3. 链上数据探索

主题简介:区块链上所有的交易都是公开透明的,链上账本会记录所有参与者交易行为,包括资金流转规律,庄家操盘,筹码分布等,价值巨大,从数据科学的角度,分享对区块链链上数据进行的认知与探索。

本此分析主要是从数据的角度切入,开始先介绍区块链,让大家有所认知;然后介绍区块链有什么样的数据,区别场内数据和场外数据;最后引出主题,对场外数据进行数据探索,通过账本的交易流水发现这些数据中的规律性的行为,坐庄行为,散户行为,拉盘行为….

数据是很有意思的,希望大家能够了解链上数据,用技术的武器去发现和鉴别真实的交易。

2. 会议体验和照片分享

本次线下沙龙的核心主题为,技术维度解读数字货币安全与数据价值,会议的主页:http://www.huodongxing.com/event/3453087067011

30人的小沙龙,定位就是区块链的技术圈,同业交流。我的分享是 “区块链链上数据的认知与探索” 也是在我这次转型积累的新的经验,跨学科的知识结合,从数据的角度理解区块链。

会议主题:

  • 14:00-14:05 开场 主办方介绍
  • 14:05-14:30 参会者自我介绍
  • 14:30-15:30《智能合约审计》分享嘉宾:赵威
  • 15:30-16:30《区块链链上数据的认知与探索》分享嘉宾:张丹
  • 16:30-17:00 合影 交流

我的介绍和照片分享。

分布式科技CTO,《R的极客理想-量化投资篇》作者,微软MVP。10年编程经验,获得10项SUN及IBM技术认证。前民生银行大数据分析师。个人博客 http://fens.me, Alexa全球排名70K。

2.2 会议相关照片

本次的场地在北京朝阳区建国路89号华贸商务楼16号B1 联合创业办公社,看上去更像是一个活动吧。

主持人:成芳

张丹,区块链链上数据的认知与探索

赵威, 智能合约审计

会后交流

政策条文: 分享开始前特意被关照,只能讲技术,不要讲其他的,最近太敏感,可能随时会被叫停!我们搞技术的人,底线是一定不会触碰的!!

布置会场。

大合照

主办方的小伙伴很辛苦,就一个小姑娘!坚持支持分享,保持高质量,坚持!坚持!

转载请注明出处:
http://blog.fens.me/meeting-hiblock-20180826

打赏作者

2018Finance-AI社区:区块链链上数据的认知与探索

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹(Conan), 程序员/Quant: Java,R,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-financeai-20180614

前言

第一次在公开场合分享区块链,是一个好的开始。2017底到现在,中国经济在去杠杠,又要打贸易战,P2P各种爆仓,银行缩表,房市限购,人民币对美元大幅贬值,各种事情都在给这个浮躁的社会降温。

区块链的世界却是一片火热,各种人都在炒作概念,搞搞投机。数据,可以说是区块链里最能落地的事情,公链上记录的账本数据,对所有人都是公开的,数据之间藏着大量地真实的交易行业为,是数据学科家最好的探索的素材。

目录

  1. 我的演讲主题:区块链链上数据的认知与探索
  2. 会议体验和照片分享

1. 我的演讲主题:区块链链上数据的认知与探索

首先,感谢主办方的Aislinn的邀请。我本次分享的主题为:区块链链上数据的认知与探索,PPT下载,主要内容来自我的1篇博客文篇:区块链链上数据的认知与探索(未发布)。

分享主题的目录大纲如下:

  1. 认识区块链
  2. 区块浏览器
  3. 链上数据探索

主题简介:区块链上所有的交易都是公开透明的,链上账本会记录所有参与者交易行为,包括资金流转规律,庄家操盘,筹码分布等,价值巨大,从数据科学的角度,分享对区块链链上数据进行的认知与探索。

本此分析主要是从数据的角度切入,开始先介绍区块链,让大家有所认知;然后介绍区块链有什么样的数据,区别场内数据和场外数据;最后引出主题,对场外数据进行数据探索,通过账本的交易流水发现这些数据中的规律性的行为,坐庄行为,散户行为,拉盘行为….

数据是很有意思的,希望大家能够了解链上数据,用技术的武器去发现和鉴别真实的交易。

2. 会议体验和照片分享

本次线下沙龙的核心主题为“突围”,在AI时代,我们如何进行突围,会议的主页:http://www.huodongxing.com/event/7448082509300?td=7742536708807

120人的小沙龙,有5500多人浏览和193个收藏,不得不说主办方的组织能力。同时也能看出,本次的主题定位,就是当下时代大家最关心的话题。我的分享是 “区块链链上数据的认知与探索” 也是在我这次转型积累的新的经验,跨学科的知识结合,迎接AI时代。

会议主题:

  • Finance·AI社区金融算法介绍 Aislinn
  • 主题分享《大牛组团的年代,怎么做才能突围》 Kevin
  • 深度对话 《AI时代个人成长迭代之路 》 Aislinn对话Kevin
  • 主题分享 《区块链链上数据的认知与探索》 张丹
  • 主题分享 《知识图谱在金融风控中的应用》 邵平
  • 圆桌论坛 《金融算法职场与精进》Aislinn对话邵平和张丹
  • 金融算法社区学习计划 Aislinn

我的介绍和照片分享。

分布式科技CTO,《R的极客理想-量化投资篇》作者,微软MVP。10年编程经验,获得10项SUN及IBM技术认证。前民生银行大数据分析师。个人博客 http://fens.me, Alexa全球排名70K。

2.2 会议相关照片

本次的场地在 在(北京朝阳)云享客 · 长富宫中心(建国门外大街26号5号楼一层),一个很适合活动聚会的咖啡厅。

kevin的分享:大牛组团的年代,怎么做才能突围

邵平的分享:知识图谱在金融风控中的应用

现场的同学们。

布置会场。

茶点,小吃。

主办方的小伙伴辛苦啦!!获得嘉宾和听众的一致好评!继续高质量坚持!

转载请注明出处:
http://blog.fens.me/meeting-financeai-20180614

打赏作者

miniCRAN离线安装R的依赖库

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,Nodejs
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-install-offline

前言

最近经常去有网络隔离的机构,每次安装R语言的环境都是特别痛苦的经历。物理网络完全隔绝,不能通过互联网进行R语言的安装,只能预先下载所有软件,再进行安装。

对于有众多依赖的库,安装过程就变得很复杂了。无意中,发现了一个可以找到每个包的依赖包的库miniCRAN,让这个安装包过程,变得自动化一点。

目录

  1. 离线安装R的依赖库的过程
  2. miniCRAN介绍
  3. 5分钟上手
  4. miniCRAN包的函数介绍
  5. miniCRAN的使用方法

1. 离线安装R的依赖库的过程

对于物理网络完全被隔绝的情况,我们不能通过互联网进行R语言的安装,只能预先下载所有软件,再进行安装。

操作过程包括以下几步操作:

  1. 在有网的环境中,下载系统软件,比例 windows环境要下载对应的.net framework。
  2. 在有网的环境中,下载R语言软件。
  3. 在有网的环境中,下载第三方软件包,比如xts包。
  4. 在有网的环境中,用miniCRAN找到xts包,所有的依赖包。
  5. 在有网的环境中,下载所有的依赖包。
  6. 通过U盘或者其他的方式,复制到无网的环境中。
  7. 分别安装系统软件,R语言软件,依赖包,软件包。
  8. 重复以上过程,直到把软件都安装好。

以上操作过程中,最复杂的操作就在于找到所有的依赖包。

2. miniCRAN介绍

miniCRAN包,主要用于发现软件包的依赖关系。R语言中,每个包一般都其所依赖的扩展包,对于企业或者机构内网来说,由于防火墙或者基于安全的管理规则,不允许从互联网下载安装。那么,用户就需要从CRAN中,下载对应的软件包,一个一个安装。通过miniCRAN包,可以递归读取这些软件包的依赖关系,然后就可以下载这些依赖包了。

开发环境所使用的系统环境

  • Win10 64bit
  • R: 3.2.3 x86_64-w64-mingw32/x64 b4bit

miniCRAN包的安装比较简单,直接用install.pacakges()函数就行。


> install.packages("miniCRAN")
         binary source needs_compilation
miniCRAN  0.2.7 0.2.11             FALSE

installing the source package 'miniCRAN'

URLhttp://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib/miniCRAN_0.2.11.tar.gz'
Content type 'application/octet-stream' length 4114313 bytes (3.9 MB)
downloaded 3.9 MB

* installing *source* package 'miniCRAN' ...
** 'miniCRAN'MD5
** R
** data
*** moving datasets to lazyload DB
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
*** arch - i386
*** arch - x64
* DONE (miniCRAN)

3. 5分钟上手

我们先做一个小的测试,分析一下chron包如果本地安装,都需要使用哪些包,会有哪些依赖关系。我们打开CRAN上面的,官方项目网页,https://cran.r-project.org/web/packages/xts/

xts唯一强依赖的包(depends)是zoo,引用R系统包methods,同时建议安装timeSeries, timeDate, tSeries, chron, fts, tis, RUnit包。

接下来,我们通过miniCRAN找到xts包的依赖关系。


> library(miniCRAN)
> tags <- "xts"
> pkgDep(tags, availPkgs = cranJuly2014)
 [1] "xts"          "zoo"          "lattice"     
 [4] "timeDate"     "quadprog"     "Hmisc"       
 [7] "survival"     "Formula"      "latticeExtra"
[10] "cluster"      "RColorBrewer" "BH"          
[13] "timeSeries"   "tseries"      "its"         
[16] "chron"        "fts"          "tis"    

画出依赖关系图。


> dg <- makeDepGraph(tags, enhances = TRUE, availPkgs = cranJuly2014)
> plot(dg, legendPosition = c(-1, 1), vertex.size = 20)

从图中,可以把整个的依赖关系看得很清楚了。

4. miniCRAN包的函数介绍

整个miniCRAN包大概有20多个函数,其中最有用的函数就是pkgDeg()和pkgAvail()。

4.1 pkgDeg()函数

pkgDeg()函数,主要对Depends,Imports和LinkLibrary执行递归检索,对Suggests执行非递归检索。


pkgDep(pkg, availPkgs, repos = getOption("repos"), type = "source",
  depends = TRUE, suggests = TRUE, enhances = FALSE,
  includeBasePkgs = FALSE, Rversion = R.version, quiet = FALSE, ...)

参数解读:

  • pkg: 包名
  • availPkgs: 所有包列表
  • repos: CRAN软件源
  • type: 下载类型,源代或二进制
  • depends: 依赖关系,包括Depends, Imports, LinkingTo
  • suggests: 建议关系
  • enhances: 增强关系
  • includeBasePkgs: 是否包括R base包
  • Rversion: R版本

4.2 pkgAvail()函数

pkgAvail()函数,是对 available.packages()函数的一个封装。如果提供了参数路径,那么该函数将尝试从本地存储库读取数据,否则尝试从repos url的CRAN镜像读取数据。


pkgAvail(repos = getOption("repos"), type = "source",
  Rversion = R.version, quiet = FALSE)

参数解读:

  • repos: CRAN软件源
  • type: 下载类型,源代或二进制
  • Rversion: R版本

这个函数在我目前测试的版本中,有一些bug,可以用available.packages()函数来解决。

5. miniCRAN的使用方法

接下来,我们详细地介绍一下,找到某包的依赖的使用方法。

5.1 定义软件源

如果我们用install.packages()函数安装过软件包,在你的本地配置中,会有当前的软件源,那么我们可以用getOption()函数,来获得本地的软件源。


> repos<-getOption("repos")
> repos
                                        CRAN 
"https://mirrors.tuna.tsinghua.edu.cn/CRAN/" 
                                   CRANextra 
        "http://www.stats.ox.ac.uk/pub/RWin" 
attr(,"RStudio")
[1] TRUE

我当前环境中配置的CRAN软件源为 https://mirrors.tuna.tsinghua.edu.cn/CRAN/ 。

5.2 获得软件源的包列表

通过软件源URL,我们需要获得软件源的包列表。


> curl<-contrib.url(repos)
> aps<-available.packages(curl)

> head(aps)
            Package       Version Priority Depends                                               Imports                                  LinkingTo
A3          "A3"          "1.0.0" NA       "R (>= 2.15.0), xtable, pbapply"                      NA                                       NA       
abbyyR      "abbyyR"      "0.5.1" NA       "R (>= 3.2.0)"                                        "httr, XML, curl, readr, plyr, progress" NA       
abc         "abc"         "2.1"   NA       "R (>= 2.10), abc.data, nnet, quantreg, MASS, locfit" NA                                       NA       
ABCanalysis "ABCanalysis" "1.2.1" NA       "R (>= 2.10)"                                         "plotrix"                                NA       
abc.data    "abc.data"    "1.0"   NA       "R (>= 2.10)"                                         NA                                       NA       
abcdeFBA    "abcdeFBA"    "0.4"   NA       "Rglpk,rgl,corrplot,lattice,R (>= 2.10)"              NA                                       NA       
            Suggests                               Enhances License              License_is_FOSS License_restricts_use OS_type Archs MD5sum
A3          "randomForest, e1071"                  NA       "GPL (>= 2)"         NA              NA                    NA      NA    NA    
abbyyR      "testthat, rmarkdown, knitr (>= 1.11)" NA       "MIT + file LICENSE" NA              NA                    NA      NA    NA    
abc         NA                                     NA       "GPL (>= 3)"         NA              NA                    NA      NA    NA    
ABCanalysis NA                                     NA       "GPL-3"              NA              NA                    NA      NA    NA    
abc.data    NA                                     NA       "GPL (>= 3)"         NA              NA                    NA      NA    NA    
abcdeFBA    "LIM,sybil"                            NA       "GPL-2"              NA              NA                    NA      NA    NA    
            NeedsCompilation File Repository                                             
A3          "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
abbyyR      "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
abc         "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
ABCanalysis "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
abc.data    "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"
abcdeFBA    "no"             NA   "https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib"

取出xts包所对应的配置信息。


> aps[which(row.names(aps)=='xts'),]
                                                Package                                                 Version 
                                                  "xts"                                                "0.10-2" 
                                               Priority                                                 Depends 
                                                     NA                                       "zoo (>= 1.7-12)" 
                                                Imports                                               LinkingTo 
                                              "methods"                                                   "zoo" 
                                               Suggests                                                Enhances 
"timeSeries, timeDate, tseries, chron, fts, tis, RUnit"                                                      NA 
                                                License                                         License_is_FOSS 
                                           "GPL (>= 2)"                                                      NA 
                                  License_restricts_use                                                 OS_type 
                                                     NA                                                      NA 
                                                  Archs                                                  MD5sum 
                                                     NA                                                      NA 
                                       NeedsCompilation                                                    File 
                                                  "yes"                                                      NA 
                                             Repository 
"https://mirrors.tuna.tsinghua.edu.cn/CRAN/src/contrib" 

5.3 找到依赖包的列表

从所有的软件包中,找到对应软件依赖包的列表。


# 要找到xts和TTR软件的依赖包
> libs<-c("xts","TTR")
> pkgList<-pkgDep(pkg=libs,availPkgs=aps,repos=repos)
> pkgList
 [1] "xts"        "TTR"        "zoo"        "lattice"    "curl"       "timeDate"   "quadprog"  
 [8] "quantmod"   "BH"         "timeSeries" "tseries"    "chron"      "fts"        "tis"       
[15] "RUnit"     

5.4 下载所有依赖包

运行下载函数,下载所有的依赖包。


> dp<-download.packages(pkgList,"D:/workspace/R/miniCRAN/pgk",type=getOption("pkgType"))
> dp
      [,1]         [,2]                                                    
 [1,] "xts"        "D:/workspace/R/miniCRAN/pgk/xts_0.10-2.tar.gz"         
 [2,] "TTR"        "D:/workspace/R/miniCRAN/pgk/TTR_0.23-3.tar.gz"         
 [3,] "zoo"        "D:/workspace/R/miniCRAN/pgk/zoo_1.8-1.tar.gz"          
 [4,] "lattice"    "D:/workspace/R/miniCRAN/pgk/lattice_0.20-35.tar.gz"    
 [5,] "curl"       "D:/workspace/R/miniCRAN/pgk/curl_3.2.tar.gz"           
 [6,] "timeDate"   "D:/workspace/R/miniCRAN/pgk/timeDate_3043.102.tar.gz"  
 [7,] "quadprog"   "D:/workspace/R/miniCRAN/pgk/quadprog_1.5-5.tar.gz"     
 [8,] "quantmod"   "D:/workspace/R/miniCRAN/pgk/quantmod_0.4-13.tar.gz"    
 [9,] "BH"         "D:/workspace/R/miniCRAN/pgk/BH_1.66.0-1.tar.gz"        
[10,] "timeSeries" "D:/workspace/R/miniCRAN/pgk/timeSeries_3042.102.tar.gz"
[11,] "tseries"    "D:/workspace/R/miniCRAN/pgk/tseries_0.10-44.tar.gz"    
[12,] "chron"      "D:/workspace/R/miniCRAN/pgk/chron_2.3-52.tar.gz"       
[13,] "fts"        "D:/workspace/R/miniCRAN/pgk/fts_0.9.9.tar.gz"          
[14,] "tis"        "D:/workspace/R/miniCRAN/pgk/tis_1.34.tar.gz"           
[15,] "RUnit"      "D:/workspace/R/miniCRAN/pgk/RUnit_0.4.31.tar.gz"       

本地目录查看下载的文件。


> dir("D:/workspace/R/miniCRAN/pgk")
 [1] "BH_1.66.0-1.tar.gz"         "chron_2.3-52.tar.gz"        "curl_3.2.tar.gz"           
 [4] "fts_0.9.9.tar.gz"           "lattice_0.20-35.tar.gz"     "quadprog_1.5-5.tar.gz"     
 [7] "quantmod_0.4-13.tar.gz"     "RUnit_0.4.31.tar.gz"        "timeDate_3043.102.tar.gz"  
[10] "timeSeries_3042.102.tar.gz" "tis_1.34.tar.gz"            "tseries_0.10-44.tar.gz"    
[13] "TTR_0.23-3.tar.gz"          "xts_0.10-2.tar.gz"          "zoo_1.8-1.tar.gz"  

5.5 安装软件包

用R语言的函数,进行本地安装。


> install.packages(dp[,2], repos = NULL, type="source")

另外,我们也可以用命令行,进行安装。


> R CMD INSTALL D:\workspace\R\miniCRAN\pgk\zoo_1.8-1.tar.gz

通过使用miniCRAN包,就让我们找到依赖包的这事情,变得简单多了。再通过批量的离线下载,和批量的安装,就可以让我们的操作更有效率。不然,一个一包的安装,真是要把人给逼疯了!

虽然本文讲了通用的方法,但对于有一些包安装过程中,还需要从网上再下载其他的包,还需要具体问题具体分析,手动安装依赖包的过程,确实是无比复杂的。

转载请注明出处:
http://blog.fens.me/r-install-offline

打赏作者

用R语言解读凯利公式

用IT技术玩金融系列文章,将介绍如何使用IT技术,处理金融大数据。在互联网混迹多年,已经熟练掌握一些IT技术。单纯地在互联网做开发,总觉得使劲的方式不对。要想靠技术养活自己,就要把技术变现。通过“跨界”可以寻找新的机会,创造技术的壁垒。

金融是离钱最近的市场,也是变现的好渠道!今天就开始踏上“用IT技术玩金融”之旅!

关于作者:

  • 张丹(Conan), 程序员R,Nodejs,Java
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/finance-kelly

前言

职业做投机交易的人,应该都听说过凯利公式,这是一个通过计算胜率和赔率,来选择最佳投注比例的公式,目的是长期获得最高的盈利。

只要找到长期看必胜的局,接下来就是让时间帮我们赚钱了。

目录

  1. 开始赌局
  2. 凯利公式
  3. 赌局的最优解
  4. 让时间帮我们赚钱

1. 开始赌局

设游戏赌局,你赢的概率是80%,输的概率是20%,赢时的净收益率是100%,输时的亏损率也是100%。如果赢,你每赌1元可以赢得1元;如果输,则每赌1元将会输掉1元。赌局可以进行无限次,每次下的赌注可由你自己任意定。如果你的初始资金是100元,那么怎么样下注,才能使得长期收益最大?

对于胜率80%,从感觉上应该是很有把握的事情了。那么我们先主观判断一次,用90%的仓位去赌一下,看看结果怎么呢?如果下注10次,按80%胜率,8次胜,2次负。我们来算一下最后的结果。


# 设置胜负,1胜,0负
> win<-c(1,1,1,0,1,1,0,1,1,1)
 
# 分别按投注计算每回合的剩余资金 
> a1<-(1+0.9)*100
> a2<-a1*(1+0.9)
> a3<-a2*(1+0.9)
> a4<-a3*0.1
> a5<-a4*(1+0.9)
> a6<-a5*(1+0.9)
> a7<-a6*0.1
> a8<-a7*(1+0.9)
> a9<-a8*(1+0.9)
> a10<-a9*(1+0.9)
 
> dat<-c(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
> df<-data.frame(win,dat)

# 打印剩余资金列表
> df
   win      dat
1    1 190.0000
2    1 361.0000
3    1 685.9000
4    0  68.5900
5    1 130.3210
6    1 247.6099
7    0  24.7610
8    1  47.0459
9    1  89.3872
10   1 169.8356

10次交易后,赢了8次,只输了2次,我们从100元本金,上升到了169元,收益率为69%,还是不错的。最高的时候,资金为685元,收益率为685%,赚了6倍多。最低则是只剩下24元,真是赔的好惨啊!

接下来,画出资金曲线。这是一个过山车式的曲线,赚钱的时候非常猛,一旦赌输了,就产生了巨大的亏损。


# 画出资金曲线 
> plot(df$dat,type='l')

曲线很陡峭,波动很大,回撤也很大,完全就是在赌博。

怎么样才能让资金曲线好看一些呢?如果每次下注用少一点资金,是不是会更好呢?那么我继续试一下。分别计算每次下注资金为 60%,40%,20%,10%的4个维度的仓位的情况。


> library(magrittr)

# 定义现金流量函数:win=胜负结果,b=赔率,pos=仓位
> postion<-function(win,b=1,pos=0.6){            # 省略代码
+ }
 
# 设置胜负,1胜,0负
> win<-c(1,1,1,0,1,1,0,1,1,1) 
> prob<-0.8                      # 胜率
> n<-10                          # 赌局数
> b<-1                           # 赔率
> caption<-100                   # 金额
 
# 分别计算不同仓位的剩余现金
> pos90<-postion(win,b,0.9)*caption
> pos60<-postion(win,b,0.6)*caption
> pos40<-postion(win,b,0.4)*caption
> pos20<-postion(win,b,0.2)*caption
> pos10<-postion(win,b,0.1)*caption

# 合并到数据框
> df1<-data.frame(win,pos90,pos60,pos40,pos20,pos10)

# 打印计算结果
> df1
   win    pos90   pos60   pos40   pos20   pos10
1    1 190.0000 160.000 140.000 120.000 110.000
2    1 361.0000 256.000 196.000 144.000 121.000
3    1 685.9000 409.600 274.400 172.800 133.100
4    0  68.5900 163.840 164.640 138.240 119.790
5    1 130.3210 262.144 230.496 165.888 131.769
6    1 247.6099 419.430 322.694 199.066 144.946
7    0  24.7610 167.772 193.617 159.252 130.451
8    1  47.0459 268.435 271.063 191.103 143.496
9    1  89.3872 429.497 379.489 229.324 157.846
10   1 169.8356 687.195 531.284 275.188 173.631

我们看到,只是简单地调整了交易的仓位比例,那么交易10次后,你剩余的现是就是有很大的不同的。其中pos60列,即60%仓位的交易,获得的回报最高为687元,而90%的仓位获得的回报,是这里面最少的。而且非常有意思的是,后面的4种仓位设置,每次交易后的资金都大于100元的原始本金。

画出资金曲线


> library(ggplot2)
> library(scales)
> library(reshape2)

# 数据转型 
> df1$num<-1:nrow(df1)
> df<-melt(df1[,-1],id.vars="num")
 
# 画图 
> g<-ggplot(df,aes(x=num,y=value,colour=variable ))
> g<-g+geom_line()
> g

从图中可以看到,对于高胜率的情况,大的仓位是可以有高回报的,但是风险也大;小仓位是相对平稳的增长。

2. 凯利公式

那么多少的仓位是最优的呢?接下来的问题,就是凯利公式会告诉我们的。

在概率论中,凯利公式(The Kelly Criterion)是一个用以使特定赌局中,拥有正期望值之重复行为长期增长率最大化的公式,由约翰·拉里·凯利于1956年在《贝尔系统技术期刊》中发表,可用以计算出每次游戏中应投注的资金比例。

除可将长期增长率最大化外,此公式不会在任何赌局中,有失去全部现有资金的可能,因此有不存在破产疑虑的优点。公式中,假设货币与赌局可无限分割,只要资金足够多,长期一定是会赚到钱的。

凯利公式的最一般性陈述为,寻找能最大化结果对数期望值的资本比例f,即可获得长期增长率的最大化。对于只有两种结果的简单赌局而言,即 输失去所有本金,胜获得资金乘以特定的赔率。

可以用下面公式来表示:

其中

  • f* 投注的比例
  • b 赔率,盈亏比,即平均一次盈利与一次亏损两者的比例
  • p 胜率
  • q 败率,即 1 – p

用凯利公式对上面的例子进行测试,胜率p=0.8,失败率q=1-p=0.2,赔率b=1,失败则下注资金完全损失,计算下注比例为


f* = (b*p-q)/b = (1*0.8-0.2)/1=0.6

所以,赌客应在每次机会中下注现有资金的60%,可以获得最大化资金的长期增长率。

通过数学变型,可以很容易得到凯利公式的另一种表达式


Kelly % = W – [(1 – W) / R]

其中Kelly % 就是上式中的f*,W就是p胜率,R就是b赔率。两者看似不同,其实完全等效一致。

对于上面的例子,我们可以计算


Kelly % = W – [(1 – W) / R] = 0.8-[(1-0.8)/1] = 0.6 

凯利公式,有一个优化的变型。如果每次下注失败后,不是全部亏损,只是亏损部分,我们对上面公式可以做一个优化,增加亏损比例参数c,公式改写为下面格式


f* =  (b*p-c*q)/c*b

其中

  • f* 投注的比例
  • b 赔率,盈亏比,即平均一次盈利与一次亏损两者的比例
  • p 胜率
  • q 败率,即 1 – p
  • c 亏损比例

对于上面的例子,如果每次亏损是c=0.8,其他条件不变,那么我们应该用什么仓位进行交易呢?


f* = (b*p-q)/b = (1*0.8-0.8*0.2)/(0.8*1)=0.8

通过计算结果是0.8,我可以增大仓位。

凯利公式定义了长期获得最高的盈利的仓位确认的计算方法,我们自己也可以按照凯利公式的数学定义,进行推到一下。

假设一个赌局,每投资1,有p的概率可获得额外正收益W,有q=1-p的概率可获得额外的负收益-L,每次投资比例为x,建立收益为f(x)的目标函数,使得期望收益最大化。

转化为规划问题:

从推到可看出,标准的凯利公式只是当L=1的情况是一个应用,通过优化可增加了亏损比例参数。

3. 赌局的最优解

我们已经把公式介绍的很清楚了,那么接下来,就可以用程序实现进行实现了。


# 凯利公式,实现函数
> kelly<-function(prob,b=1,loss=1){   # 省略代码
+ }

用凯利公式计算的上文中的例子。


> prob<-0.8                     # 胜率
> b<-1                          # 赔率
> k<-kelly(prob,b,1);k
[1] 0.6

这时通过凯利公式,我们就能算出最最优的解其实是0.6的仓位设置,也就可以解释,上面的结果60%的仓位占比,获得的收益是最大的。

接下来,我们再比较一下不同的胜率和赔率的最优解是什么?

大胜率和大赔率时,可以重仓。当80%的胜率,2倍赔率时,仓位为70%。


> kelly(0.8,2)
[1] 0.7

通常情况下的赌局,不足50%的胜率,高赔率时,可以轻仓。当45%的胜率,2倍赔率时,仓位为17.5%。


> kelly(0.45,2)
[1] 0.175

通常情况下的赌局,不足50%的胜率,低赔率时,不要参考。当45%的胜率,1倍赔率时,不参与赌局。


> kelly(0.45,1)
[1] "Lost!!!"
[1] 0

小胜率,中等赔率时,不要参与。


> kelly(0.2,1)
[1] "Lost!!!"
[1] 0

小胜率,中等赔率时,中等损失,不要参与。


> kelly(0.2,1,0.5)
[1] "Lost!!!"
[1] 0

小胜率,中等赔率时,很小损失,可以All in。很小的损失比例,其实是变相的增大了赔率。


> kelly(0.2,1,0.1)
[1] "All In"
[1] 1

大胜率,很小赔率,很小损失,All in。


> kelly(0.8,0.1,0.1)
[1] "All In"
[1] 1

中胜率,很小赔率,很小损失,不要参与。


> kelly(0.45,0.1,0.1)
[1] "Lost!!!"
[1] 0

总结一下,投机操作的游戏规则。

胜率 赔率 损失率 仓位 指导建议 备注
80% 2 100% 70% 重仓 大胜率、大赔率、全部损失
45% 2 100% 17.5% 轻仓 中胜率、大赔率、全部损失
45% 1 100% 0 离场 中胜率、中赔率、全部损失
20% 1 100% 0 离场 小胜率、中赔率、全部损失
20% 1 50% 0 离场 小胜率、中赔率、中等损失
20% 1 10% 100% 满仓 小胜率、中赔率、小损失
80% 10% 10% 100% 满仓 大胜率、小赔率、小损失
45% 10% 10% 0 离场 中胜率、小赔率、小损失

这样我们就判断出,哪些投机操作值得玩,哪些不能玩,应该怎么玩。是不是很神奇!!

4. 让时间帮我们赚钱

根据凯利公式的定义,赌局可以进行无限次,那么当真的把赌局设置为很大时,会是什么情况呢?

我们把第一次的数据,进行100次的赌局,胜率为80%,赔率为1,金额100元,看一下结果。


> n<-100                          # 赌局数
> prob<-0.8                       # 胜率
> b<-1                            # 赔率
> caption<-100                    # 金额

# 基本二项分布,生成每盘的赌局正负
> set.seed(1)
> win<-rbinom(n,1,prob)
 
# 生成每盘的资金
> pos90<-postion(win,b,0.9)*caption   # 90%仓位
> pos60<-postion(win,b,0.6)*caption   # 60%仓位
> pos40<-postion(win,b,0.4)*caption   # 40%仓位
> pos20<-postion(win,b,0.2)*caption   # 20%仓位
> pos10<-postion(win,b,0.1)*caption   # 10%仓位

# 打印数据
> df2<-data.frame(win,pos90,pos60,pos40,pos20,pos10)
> tail(df2)
    win     pos90       pos60       pos40   pos20   pos10
95    1 105083487 5.73375e+11  9874948167 5067085 34506.6
96    1 199658625 9.17399e+11 13824927434 6080503 37957.3
97    1 379351388 1.46784e+12 19354898407 7296603 41753.0
98    1 720767637 2.34854e+12 27096857770 8755924 45928.3
99    0  72076764 9.39417e+11 16258114662 7004739 41335.5
100   1 136945851 1.50307e+12 22761360527 8405687 45469.0

从100盘赌局后的结果来看,60%的仓位可以获得最高收益的,为1.50307e+12,比其他的仓位都要高少非常。

接下来,我们生成资金曲线图。


# 数据转型
> df2$num<-1:nrow(df2)
> df<-melt(df2[,-1],id.vars = "num")

# 画图 
> g<-ggplot(df,aes(x=num,y=value,colour=variable ))
> g<-g+geom_line()
> g<-g+scale_y_log10()  # y坐标轴log化
> g

资金曲线图能非常直观地告诉了我们,什么的仓位有什么样曲线形状。你如果追求低风险,就用10%仓位稳健上涨。90%接近满仓并不是最赚钱的,反而是60%的仓位是有最大的回报。

我们再用凯利公式进行计算,可以发现结果最优的结果也是60%。


> kelly(prob,1)
[1] 0.6

神奇的算法,可以有效的帮我们控制仓位,最大化长期收益。只要找到长期必胜的局,接下来就是让时间帮我们赚钱了。下一篇文章,将介绍凯利公式在金融市场应用的应用。

写文章很辛苦,如果需要获得本文源代码或加入量化投资社群,请扫下面二维码,请作者喝杯咖啡。

转载请注明出处:
http://blog.fens.me/finance-kelly

打赏作者