罗兰在MATLAB的艺术

把想法变成MATLAB

请注意

罗兰在MATLAB的艺术已经存档,不会被更新。

PCT和mdc内存大数据分析

艾特威尔肯的MATLAB产品管理组是客人对使用博客分布式数组在内存中执行数据分析“大数据”。

大数据应用程序可以有很多种形式。与非结构化文本处理,在许多企业和消费者应用程序,在科学和工程领域的大数据通常可以采取更加“正常”形式,冗长的数据集的观察或时间序列数据,或单片、多维矩阵获取一些问题空间。

64位MATLAB根本上是适合处理这些类型的数据,只要你的电脑的内存中的数据符合。当数据规模已经长大到一台计算机的能力,MATLAB分布式计算服务器(mdc)允许MATLAB应用程序简单地规模和可以利用的总内存和计算能力的计算机。

这篇文章探讨了使用mdc分析一组表格数据不符合典型的桌面计算机的记忆。亮点包括:

  • 导入一个大数据集来自多个文件并行文件I / O,和后期处理数据集
  • 整个聚合数据集进行并行计算
  • 可视化的统计特征聚合数据集
  • 用MATLAB mat文件优化文件I / O性能
  • 和员工之间的工作负载平衡数据

您将需要并行计算工具箱(PCT)来访问分布式数组,一个数据类型与数据存储在一个集群。它的使用几乎相同的一个正常的MATLAB矩阵,支持简单和快速应用。金宝app分布数组的内存中自然实验和便利的快速迭代工作流,MATLAB用户所期望的。

最后,请注意,这个例子的设计运行在大约20 GB的内存。这很难说是“大数据”,但问题大小被故意减少足够小,适合高端工作站的中期,你应该没有访问集群。

内容

加载数据集

这个示例使用公开数据的一组超过1亿航班记录在20年时间跨度从1987年到2008年。年单独下载:

  1. https://s3.amazonaws.com/h2o-airlines-unpacked/year1987.csv
  2. https://s3.amazonaws.com/h2o-airlines-unpacked/year1988.csv
  3. https://s3.amazonaws.com/h2o-airlines-unpacked/year1989.csv
  4. https://s3.amazonaws.com/h2o-airlines-unpacked/year1990.csv
  5. https://s3.amazonaws.com/h2o-airlines-unpacked/year1991.csv
  6. https://s3.amazonaws.com/h2o-airlines-unpacked/year1992.csv
  7. https://s3.amazonaws.com/h2o-airlines-unpacked/year1993.csv
  8. https://s3.amazonaws.com/h2o-airlines-unpacked/year1994.csv
  9. https://s3.amazonaws.com/h2o-airlines-unpacked/year1995.csv
  10. https://s3.amazonaws.com/h2o-airlines-unpacked/year1996.csv
  11. https://s3.amazonaws.com/h2o-airlines-unpacked/year1997.csv
  12. https://s3.amazonaws.com/h2o-airlines-unpacked/year1998.csv
  13. https://s3.amazonaws.com/h2o-airlines-unpacked/year1999.csv
  14. https://s3.amazonaws.com/h2o-airlines-unpacked/year2000.csv
  15. https://s3.amazonaws.com/h2o-airlines-unpacked/year2001.csv
  16. https://s3.amazonaws.com/h2o-airlines-unpacked/year2002.csv
  17. https://s3.amazonaws.com/h2o-airlines-unpacked/year2003.csv
  18. https://s3.amazonaws.com/h2o-airlines-unpacked/year2004.csv
  19. https://s3.amazonaws.com/h2o-airlines-unpacked/year2005.csv
  20. https://s3.amazonaws.com/h2o-airlines-unpacked/year2006.csv
  21. https://s3.amazonaws.com/h2o-airlines-unpacked/year2007.csv
  22. https://s3.amazonaws.com/h2o-airlines-unpacked/year2008.csv

在许多大数据是典型的应用程序、数据分布在大中型文件的集合,而不是一个非常大的文件。这实际上是有利,使数据更容易分布在集群MDCS运行。在这个发展阶段中,使用温和的池(8工人),只有第一个八个文件数据集——完整的数据集将会在这篇文章。

识别文件处理

一旦文件被下载,在MATLAB寻找他们。修改的值dataFolder无论你下载你的文件。

关闭所有清晰的所有dataFolder =/卷/ HD2 /航空/数据的;allFiles = dir (fullfile (dataFolder‘* . csv‘));%删除“点”文件(Mac)allFiles = allFiles (~ strncmp ({allFiles (:) . name},“。”1));文件= allFiles (1:8);%初始发展

检查数据

