• 粉丝日志首页

R语言轻巧的时间包hms

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-hms/

前言
时间是数据的基本维度,是在做数据处理的时候,必须要掌握的技术。根据时间周期的不同,通常把时间分为,年、月、日、时、分、秒、毫秒等。对于年月日的数据是最常见的,也有很多的处理工具,时分秒的数据通常也会用处理日期的工具,这样有时候就不太方便。

hms包,很小很轻,专注于时、分、秒的时间数据处理。

目录

  1. hms包介绍
  2. hms包的使用

1. hms包介绍

hms包,用于存储和格式化时间,基于difftime类型,使用S3的面向对象数据结构。

本文的系统环境为:

  • Win10 64bit
  • R: 3.4.2 x86_64-w64-mingw32

安装hms包,非常简单,一条命令就可以了。


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

函数列表:

  • hms: 创建一个hms类型对象
  • is.hms: 判断是否是hms类型
  • parse_hm: 解析hm值
  • parse_hms: 解析hms值
  • round_hms:四舍五入对齐
  • trunc_hms:裁剪对齐
  • as.hms: hms泛型函数,S3类型,用于隐式调用它的继承函数
  • as.hms.character: character转型hms,用于as.hms的继承调用
  • as.hms.default: hms转型hms,用于as.hms的继承调用
  • as.hms.difftime:difftime转型hms,用于as.hms的继承调用
  • as.hms.numeric: numeric转型hms,用于as.hms的继承调用
  • as.hms.POSIXlt: POSIXlt转型hms,用于as.hms的继承调用
  • as.hms.POSIXt: POSIXt转型hms,用于as.hms的继承调用
  • as.character.hms: hms转型character,用于as.character的继承调用
  • as.data.frame.hms: hms转型data.frame,用于as.data.frame的继承调用
  • as.POSIXct.hms: hms转型POSIXct,用于as.POSIXct的继承调用
  • as.POSIXlt.hms: hms转型POSIXlt,用于as.POSIXlt的继承调用
  • format.hms: 格式化hms,用于format的继承调用
  • print.hms: 打印hms对像,用于print的继承调用

从函数列表可以看到,hms包的功能很单一,就在做数据类型和数据变型,是底层的数据结构包,设计思路与zoo包的设计思路一致。zoo包的详细介绍,请参考文章R语言时间序列基础库zoo

hms包中,有大量的as.xxx()函数、format.hms()函数和print.hms()函数,是被用于S3类型函数继承调用的,是不需要我们在写程序的时候显示调用的。S3数据结构详细介绍,请参考文章R语言基于S3的面向对象编程

2. hms包的使用

接下来,我们找几个重点函数进行介绍。

2.1 hms()函数
hms()函数,用于创建一个hms类型的对象。
函数定义:

hms(seconds = NULL, minutes = NULL, hours = NULL, days = NULL)

hms()函数,接收4个参数,分别对应秒,分,时,日。

创建hms对象


# 创建12:34:56的时间对象
> a1<-hms(56, 34, 12);a1
12:34:56

# 创建 10日12:34:56的时间对象
> a2<-hms(56, 34, 12,10);a2
252:34:56

打印结果的第一位252=10*24+12。

2.2 is.hms: 判断是否是hms类型


# 判断是否是hms类型
> is.hms(a1)
[1] TRUE

# 查看hms类型,父类是difftime类型
> class(a1)
[1] "hms"      "difftime"

# 查看hms的属性
> attributes(a1)
$units
[1] "secs"

$class
[1] "hms"      "difftime"

# 查看hms对象的静态数据结构
> str(a1)
Classes 'hms', 'difftime'  atomic [1:1] 45296
  ..- attr(*, "units")= chr "secs"

# 查看面向对象类型
> library(pryr)
> otype(a1)
[1] "S3"

2.3 as.xxx.hms:把hms转型到其他类型


# 默认转型
> as.hms(a1)
12:34:56

# hms转型character,实际会隐式调用as.character.hms()函数
> as.character(a1)
[1] "12:34:56"

# hms转型POSIXct
> as.POSIXct(a1)
[1] "1970-01-01 12:34:56 UTC"

# hms转型POSIXlt
> as.POSIXlt(a1)
[1] "1970-01-01 12:34:56 UTC"

由于我们没有定义as.Date.hms()函数,所以as.Date()函数,不能认识hms类型的转换。


# hms转型Date
> as.Date(a1)
Error in as.Date.default(a1) : 不知如何将'a1'转换成“Date”类别
Error during wrapup: cannot open the connection

自己定义一个as.Date.hms()函数,仅用于转型实验,没有实际业务意义。


