Category Archives: Data Science

ggplot2 Simple Tricks

Grid plots

library(gridExtra)
grid.arrange(p1,p2,p3,p4,p5,p6,ncol=2)

#Similar:
#Note: order is column-wise.
m=marrangeGrob(list(p1,p2,p3,p4,p5,p6),nrow=3,ncol=2)
ggsave("xx.pdf", m)

#Similar:
p=marrangeGrob(list(p1,p2,p3,p4,p5,p6),nrow=3,ncol=2,top=NULL)
#Set pointsize for high DPI png.
png("../result/random forest - regression - density.png",height=16.9, width=18,units="cm",res=600 , pointsize=10)
print(p)
dev.off()

Grouped density plot

library(ggplo2)
library(dply)

#mu is group statistics.
#"y" is target variable and "type" is group variable.
mu <- ddply(dfy, "type", summarise, grp.mean = mean(y))

#alpha = 0.4: set alpha for transparency.
#geom_vline(): plot vertical lines.
p <- ggplot(dfy, aes(x = y, color = type)) +
    geom_density(alpha = 0.4) +
    geom_vline(
      data = mu,
      aes(xintercept = grp.mean, color = type),
      linetype = "dashed") +
    ggtitle(title) +
    xlim(-1, 1) +
    ylab("Density") +
    xlab("x")

在Windows的bash下运行Linux命令行及图形界面程序

Windows 10在最新的年度更新中添加了bash功能,使得开发者可以在windows系统 中原生运行bash命令,不需要虚拟机,对于经常切换到Linux系统的开发者来说是一个大好消息。下面来进行配置:

首先在设置-更新-For Developer中打开开发者模式,此时电脑需要一段时间安装一些软件包。

2017-02-02_12-42-31

然后打开控制面板中的安装/删除程序-打开/关闭windows功能,在里面找到Linux子系统:

2017-02-02_12-43-03

启用时会安装一些东西并要求重启电脑。重启电脑后在搜索中输入bash.exe运行,会询问是否安装ubuntu,选择y开始安装,系统会下载一个完整的ubuntu镜像。

2017-02-02_14-22-39

之后 会设置用户名和密码。以上就完成了安装,但此时只能运行命令行程序,如果运行图形界面的unix程序则会报错,没有display,因此需要安装额外的软件,首先安装Xming,然后在bash中运行export DISPLAY=:0。

然后作为测试,安装gvim:sudo apt-get install gvim

安装完成以后运行gvim命令,就可以见到Ubuntu上的gvim了:

2017-02-02_15-39-33

另外ubuntu中安装软件常用的命令就是sudo apt-get install xx。

Mathematica绘制实时数据:Dynamic[]函数使用

在工业级应用中,我们时常会遇到对实时性有要求的计算,比如动态绘制股票的价格数据,这就要求对数据进行动态更新与计算。在Mathematica中能完成这一目的函数主要有两类,一类是Dynamic[]函数,一类是ScheduledTask[]系列函数。其中后者为后台任务,计算结果不会直接输出,作用主要与语句有关;而前者的结果可以实时地显示出来,其作用主要与变量有关。

考虑这样一个场景,我们首先给变量x赋值,然后指定其为Dynamic[x],这样我们就可以得到x的值的输出:

2016-10-28_19-54-16

 

其中的UpdataInterval->1指定变量更新的速度为每秒一次。现在我们在其它地方重新给x赋值为8,就会发现如上图所示的区域中,x的输出也变成了8:

2016-10-28_19-56-08

这就是Dynamic[]函数的作用即指定的间隔更新变量的输出值。现在假定x的赋值是以迭代的形式指定的,比如x=x+5,由于在Mathematica中万物皆表达式,因此我们也可以在Dynamic[]中直接使用迭代的赋值语句:

2016-10-28_20-01-07

此时我们会发现x的值不停地变化,其频率远超过了每秒一次,原因是在更新x的时候,x的值已经被改变了,所以它就会不停地迭代更新,无限循环。事实上虽然指定了每秒指定更新一次,但这一次“更新”从来没有完成,UpdateInterval->1已经失效了。而如果我们在SchduledTask[]中指定了x=x+5,那么这条赋值语句就会按一定间隔执行。

所以总的来说,Dynamic[]的作用是更新变量的值,而SchduledTask的作用是定期执行语句。