数据集是逗号分隔的文本。为了简单起见在这个特定的示例中,只在几列的数据集。进口从文本是一项昂贵的操作,减少了进口只需要列可以大大加快MATLAB应用程序。第一个看左边的部分原始数据:

如果~ ispc系统([“-20头”fullfile (dataFolder文件(8). name)“|削减-60 - c”]);结束
DepTime,年、月、DayofMonth DayOfWeek CRSDepTime, ArrTime, 1994 C, 1, 7日,5858900954年,1003年,227年,NA, 56岁,63年,NA, 9日,2,解释水平理论,1994年开放,1,8日,6859900952年,1003年,美国,227年,NA, 53岁,63年,NA, 1,解释水平理论,-11年或1994年,1,10日,1935900年,1023年,1003年,227年,NA, 48岁,63年,NA, 20岁,35岁,解释水平理论,O 1994 1, 11日,2903900年,1131年,1003年,227年,NA, 148年,63年,NA, 88年,3,解释水平理论,O 1994 1, 12日,3933900年,1024年,1003年,227年,NA, 51岁,63年,NA, 21岁,33岁的解释水平理论,1994啊,1、13、4,NA, NA, 1003年,900年,227年,NA, NA, 63年,NA, NA, NA,解释水平理论,ORF, 1994年,1,14日,5903900年,1005年,1003年,227年,NA, 62年,63年,NA, 2, 3,解释水平理论,1994年开放,1,15日,6859900年,1004年,1003年,227年,NA, 65年,63年,NA, 1, 1,解释水平理论,或1994年,1,17日,1859900955年,1003年,227年,NA, 56岁,63年,NA, 8日,1,解释水平理论,或1994年,1,18岁,2904900959年,1003年,227年,NA, 55岁,63年,NA, 4, 4,解释水平理论,1994年开放,1,19日,3858900947年,1003年,227年,NA, 49岁,63年,NA, -16, 2,解释水平理论,O 1994 1, 20日,4923900年,1015年,1003年,美国,227年,NA, 52岁,63年,NA, 12日,23日,解释水平理论,O 1994 1, 21日,5日,NA, NA, 1003年,900年,227年,NA, NA, 63年,NA, NA, NA,解释水平理论,ORF, 1994年,1,22岁,6859900年,1001年,1003年,227年,NA, 62年,63年,NA, 2, 1,解释水平理论,O 1994 1, 24岁,1901900年,1006年,1003年,227年,NA, 65年,63年,NA, 3, 1,解释水平理论,1994年开放,1,25岁,2859900952年,1003年,227年,NA, 53岁,63年,NA, -11年,1,解释水平理论,O 1994 1, 27日,4910900年,1008年,1003年,227年,NA, 58岁的63年,NA, 5, 10,解释水平理论,或1994年,1,28岁,5858900年,1020年,1003年,227年,NA, 82年,63年,NA, 17日,2,解释水平理论,O 1994 1, 29岁,6859900953年,1003年,227年,NA, 54岁,63年,NA, -10年,1,解释水平理论,O

加载一个文件

使用textscan函数导入数据,因为它提供了所需的灵活性从文件导入特定的列混合的文本数据;它也可以应对“NA”作为缺失值的指标。提取列1、2、4和5 (一年,,DayOfWeek,DepTime)从一个文件在本地机器上。

抽搐srcFile = fullfile (dataFolder、文件(8). name);f = fopen (srcFile);C = textscan (f,' % f % % * % f % f % * ^ \ [n]”,“分隔符”,”、“,“HeaderLines”,1“TreatAsEmpty”,“NA”);文件关闭(f);(年、月、DayOfWeek DepTime] = C {:};sprintf (' % g秒加载“% s”。\ n”、toc、srcFile)
ans = 52.4414秒加载" /卷/ HD2 /航空/数据/ 1994. csv”。

打开一个本地工人

前一步骤可能花了一点时间来导入,也许一分钟。幸运的是,这个操作以后再并行运行。如果有必要,打开一个8-worker池:

试一试parpool (“本地”8);结束
开始平行池(parpool)使用“本地”概要文件…连接到8工人。

加载一个文件所有工人

移动textscan代码到集群,集群中的所有节点加载该文件。这是完成了一个单个项目/多个数据(SPMD)块。一个spmdMATLAB代码块并行执行的所有八个工人:

抽搐spmdsrcFile = fullfile (dataFolder、文件(8). name);f = fopen (srcFile);C = textscan (f,' % f % % * % f % f % * ^ \ [n]”,“分隔符”,”、“,“HeaderLines”,1“TreatAsEmpty”,“NA”);(年、月、DayOfWeek DepTime] = C {:};文件关闭(f);结束sprintf (' % g秒加载所有工人“% s”。\ n”toc, srcFile {1})
ans = 65.2914秒加载" /卷/ HD2 /航空/数据/ 1994。对所有工人csv”。