# 函数定义
> as.Date.hms<-function(hms){
+   s<-paste(Sys.Date(),' ',hms,sep="")
+   as.Date(s)
+ }

# 显示调用函数
> as.Date.hms(a1)
[1] "2018-12-14"

# 隐式调用函数
> as.Date(a1)
[1] "2018-12-14"

2.4 as.hms.xxx:把其他类型转型到hms


# 把字符串转hms
> as.hms('19:13:14')
19:13:14
# 非法时间字符串转型
> as.hms('19:78:14')
NA

# 数字转型
> as.hms(111312)
30:55:12

# 时间转型
> as.hms(Sys.time())
14:22:59.462795

# 日期转型,同样发生了错误
> as.hms(Sys.Date())
Error: Can't convert object of class Date to hms.
Error during wrapup: cannot open the connection

2.5 parse_hms()/parse_hm()字符串解析

parse_hms对字符串进行转型,对比parse_hms()与as.hms()结果一样的。


# 执行parse_hms
> parse_hms("12:34:56.789")
12:34:56.789
> as.hms("12:34:56.789")
12:34:56.789

# 执行parse_hm
> parse_hm("12:34")
12:34:00
> as.hms("12:34")
NA

打印parse_hms 函数名,查看源代码实现。


> parse_hms 
function (x) {
as.hms(as.difftime(as.character(x), format = "%H:%M:%OS",
units = "secs"))
}
>environment: namespace:hms<

parse_hms()函数,实际就是调用了as.hms()函数。

2.6 round_hms/trunc_hms
round_hms()函数,是把时间进行四舍五入对齐。


# 按秒,以5的倍数进行对齐,四舍五入
> round_hms(as.hms("12:34:51"), 5)
12:34:50
> round_hms(as.hms("12:34:54"), 5)
12:34:55
> round_hms(as.hms("12:34:56"), 5)
12:34:55
> round_hms(as.hms("12:34:59"), 5)
12:35:00

# 按秒,以60的倍数对齐
> round_hms(as.hms("12:34:56"), 60)
12:35:00

trunc_hms()函数,是把时间进行裁剪对齐。


# 按秒去掉末位,以5的倍数进行对齐
> trunc_hms(as.hms("12:34:01"), 5)
12:34:00
> trunc_hms(as.hms("12:34:44"), 5)
12:34:40
> trunc_hms(as.hms("12:34:56"), 60)
12:34:00

2.7 在data.frame中插入hms列


# 创建data.frame
> df<-data.frame(hours = 1:3, hms = hms(hours = 1:3))
> df
  hours      hms
1     1 01:00:00
2     2 02:00:00
3     3 03:00:00

# 查看df的静态结构
> str(df)
'data.frame':	3 obs. of  2 variables:
 $ hours: int  1 2 3
 $ hms  :Classes 'hms', 'difftime'  atomic [1:3] 3600 7200 10800
  .. ..- attr(*, "units")= chr "secs"

hms包很轻巧很简单,但却可以快速提高帮助我们处理时分秒数据,这些基础函数库是需要我们完全掌握和熟练运用的。

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

打赏作者

用R语言实现密度聚类dbscan

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-cluster-dbscan

前言

聚类是一种将数据点按一定规则分群的机器学习技术,k-Means聚类是被用的最广泛的也最容易理解的一种。除了K-Means的方法,其实还有很多种不同的聚类方法,本文将给大家介绍基于密度的聚类,我们可以通过使用dbscan包来实现。

目录

  1. DBSCAN基于密度的聚类
  2. dbscan包介绍
  3. kNN()函数使用
  4. dbscan()函数使用
  5. hdbscan()函数使用

1. DBSCAN基于密度的聚类

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)聚类算法,它是一种基于高密度连通区域的基于密度的聚类算法,能够将具有足够高密度的区域划分为簇,并在具有噪声的数据中发现任意形状的簇。

DBSCAN需要两个重要参数:epsilon(eps)和最小点(minPts)。参数eps定义了点x附近的邻域半径ε,它被称为x的最邻居。参数minPts是eps半径内的最小邻居数。

上图中(a),数据集中的任何点x邻居(6=minPts)都被标记为核心点,ε是半径。上图中(b),x为核心点,y的邻居小于(4<minpts)是边界点,但它属于核心点x的最邻居。z点既不是核心也不是边界点,它被称为噪声点或异常值。

dbscan算法将数据点分为三类:

  • 核心点:在半径eps内含有超过minPts数目的点。
  • 边界点:在半径eps内点的数量小于使用DBSCAN进行聚类的时候,不需要预先指定簇的个数,最终的簇的个数不确定。minPts,但是落在核心点的邻域内的点。
  • 噪音点:既不是核心点也不是边界点的点