考虑如下场景,我们有一个数组存放了每秒的股票价格,在绘制图像时,我们往往不是全部绘制出来,而是绘制最近的一定数量数据,由于每秒都会有新数据生成,我们需要在加入新数据的同时,删除原有数据的头部。这就会涉及到变量的迭代赋值,如果我们直接在Dynamic[]中赋值,就会发现如上所示的变化过快的问题。此时一种解决办法是将变量的更新与绘制进行分离,在Dynamic[]中绘制变量图像,而另建立一个ScheduledTask[]来更新变量的值。代码如下:


lt = Accumulate[RandomReal[{-1, 1}, 150]] + 10;
Dynamic[Show[ListLinePlot[lt, PlotRange -> {{0, 155}, {0, 25}}],
Plot[lt[[-1]], {y, 0, 155}, PlotTheme -> "ThinLines"],
ParametricPlot[{150, u}, {u, 0, 25}, PlotTheme -> "ThinLines"]],
UpdateInterval -> 1]
RunScheduledTask[
lt = Drop[lt, 1]~Join~(lt[[-1]] + RandomReal[{-1, 1}, 1]), {1, 100}]

此语句中,Accumulate[]为累计和函数,初始时数据lt为150个随机数的累计和与10的和,Dynamic[]函数绘制数组lt及横、坚线,而RunScheduledTask[]中每秒执行一次lt的重新计算,即删除第一个值,且在末尾添加一个值。然后我们就可以看到Plot[]的实时更新了:

ezgif-com-video-to-gif

不同数据写入方式性能对比(含SQL数据库)

数据写入

测试时生成一百万个随机双精度数,然后写入文件。

1.OpenAppend[]

代码如下:

AbsoluteTiming[file = OpenAppend["data.csv"];
 For[i = 1, i &lt;= 1000000, i++,
  Write[file, RandomReal[]]];
 Close[file]]

用时:21.83s。

2.动态内存分配+Export[]

代码如下:

AbsoluteTiming[temp = {};
 For[i = 1, i &lt;= 1000000, i++,
  AppendTo[temp, RandomReal[]]];
 Export["data1.csv", temp]]

用时:???。程序运行了一个小时都没有结果,所以没有等它运行完成。花这么长时间运行是因为在动态内存分配下,需要大量时间用于分配内存的计算。

3.静态内存分配+Export[]

AbsoluteTiming[temp = ConstantArray[0, 1000000];
 For[i = 1, i &lt;= 1000000, i++,
  temp[[i]] = RandomReal[]];
 Export["data1.csv", temp]]

用时:21.1901s。

4.Map[]+Export[]

AbsoluteTiming[
 Export["data1.csv", RandomReal[] &amp; /@ Range[1, 1000000]]]

用时:19.7779s。

5.Map[]+OpenWrite[]

AbsoluteTiming[
 file1 = OpenWrite["data2.csv"];
 Write[file1, RandomReal[] &amp; /@ Range[1, 1000000]];
 Close[file1]]

用时:4.12419s。是的!你没有看错,这种写法仅用于了4.12s,性能是前面的5倍左右!

6.静态内存分配+OpenWrite[]

AbsoluteTiming[temp = ConstantArray[0, 1000000];
 file2 = OpenWrite["data3.csv"]; For[i = 1, i &lt;= 1000000, i++,
  temp[[i]] = RandomReal[]];
 Write[file2, temp];
 Close[file2]]

用时:5.68126s。

7.DumpSave[]

AbsoluteTiming[ss = RandomReal[] &amp; /@ Range[1, 1000000];
 DumpSave["datama.mx", ss]]

用时:0.0841409s。这个已经快得不像话了.比4.12秒性能提升了几百倍.

8.SQL数据库

AbsoluteTiming[
 s = SQLServerLaunch[{"myDb1" ->
     FileNameJoin[{$TemporaryDirectory, "HSQLServer"}]}];
 conn = OpenSQLConnection[JDBC["HSQL(Server)", "localhost/myDb1"]];
 SQLCreateTable[conn, SQLTable["test"],
  SQLColumn["col", "DataTypeName" -> "Double"]];
 For[i = 1, i <= 1000000, i++,
  SQLInsert[conn, "data", "col1", RandomReal[]]];
 SQLCommitTransaction[conn];
 CloseSQLConnection[conn];
 SQLServerShutdown[s]]

用时:7.28357s
从以上的对比中,可以看出,DumpSave[]加函数式编程是最快的一种写入数据的方式。仅需要0.08s就可以生成并写入100万个双精度随机数。其次的为Write[]、数据库方式。