加载不同的文件在每个工人

这前一步大约需要的时间是一样长的前负荷,接近线性加速。但是,观察到相同的文件被加载的8倍。允许不同的行为在不同的工人,每个工人都指定了一个惟一的索引,叫做labindex。使用labindex在一个让每个工人的行为不同spmd块。在这种情况下,只需更换硬编码的索引文件(8)文件(labindex),spmd块加载不同的文件在不同的工人(取消文件是一个矢量数据集的所有文件名)——这个吗spmd块,否则与前一个相同。

抽搐spmdsrcFile = fullfile (dataFolder文件(labindex) . name);f = fopen (srcFile);C = textscan (f,' % f % % * % f % f % * ^ \ [n]”,“分隔符”,”、“,“HeaderLines”,1“TreatAsEmpty”,“NA”);(年、月、DayOfWeek DepTime] = C {:};文件关闭(f);结束sprintf (' % g秒加载不同的文件在每个工人。\ n”toc)
ans = 61.4875秒加载不同的文件在每个工人。

执行非合作计算每个工人

现在每个工人都有自己的一组数据。在某些应用程序中,这可能是足够的,每个数据集都可以独立于彼此。这有时被称为一个“高度平行”的问题。在这个数据集的情况下,每个文件是一整年的数据,所以计算是简单的计算。的价值一年在每个工人应该是相同的。确认这一spmd块,然后把计算结果在本地考试。请注意电池的使用array-style索引后立即spmd块;这是意味着一个变量检索所有值在每个工人。因为有八个工人,八个值——这是称为返回复合在MATLAB。

spmdallYearsSame =所有(年= =一年(1));myYear = (1);结束[allYearsSame {:}] [myYear {}):
ans = 1 1 1 1 1 1 1 1 ans =列列1到6 1987 1988 1989 1990 1991 1992 7到8 1993 1994

可视化起飞时间

创建一个直方图出发小时八年来第一次真正看数据。注意,一年(1987年)级大大低于其它年份,这是因为它只有部分的有价值的数据。course-grain分区使用文件和文件夹层次结构的数据可以是一个直接的方法把你的数据集进行细分成有意义的和可控的子集。

spmdH =嘘(DepTime、24);结束情节(cell2mat (H (:)) ',“o”)标题(出发时间在今年的直方图)包含(一天的小时)ylabel (航班的数量)传说(arrayfun (@ (x) sprintf (' % d ',x) [myYear {}):,“UniformOutput”假),“位置”,“西北”)

执行合作计算每个工人

但假设分析必须执行所有观测数据集。为此,分布式可以使用数组。一个分布式数组允许MATLAB处理数组遍布许多工人似是一个“正常”的MATLAB数组。分布式数组是由大量的MATL金宝appAB函数,包括线性代数。

创建一个分布式数组的数据已经在内存中,首先确定数组的每个工人的文章有多大,和它的总大小。计算个人和总长度,然后创建四个分布式每一列的数组,一个原始数据集,使用所谓的codistributor(称为co-distributor从的角度来看,因为这是每个工人;每个需要与其他工人合作)。

抽搐spmd长度=大小(,1);结束长度= cell2mat(长度(:));长度=长度';totalLength =总和(长度);spmdcodistr = codistributor1d(1,长度,[totalLength 1]);年= codistributed。构建(一年,codistr);月= codistributed。构建(月、codistr);DayOfWeek = codistributed。构建(DayOfWeek codistr);DepTime = codistributed。构建(DepTime codistr);结束sprintf (' % g秒从复合材料创建分布式阵列。\ n”toc)
ans = 1.86178秒,从复合材料创建分布式阵列。

可视化在整个数据集

现在有四个变量(一年,,DayOfWeek,DepTime)包含整个8年的数据集;这些变量可以使用MATLAB变量一样正常。这个例子使用一维数组,但多维分布式数组也支持你应该需要跨集群的数据金宝app分发“瓷砖”。如果你想要收集的分布式数组为一个正常的MATLAB数组,你可以这样做收集函数。在这样做时要小心,确保你的本地计算机有足够的内存来保存整个的聚合内容分布式数组中。创建一个直方图出发:

大一=收集(min ());去年=收集(max ());图嘘(一年,大一:去年,“EdgeColor”,' w ')标题(年的直方图)包含(“年”)ylabel (航班的数量)