DBSCAN算法的执行过程

1、DBSCAN算法随机从一个未被访问的数据点x开始,以eps为半径搜索范围内的所有邻域点。

2、如果x点在该邻域内有足够数量的点,数量大于等于minPts,则聚类过程开始,并且当前数据点成为新簇中的第一个核心点。否则,该点将被标记为噪声。该点都会被标记为“已访问”。

3、新簇中的每个核心点x,它的eps距离邻域内的点会归为同簇。eps邻域内的所有点都属于同一个簇,然后对才添加到簇中的所有新点重复上述过程。

4、重复步骤2和3两个过程,直到确定了簇中的所有点才停止,即访问和标记了聚类的eps邻域内的所有点。

5、当完成了这个簇的划分,就开始处理新的未访问的点,发现新的簇或者是噪声。重复上述过程,直到所有点被标记为已访问才停止。这样就完成了,对所有点的聚类过程。

优点和缺点

DBSCAN具有很多优点,提前不需要确定簇的数量。不同于Mean-shift算法,当数据点非常不同时,会将它们单纯地引入簇中,DBSCAN能将异常值识别为噪声。另外,它能够很好地找到任意大小和任意形状的簇。

DBSCAN算法的主要缺点是,当数据簇密度不均匀时,它的效果不如其他算法好。这是因为当密度变化时,用于识别邻近点的距离阈值ε和minPoints的设置将随着簇而变化。在处理高维数据时也会出现这种缺点,因为难以估计距离阈值eps。

2. dbscan包介绍

dbscan包,提供了基于密度的有噪声聚类算法的快速实现,包括 DBSCAN(基于密度的具有噪声的应用的空间聚类),OPTICS(用于识别聚类结构的排序点),HDBSCAN(分层DBSCAN)和LOF(局部异常因子)算法,dbscan底层使用C++编程,并建立kd树的数据结构进行更快的K最近邻搜索,从而实现加速。

本文的系统环境为:

  • Win10 64bit
  • R 3.4.2 x86_64

dbscan包的安装非常简单,只需要一条命令就能完成。


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

函数列表:

  • dbscan(), 实现DBSCAN算法
  • optics(), 实现OPTICS算法
  • hdbscan(), 实现带层次DBSCAN算法
  • sNNclust(), 实现共享聚类算法
  • jpclust(), Jarvis-Patrick聚类算法
  • lof(), 局部异常因子得分算法
  • extractFOSC(),集群优选框架,可以通过参数化来执行聚类。
  • frNN(), 找到固定半径最近的邻居
  • kNN(), 最近邻算法,找到最近的k个邻居
  • sNN(), 找到最近的共享邻居数量
  • pointdensity(), 计算每个数据点的局部密度
  • kNNdist(),计算最近的k个邻居的距离
  • kNNdistplot(),画图,最近距离
  • hullplot(), 画图,集群的凸壳

dbscan包,提供了多个好用的函数,我们接下来先介绍3个函数,分别是kNN(),dbscan(), hdbscan(),其他的函数等以后有时间,再单独进行使用介绍。

3. kNN()函数使用

kNN()函数,使用kd-tree数据结构,用来快速查找数据集中的所有k个最近邻居。

函数定义:


kNN(x, k, sort = TRUE, search = "kdtree", bucketSize = 10, splitRule = "suggest", approx = 0)

参数列表

  • x,数据矩阵,dist对象或kNN对象。
  • k,要查找的邻居数量。
  • sort,按距离对邻居进行排序。
  • search,最近邻搜索策略,使用kdtree,linear或dist三选一,默认为kdtree。
  • bucketSize,kd-tree叶子节点的最大值。
  • splitRule,kd-tree的拆分规则,默认用SUGGEST。
  • approx,使用近似方法,加速计算。

函数使用:以iris鸢尾花的数据集,做为样本。聚类是不需要有事前有定义的,所以我们把iris的种属列去掉。

# 去掉种属列
> iris2 <- iris[, -5]
> head(iris2)
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1          5.1         3.5          1.4         0.2
2          4.9         3.0          1.4         0.2
3          4.7         3.2          1.3         0.2
4          4.6         3.1          1.5         0.2
5          5.0         3.6          1.4         0.2
6          5.4         3.9          1.7         0.4

使用kNN()函数,来计算iris2数据集中,每个值最近的5个点。


# 查询最近邻的5个点
> nn <- kNN(iris2, k=5)

# 打印nn对象
> nn
k-nearest neighbors for 150 objects (k=5).
Available fields: dist, id, k, sort

# 查询nn的属性列表
> attributes(nn)
$names
[1] "dist" "id"   "k"    "sort"

$class
[1] "kNN" "NN" 

打印出,每个点最近邻的5个点。行,为每个点索引值,列,为最近邻的5个点,输出的矩阵为索引值。


> head(nn$id)
      1  2  3  4  5
[1,] 18  5 40 28 29
[2,] 35 46 13 10 26
[3,] 48  4  7 13 46
[4,] 48 30 31  3 46
[5,] 38  1 18 41  8
[6,] 19 11 49 45 20

打印出,每个点与最近的5个点的距离值。行,为每个点的索引,列,为最近邻的5个点,输出的矩阵为距离值。


> head(nn$dist)
             1         2         3         4         5
[1,] 0.1000000 0.1414214 0.1414214 0.1414214 0.1414214
[2,] 0.1414214 0.1414214 0.1414214 0.1732051 0.2236068
[3,] 0.1414214 0.2449490 0.2645751 0.2645751 0.2645751
[4,] 0.1414214 0.1732051 0.2236068 0.2449490 0.2645751
[5,] 0.1414214 0.1414214 0.1732051 0.1732051 0.2236068
[6,] 0.3316625 0.3464102 0.3605551 0.3741657 0.3872983

如果我们要查看索引为33的点,与哪5个点最紧邻,可以用下面的方法。


# 设置索引
> idx<-33

# 打印与33,最近邻的5个点的索引
> nn$id[idx,]
 1  2  3  4  5 
34 47 20 49 11 

# 画图
> cols = ifelse(1:nrow(iris2) %in% nn$id[idx,],"red", "black")
> cols[idx]<-'blue'
> plot(iris2,pch = 19, col = cols)

我们的数据集是多列的,把每2列组合形成的二维平面,都进行输出。蓝色表示索引为33的点,红色表示最紧邻的5个点,黑色表示其他的点。

从图中,可以很直观的看到,这几点确实是密集的在一起,也就是找到了最近邻。

接下来,我们画出连线图,选取第一列(Sepal.Length)和第二列(Sepal.Width),按取画出最紧邻前5连接路径。

> plot(nn, iris2)

通过连接路径,我们就能很清晰的看到,最紧邻算法的分组过程,连接在一起的就够成了一个分组,没有连接在一起的就是另外的分组,上图中可以看出来分成了2个组。

再对nn进行二次最近邻计算,画出前2的连接路径。

> plot(kNN(nn, k = 2), iris2)

通过2次的最紧邻缩减,连接路径大幅度减少了,又形成了新的独立区块。

2. dbscan()函数使用

dbscan是一种基于密度的聚类算法,这类密度聚类算法一般假定类别可以通过样本分布的紧密程度决定。同一类别的样本,他们之间的紧密相连的,也就是说,在该类别任意样本周围不远处一定有同类别的样本存在。

函数定义:

dbscan(x, eps, minPts = 5, weights = NULL, borderPoints = TRUE, ...)

参数解释:

  • x, 矩阵或者距离对象,frNN对象。
  • eps,半径的大小。
  • minPts, 半径区域中的最小点数量,默认为5
  • weights, 数据点的权重,仅用于加权聚类
  • borderPoints,边界点是否为噪声,默认为TRUE;为FALSE时,边界点为噪声。
  • …,将附加参数传递给固定半径最近邻搜索算法,调用frNN。

函数使用:以iris鸢尾花的数据集,做为样本。聚类是不需要有事前有定义的,所以我们把iris的种属列去掉。

# 去掉种属列
> iris2 <- iris[, -5]
> head(iris2)
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1          5.1         3.5          1.4         0.2
2          4.9         3.0          1.4         0.2
3          4.7         3.2          1.3         0.2
4          4.6         3.1          1.5         0.2
5          5.0         3.6          1.4         0.2
6          5.4         3.9          1.7         0.4

在使用dbscan函数时,我们要输出2个参数,eps和minPts。

  • eps,值可以使用绘制k-距离曲线(k-distance graph)方法得到,在k-距离曲线图明显拐点位置为较好的参数。若参数设置过小,大部分数据不能聚类;若参数设置过大,多个簇和大部分对象会归并到同一个簇中。
  • minPts,通常让minPts≥dim+1,其中dim表示数据集聚类数据的维度。若该值选取过小,则稀疏簇中结果由于密度小于minPts,从而被认为是边界点儿不被用于在类的进一步扩展;若该值过大,则密度较大的两个邻近簇可能被合并为同一簇。

下面我们通过绘制k-距离曲线,寻找knee,即明显拐点位置为对应较好的参数,找到适合的eps值。使用kNNdistplot()函数,让参数k=dim + 1,dim为数据集列的个数,iris2是4列,那么设置k=5。

# 画出最近距离图
> kNNdistplot(iris2, k = 5)
> abline(h=0.5, col = "red", lty=2)