注意使用收集在这里。上的任何操作分布式产生另一个数组分布式数组中。尽管最小值马克斯返回小数组,不过他们必须收集ed回到你当地MATLAB在使用它们之前的第二个参数函数。你可以看到更多的赤裸裸的现在,1987年更少比随后几年的观察。

可视化起飞时间在整个数据集

下产生的直方图出发的时间。不需要收集任何因为第二个参数(24小时一天)是一个常量值,不需要计算的东西分布式数据。

图;嘘(DepTime, 24);标题(起飞时间的直方图)包含(一天的小时)ylabel (航班的数量)

使用24直方图箱

读者会注意到直方图箱2500运行,而不是25。这是由于原始数据集表示时间为整数编码HHMM。只考虑小时:

嘘(地板(DepTime / 100), 24)标题(起飞时间(小时)的柱状图)包含(一天的小时)ylabel (航班的数量)

把出发的时间

事实上,把HHMM数字0和24之间,与小数点后的价值表达1/60th每分钟。更新的值分布式然后再画出直方图数组DepTime改进的表示。

清晰的C;DepTime =地板(DepTime / 100) +国防部(DepTime 60) / 60;嘘(DepTime 24)标题(起飞时间(部分时间)的柱状图)包含(一天的小时)ylabel (航班的数量)

注意使用清晰的工作区中摆脱C早些时候,创建一个临时文件导入时的代码。MATLAB通常避免把一些不必要的数据的副本,并保持暂时没有材料,影响项目到目前为止。然而,由于的价值DepTime会改变,MATLAB将在一个位置需要保持similar-but-distinct数组的副本。这是要避免的原因很明显,所以在修改前清除这些老“快照”DepTime

删除丢失的数据点

到目前为止,数据还没有检查缺失数据的存在,不是一个数字代表(南)出发的时间。寻找nan,然后把那些坏的行从所有的分布式阵列。

抽搐goodRows = ~ isnan (DepTime);流(有% d行删除从数据。\ n”,totalLength-gather (sum (goodRows)));年=一年(goodRows);=月(goodRows);DayOfWeek = DayOfWeek (goodRows);DepTime = DepTime (goodRows);sprintf (' % g秒修剪坏行。\ n”toc)
删除的数据有419397行。ans修剪坏行= 23.9631秒。

使用完整的数据集

是时候处理所有的文件在数据集。因为数据文件是文本,这个应用程序将花费大部分运行时解析文本和转换成数字。一次性分析这可能是可以接受的,但如果你预见到需要加载数据集不止一次,可能是值得的努力保存数字表示法,以供将来使用。这是在一个简单的完成parfor循环,为每个文件创建一个MATLAB MAT-File原始数据集。这个循环需要几分钟第一次运行。然而,代码也足够聪明不重建MAT-File时已经存在,所以这个循环结束后重新运行时迅速。

注意:如果你有一个集群有超过八个核心提供给你,现在是一个很好的时间来关闭eight-worker池和打开一个大池。如果你没有获得一个集群,这也是好的,只要您的本地计算机有16 GB的RAM或更多。

清晰的所有dataFolder =/卷/ HD2 /航空/数据的;文件= dir (fullfile (dataFolder,‘* . csv‘));文件=文件(~ strncmp({文件(:). name},“。”1));%删除“点”文件(Mac)抽搐parfori = 1:元素个数(文件)%见//www.tatmou.com/supp金宝apport/solu金宝搏官方网站tions/en/data/1-D8103H为下面的技巧parSave = @(帧,年、月DayOfWeek DepTime)保存(帧,“年”,“月”,“DayOfWeek”,“DepTime”);srcFile = fullfile (dataFolder文件(我). name);(路径、名称、~)= fileparts (srcFile);cacheFile = fullfile(路径,[名字“.mat”]);如果isempty (dir (cacheFile)) f = fopen (srcFile);C = textscan (f,' % f % % * % f % f % * ^ \ [n]”,“分隔符”,”、“,“HeaderLines”,1“TreatAsEmpty”,“NA”);文件关闭(f);(年、月、DayOfWeek DepTime] = C {:};parSave (cacheFile,年、月DayOfWeek DepTime);结束结束sprintf (' % g秒导入文本文件保存到mat文件。\ n”toc)
ans = 220.984秒mat文件导入文本文件保存。

加载整个数据集

现在是时候加载整个数据集,而只是保存到mat文件。因为工人的数量可能不到文件的数量,每个工人将负责文件的集合。文件分配给工人使用他们labindex和模运算。每个工人读取它的所有文件vertcat的内容到一个数组中。导入数据时,这是一个方便的时间来执行处理前面介绍——过滤南行,转换的HHMM表示起飞时间,并注意每个工人的长度的数据集。接下来,创建分布式数组。虽然这段代码是最长的这篇文章中,它在很大程度上是一个复制粘贴代码已经讨论过。

抽搐spmdmyIndicies = labindex: numlabs:元素个数(文件);年=细胞(大小(myIndicies));月=细胞(大小(myIndicies));DayOfWeek =细胞(大小(myIndicies));DepTime =细胞(大小(myIndicies));i = 1:元素个数(myIndicies) srcFile = fullfile (dataFolder、文件(myIndicies(我)). name);(路径、名称、~)= fileparts (srcFile);cacheFile = fullfile(路径,[名字“.mat”]);人体=负载(cacheFile);{我}= tmpT.Year;月{我}= tmpT.Month;DayOfWeek{我}= tmpT.DayOfWeek;DepTime{我}= tmpT.DepTime;结束结束清晰的人体%以上,避免深拷贝spmd{:}= vertcat(年);每月月= vertcat ({});DayOfWeek = vertcat (DayOfWeek {:});DepTime = vertcat (DepTime {:});goodRows = ~ isnan (DepTime);年=一年(goodRows);=月(goodRows);DayOfWeek = DayOfWeek (goodRows);DepTime = DepTime (goodRows);DepTime =地板(DepTime / 100) +国防部(DepTime 60) / 60; lengths = size(Year,1);结束长度= cell2mat(长度(:));长度=长度';totalLength =总和(长度);spmdcodistr = codistributor1d(1,长度,[totalLength 1]);年= codistributed。构建(一年,codistr);月= codistributed。构建(月、codistr);DayOfWeek = codistributed。构建(DayOfWeek codistr);DepTime = codistributed。构建(DepTime codistr);结束sprintf (' % g秒从mat文件导入并创建分布式阵列。\ n”toc)
ans = 12.121秒,导入从mat文件和创建分布式阵列。