kNNdistplot()会计算点矩阵中的k=5的最近邻的距离,然后按距离从小到大排序后,以图形进行展示。x轴为距离的序号,y轴为距离的值。图中黑色的线,从左到右y值越来越大。

通过人眼识别,k-距离曲线上有明显拐点,我们以y=0.5平行于x轴画一条红色线,突出标识。所以,最后确认的eps为0.5。

调用dbscan()函数,进行对iris2数据集进行聚类,eps=0.5,minPts=5。

> res <- dbscan(iris2, eps = 0.5, minPts = 5)
> res
DBSCAN clustering for 150 objects.
Parameters: eps = 0.5, minPts = 5
The clustering contains 2 cluster(s) and 17 noise points.

 0  1  2 
17 49 84 

Available fields: cluster, eps, minPts

聚类后,一共分成了2组,第1组49个值,第2组84个值,另外,第0组17个值为噪声点。把聚类的结果画图展示。

> pairs(iris, col = res$cluster + 1L)

数据集是多列的,把每2列组合形成的二维平面,都进行输出。红色点表示第1组,绿色点表示为第2组,黑色点表示噪声点。这样就完成了有噪声的基于密度的dbscan聚类。

5. hdbscan()函数使用

hdbscan(),快速实现了分层DBSCAN算法,与stats包中的hclust()方法形成的传统分层聚类方法类似。

函数定义:

hdbscan(x, minPts, xdist = NULL,gen_hdbscan_tree = FALSE, gen_simplified_tree = FALSE)

参数解释:

  • x,矩阵或者距离对象
  • minPts,区域中的最小点数量
  • xdist,dist对象,可以提前算出来,当参数传入
  • gen_hdbscan_tree,生成一个hdbscan树
  • gen_simplified_tree,生成一个简化的树结构

5.1 iris鸢尾花的数据集
以iris鸢尾花的数据集,做为样本,去掉种属列。设置minPts =5让当前群集中最小的数量为5,开始聚类。

> hcl<-hdbscan(iris2, minPts = 5);hcl
HDBSCAN clustering for 150 objects.
Parameters: minPts = 5
The clustering contains 2 cluster(s) and 0 noise points.

  1   2 
100  50 

Available fields: cluster, minPts, cluster_scores, membership_prob, outlier_scores, hc

聚类后,一共分成了2组,第1组100个值,第2组50个值,没有噪声点。生成的hcl对象包括6个属性。
属性解释

  • cluster,表明属性哪个群集,零表示噪声点。
  • minPts,群集中最小的数量
  • cluster_scores,每个突出(“平坦”)群集的稳定性分数之和。
  • membership_prob,群集内某点的“概率”或个体稳定性
  • outlier_scores,每个点的异常值
  • hc,层次结构对象

把聚类的结果画图展示。

> plot(iris2, col=hcl$cluster+1, pch=20)

数据集是多列的,把每2列组合形成的二维平面,都进行输出。红色点表示第1组,绿色点表示为第2组,这样就完成了hdbscan聚类。

打印hcl对象层次结构,包括150个数据,聚法方法是健壮单一的,距离是相互可达。

> hcl$hc

Call:
hdbscan(x = iris2, minPts = 5)

Cluster method   : robust single 
Distance         : mutual reachability 
Number of objects: 150 

画出层次的合并过程图

> plot(hcl$hc, main="HDBSCAN* Hierarchy")

从图可以清楚的看出,主要的2类的分支,区分度比较高。

5.2 moons数据集
由于iris数据集用hdbscan聚类获得的结果,与真实的数据分类结果不一致。我们再用dbscan包自带的数据集moons做一下测试。

先准备数据,加载moons数据集,了解数据基本情况,画出散点图。

# 加载dbscan自带数据集
> data("moons")
> head(moons)
            X          Y
1 -0.41520756  1.0357347
2  0.05878098  0.3043343
3  1.10937860 -0.5097378
4  1.54094828 -0.4275496
5  0.92909498 -0.5323878
6 -0.86932470  0.5471548

# 画出散点图
> plot(moons, pch=20)

用hdbscan()函数,实现层次dbscan算法。


> cl <- hdbscan(moons, minPts = 5)
> cl
HDBSCAN clustering for 100 objects.
Parameters: minPts = 5
The clustering contains 3 cluster(s) and 0 noise points.

 1  2  3 
25 25 50 

Available fields: cluster, minPts, cluster_scores, membership_prob, outlier_scores, hc

一共100条数据,被分成了3类,没有噪声。把聚类的结果画图展示。


# 画图
> plot(moons, col=cl$cluster+1, pch=20)

打印层次结构


> cl$hc
Call:
hdbscan(x = moons, minPts = 5)

Cluster method   : robust single 
Distance         : mutual reachability 
Number of objects: 100 

画出层次的合并过程图

> plot(cl$hc, main="HDBSCAN* Hierarchy")

从图可以清楚的看出,主要的3类的分支,区分度比较高。

如果我们想省略分层的细节,我们可以只画出主要分支,并标识类别。

plot(cl, gradient = c("purple", "blue", "green", "yellow"), show_flat = T)

接下来,我们要对群集的稳定性做一些优化,cluster_scores属性可以查看集群的得分。

> cl$cluster_scores
        1         2         3 
110.70613  90.86559  45.62762 

通过membership_prob属性,画图表示个体的稳定性。

# 打印membership_prob
> head(cl$membership_prob)
[1] 0.4354753 0.2893287 0.4778663 0.4035933 0.4574012 0.4904582

# 计算群集的数量
> num<-length(cl$cluster_scores)

# 从彩虹色中取得对应数量的颜色
> rains<-rainbow(num)
> cols<-cl$cluster
> cols[which(cols==1)]<-rains[1]
> cols[which(cols==2)]<-rains[2]
> cols[which(cols==3)]<-rains[3]

# 设置透明度,表示个体的稳定性
> plot(moons, col=alpha(cols,cl$membership_prob), pch=19)

最后,我们可以在图中,在标记出异常值得分最高的前6个点。

# 对异常值进行排序,取得分最高的
> top_outliers <- order(cl$outlier_scores, decreasing = TRUE) %>% head
> plot(moons, col=alpha(cols,cl$outlier_scores), pch=19)
> text(moons[top_outliers, ], labels = top_outliers, pos=3)

从图中看到,异常得分高的点(outlier_scores)与个体的稳定性(membership_prob),并不是同一类点。异常值通常被认为是,偏离其假定的基础分布的离群点。

通过上面3个函数的使用案例,我们了解了如何用dbscan包实现基于密度的聚类方法。真实世界的数据是复杂的,我们用来分析数据的工具也是多样的,多掌握一种工具、多一些知识积累,让我们迎接真实世界数据的挑战吧。

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

打赏作者

2018中国R大会上海 : R语言商业实践 -从金融市场到区块链

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

关于作者

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

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

前言

本次R语言(上每)大会由上海华东师范大学与统计之都合办,主题围绕着“数据科学”的展开,9个会场,涉及51个分享主题。报名1400多人,实际到场有接近1000人。

本次大会,结合了学术界、产业界、台湾地区,跨领域跨专业的交流,通过碰撞形成了新的火花。我在会议中,发现到了很多还没有毕业的学生,做了不错的创新的尝试,确实是一场不错的盛会。特别值得称赞的是:没有广告,回归内容本质,这才是高质量的大会。

目录

  1. 我分享的主题:R语言商业实践-从金融市场到区块链
  2. 会议体验和照片分享

1. 我分享的主题:R语言商业实践-从金融市场到区块链

本次大会我被安排在主会场第一场,之前本来想贴底气地讲一些R代码,看到出场的顺序果断调整内容和思路。以“认知”为切入点做为开场,希望能让已工作的人和在校的学生,获得思想上的共鸣。我的分享的PPT下载,本次活动的官方报名链接

第一天能容纳千人的主会场,在华东师范大学的闵行校区开幕。

我分享主题:R语言商业实践 -从金融市场到区块链

从“认知”上讲述,我们为什么要用R语言,R语言适合的领域,复合型人才的知识结构,如何创造场景,如何发现价值,以有序金融市场和混乱的区块链市场,做为2个场景进行分析,介绍如何发现规律,实现价值。

我主要为分三个部分进行介绍:

  • 思维模式:跨界,是需要综合素质的长期积累。
  • 金融市场:市场在变化,要跟上市场的变化
  • 区块链:链上数据,让交易无所遁形

由于时间有限,同时又了思路上的介绍,还请有问题的朋友,给我留言再进行沟通。后面如果有时间,我也争取把这种思维模式形成文章。

2. 会议体验和照片分享

本次大会我体会到的一些关键字:没有广告,创新和新想法,新朋友和老朋友,年轻的同学,第一场雪。

2.1 会议体验证和总结

会后和嘉宾聊天,完全没有想到,“数据科学”的理念已非常快的速度被大学被认同,已开设专业,做为重要的教学方向。同时,也遇到了一些困境,没有适合的教材,没有落地的场景。

把教学到实际业务结合,确实一直都是学术界与工业界的鸿沟,单独领域都有非常多的人才,但是能够打通这2个端的人才,是非常稀缺的,是需要复合型知识体系的人来打通的。