重新运行可视化

现在,您可以执行一些可视化的整个数据集。DayOfWeek这次是可视化。

图嘘(DayOfWeek 1:7)标题(星期的直方图)包含(“星期”)ylabel (航班的数量甘氨胆酸)组(,“XTickLabel”,{“我的”,“面前”,“结婚”,“碰头”,“星期五”,“坐”,“太阳”});

平衡数据池的工人

负载平衡的最后一个话题是讨论。的分布式数组在文件级别分区,每个工人零个或多个文件。这可能是如果你输入文件大致相同的大小和工人的数量小于文件的数量。然而,文件大小不均可能创建一个不平衡的工作,或者,更糟糕的是,更多的工人比文件将导致完全闲置劳动力!如果您正在运行超过22个工人,你会看到这种效果在处理这个数据集。

因此它可以帮助平衡的分布分布式数组中。这将需要一些工人之间的数据传输,但它可能是一个有价值的投资,加快后续计算。计算“理想”(平衡)分布,创建一个新的codistributor与理想分布,然后重新分配使用这个理想。

抽搐spmdbeforeSizes =大小(getLocalPart(年),1);结束newBreaks =圆(linspace (0 totalLength元素个数(长度)+ 1));newLengths = newBreaks(2:结束)-newBreaks (1: end-1);spmdnewCodistr = codistributor1d (1 newLengths [totalLength 1]);年=重新分配(一年,newCodistr);月=重新分配(月,newCodistr);DayOfWeek =重新分配(DayOfWeek newCodistr);DepTime =重新分配(DepTime newCodistr);结束spmdafterSizes =大小(getLocalPart(年),1);结束sprintf (' % g秒重新分配数组。\ n”toc)图酒吧([[beforeSizes {}):”, [afterSizes{}): '])标题(每个工人的数据(前后))包含(工人数量的)ylabel (的数据量的)({传奇“之前”,“后”},“位置”,“西北”)
ans = 14.1069秒重新分配的数组。

在关闭

希望这篇论文和代码给你一种意义上的交互式工作流与大数据可能在使用一个分布式阵列。并行文件I / O、分布式合作操作,可视化,介绍了负载平衡和探索。虽然这里使用的例子很简单,但这些基本原则扩展到其它数据集同样分布在文件的集合。

值得注意的是,这篇文章只触及表面的实际数字功能的分布式阵列——高阶操作,比如单一分解(计算)和其他线性代数函数、fft算法等也可用。关于分布式阵列的进一步阅读,试试以下:

你如何管理你的大数据分析?让我们知道在这里




发表与MATLAB®R2013b


  • 打印

评论

要发表评论,请点击此处登录到您的MathWorks帐户或创建一个新帐户。