我的分享。

能容纳1000人的会场。

2.2 相关照片

分享嘉宾大合照:仅包括了第一天到场的嘉宾。

部分工作人员大合照:仅包括了第一天到位的工作人员。

微软MVP合照,中间2个女生是台湾的MVP,很有意思的在这里碰上了。

老朋友(从左向右):叶鹏,张丹,李舰,谢佳标,张杰

我和黄小伟

我和袁欣

新朋友,老朋友,跨界的朋友,台湾的朋友,用过R语言让我们有共同的话题,感谢华东师范大学和统计之都,所有主办方的小伙们,辛苦了!明年再见。

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

打赏作者

2018南京信息工程大学:R语言与计量经济学

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

关于作者

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

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

前言

学生面临毕业的竞争,如何能脱颖而了,不仅需要有良好的知识储备,更要具有动手能力,同时了解市场的需求是什么。很多同学,在学校读书学习,最后都变成了,“死读书,读死书”,完成不知道社会是什么样的,只是把书本上和老师教的内容掌握,这是完全不行的!!!

当老师充分的认识到,学生需要更多的知识来源时,就会选择与行业专家来合作,从而打开学生的视野。那么,本次的教学就是这样的一个目的,南京信息工程大学经济管理学院的鲁老师找到我,希望我给他的学生带来一次,R语言与计量经济的培训,让学生不仅学到知识,更多看看外面的世界是什么样子的。

目录

  1. 我的培训主题:基于R语言的数据挖掘与计量经济学
  2. 会议体验和照片分享

1. 我的培训主题:基于R语言的数据挖掘与计量经济学

50人的小班课程,定位就是把R语言和计量经济学的知识结合起来,让学生们提高动手能力,掌握一门技能,提高毕业时求职的竞争力。本次培训的活动主页

课程大纲:2018年全国高校计量经济学及R语言应用师资培训大纲

本期培训内容以“计量经济学及应用”考核大纲为基础,重点讲解R语言编程、金融数据计算、数据分析与可视化等内容,并对2018年度计量经济学及应用试题进行实操演练。

经过2天的密集的授课,让同学们从3个维度获得了提升:

  • IT思维:熟悉的R语言编程
  • 统计思维:把计量经济学的模型通过R语言落地
  • 金融市场思维:了解金融市场,把书里上的知识与市场进行了对接。

2. 会议体验和照片分享

我的介绍和照片分享。

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

2.2 会议体验证和相关照片

本次的场地南京信息工程大学经济管理学院,由学院的鲁老师负责制定整体的教学计划。整体来说,课程安排的很紧很充实,也很累。嗓子疼!!又赶上了南京的大雾霾天,和北京真是有的一比了。

大合照

我在讲课

上课啦

动手实践,讨论问题

教师里问问题的学生

学校正门

体育场

图书馆

据说全国排名1-2的气象学院

野鸭湖

最后,课程获得了,同学们和老师的好评!希望同学们能消化吸收,未来的世界是属于你们的。

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

打赏作者

矩阵数字经济智库专访: 顶层设计决定行业基础

架构师的信仰系列文章,主要介绍我对系统架构的理解,从我的视角描述各种软件应用系统的架构设计思想和实现思路。

从程序员开始,到架构师一路走来,经历过太多的系统和应用。做过手机游戏,写过编程工具;做过大型Web应用系统,写过公司内部CRM;做过SOA的系统集成,写过基于Hadoop的大数据工具;做过外包,做过电商,做过团购,做过支付,做过SNS,也做过移动SNS。以前只用Java,然后学了PHP,现在用R和Javascript。最后跳出IT圈,进入金融圈,研发量化交易软件。

架构设计就是定义一套完整的程序规范,坚持架构师的信仰,做自己想做的东西。

关于作者:

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

转载请注明出处:
http://blog.fens.me/architect-matrix-interview

前言

受矩阵数字经济智库邀请,做一起对于行业发展的专访。专访的过程,涉及了大数据,区块链,宏观经济,个人转型等多个领域,我也是根据个人的理解,对上述的一些问题做了总结。

2018年,我经历了很多,大病初愈,去了微软总部参观,从从银行的舒适区出来,经历区块链快速下跌的市场,关注金融改革,了解中美贸易的影响,看到国内经济的从乱序到稳定。

总结一句话:2018市场的变化真是太快了,各行各业都缺少顶层设计者。

目录

  1. 专访背景
  2. 如何从技术转型
  3. 量化投资,更需要规范的市场环境
  4. 顶层设计,是行业发展先行条件

1. 专访背景

十年前,银行核心系统的升级改造促进了大数据的积累;十年后,数字化转型的需求使得大数据在各个行业广泛应用。经过十年的数据积累和科技分析能力的提升,金融大数据的分析和应用已经进入到了一个新的层次,金融改变人们的生活,生活也会改变着金融,而大数据已经成为改变人们的生活和金融行为的重要手段和方式,大数据的应用让金融和人们的生活更加了解、互相改进和互相适应。

应矩阵数字经济智库之约,我们邀请到青萌数海CTO张丹,国内顶尖的R语言专家,金融大数据专家,曾在民生银行等金融机构工作,积累了丰富业务经验和对金融数据深刻理解,共同探讨国内大数据的未来发展。官方文章发布地址

2. 如何从技术转型

从最初的编程技术入手,作为国内顶尖的R语言专家,张丹无论在技术水平还是作品产出都居于一线水准。之后进入金融领域做量化投资,而目前主要做数据科学相关的行业研究,发现数据规律。

一路跨界,从IT技术到量化投资再到数据科学,张丹认为当一个人在一个领域取得了很深入的理解,包括技术能力、思维模式、业务思路、整个产业的上下游企业关系等,将知识理解形成系统的方法论,作为基础再进入一个新的领域,也会很快成为新领域的专家。

作为技术出身的张丹,对待新事物的认知往往采取理性的态度。对于目前热议的区块链金融,他认为金融是指银行、证券、信托、保险、基金等金融领域,而区块链金融仅仅是利用币的交易属性进行流通。因此,区块链金融应该是金融业务对区块链的金融支持,而不是颠覆传统金融,单独以区块链为基础的金融。只有当投资银行、商业银行、信托等金额机构,对整个区块链的账户体系,资金流转,信用体系等,提供各种各样的金融服务支撑之后,才能开展基于区块链的金融类型服务。

在谈及自己深入研究的大数据领域时,张丹认为大数据是基于技术领域衍生出来的一个概念,同时也是社会所需要的技术。大数据带来了一次生产力的变革,大数据会成为一个长期的机会。在未来,数据会成为每个人所必须的知识。

当我们以大数据的视角去看待日常的生活时,会为我们带来很多的改变。将大数据结合人工智能、物联网等技术,在多方面可以提高人的工作效率。人工智能领域突破,如AlphaGo,会打破了人类固有的认知,进而形成的新的思维方式,是人类应该学习的。

张丹曾在金融行业设计和开发智能投顾系统,他认为的智能投顾是利用已有的金融市场交易规则和评判标准,帮助外行人做投资决策。而之所以可以这样做,是因为投资方法是建立在西方的现代金融学理论之上的,有固定的规则、评价方法、运作模式且已经得到市场的认可,基于这个市场基础,可以利用算法进行建模,提升收益。但国内推出智能投顾问服务,更多是站在卖方市场,缺少对买方的利益的保障。

3. 量化投资,更需要规范的市场环境

张丹所认为的量化投资是对传统投资的提升,并不能代替传统投资的模式。量化投资应与传统投资相辅相成,量化本身不能量化一切东西,还需要人的思考,用量化的工具进行辅助决策,会极大地提升工作效率。

张丹认为近两年中国市场的管制逐渐加强,使得很多可以通过量化、程序化的交易通道被堵塞,导致量化投资受到政策上的影响和限制,但并不影响量化的决策继续进行。对于数字货币交易市场,还处于鱼龙混杂的时期,区块链生态都面临着洗牌,量化投资可以帮助币市恢复理性。让纯投机的人离场,通过更多的数据指标支撑,重新建立数据货币的秩序。

4. 顶层设计,是行业发展先行条件

当谈及金融大数据的未来时,张丹乐观的认为,金融数据会不断延伸到各行各业,及至个人的生活交易。金融大数据也会衍生出各种的数据,在数据量和数据维度方面不断的进行拓展。金融数据的未来会成为一个机会,在如何把握这样的机会上,张丹认为我们应明确区分金融属性的数据和金融业的数据,在此基础上抓住未来的发展机会。

而对于未来区块链行业发展的方向上,他提出,行业内最需要精英进行顶层设计,技术资源和资本是相对丰富的,但真正能调配这些资源的顶层设计者是难求的。

他通过研究公链上数据的交易行为,来评价公链项目的优劣。每条公链都有自己的使命和独特的性质。公链上数据所呈现的行为,应该是反映这个项目的价值观。通过数据分析验证公链项目的言行一致,是判断公链是否是空气项目的重要标准。

行业的发展瞬息万变,但一个行业的发展离不开站在顶端看世界的人,高瞻远瞩的布局会奠定行业的趋势。未来的大数据和区块链等行业会如何发展,让我们拭目以待。

转载请注明出处:
http://blog.fens.me/architect-matrix-interview

打赏作者