分布式机器学习:如何快速从Python栈过渡到Scala栈

首先介绍下我的情况和需求,如果你跟我类似,那么这篇文章将很有帮助;

我之前的技术栈主要是JavaPython,机器学习方面主要用到是pandasnumpysklearnscipymatplotlib等等,因为工作需要使用spark,所以理所应当的开始学习pyspark

之后一方面团队其他成员基本都是用scala,同时在Spark API更新上,pyspark也要慢于scala的,而且对于集群维护的同事来说,也不想再维护一套python环境,基于此,开始将技术栈转到scala+spark

如果你的情况也大致如上,那么这篇文章可以作为一个很实用的参考,快速的将一个之前用pyspark完成的项目转移到scala上;

正文开始。。。。

项目介绍

基于300w用户的上亿出行数据的聚类分析项目,最早使用Python栈完成,主要是pandas+sklearn+seaborn等库的使用,后需要使用spark集群,因此转移到pyspark;

现在的需求是功能等不动的前提下转移到Scala下实现,也就是通过Scala+SparkAPI实现整个机器学习流程以及结果解释分析;

根据需求分解任务如下:

学习scala基本语法、数据结构、IO等;

搭建Idea+scala+spark的本地开发环境;

以上述两点为基础移植前Python项目;

Scala基础学习

Scala是一门多范式语言,函数式编程语言,这一点主要体现在于针对问题的处理方式上于面向对象的语言略有不同,函数式+惰性求值+多线程支持等方面的优势使得它被Spark选择为开发语言;

上述是一些概念性的东西,属于熟悉了Scala之后需要去多多了解的,不过对于工作中现学的同学来说更重要的是如何快速上手,那就从最最紧迫的部分开始吧;

一般来说一门语言最快掌握的方法是与其他语言对比进行学习,因此下面每一部分都与java、python两门最多人用的语言做对比者进行,指出一些明显差异的点和类似的点;

参考链接:https://www.cnblogs.com/qingyunzong/p/8858234.html

Hello World

Scala语言是运行于JVM的,没错,就是java虚拟机,因此它的编译、运行过程与java非常类似,或者说我们就认为是一样也是可以的,java通过javac编译得到字节码文件,通过java运行,Scala则是通过scalac编译,通过scala运行,而且由于二者底层是一致的,因此Scala中可以直接导入java的库来使用,这有助于利用java中很多久经考验的第三方库;

开发工具选择Idea,Idea支持Scala插件,下载后可以直接新建Scala项目,还是很方便的,Idea搭建Scala环境参考链接:https://www.cnblogs.com/skyell/p/9939535.html

Hello World:

object Demo { def hello(): Unit = { println("Hello Scala!!!") } def main(args: Array[String]): Unit = { hello() } }

对比Java、Python等,看看它的特点:

首先整体代码组成结构上与java一致,需要一个类为运行主体,main函数为入口;

在方法定义上使用def关键字,同时是先指定入参,再指定出参,注意Unit表示函数没有返回值;

每行代码末尾的;可有可无,这与Python一致;

语言基础

语言基础主要由基本数据类型IF-ELSE循环函数组成,这也是每个语言的基础,基本上这部分统一了大部分代码都能看懂;

基本数据类型 val byte:Byte = 127 // -128 ~ 127 val short:Short = 32767 // -32768 ~ 32767 val int:Int = 123456 val long:Long = 1234567890 val float:Float = 123.45f val double:Double = 123.45d val char:Char = 'a' val string:String = "abc" val bool:Boolean = true val unit:Unit = () // unit一般用于函数不返回值时,也就是java的void val nil:Null = null // 空值 // Nothing是所有其他类的子类 Any是所有其他类的超类 AnyRef是所有引用类的基类 var name = "helong" name = "nemo" // var才能赋值,val赋值会报错,可以不指定类型,会自动推断 println(byte,short,int,long,float,double,char,string,bool,unit,nil,name)

数据类型上看Scala的特点有:

与java类似支持的数据类型比较多,比如单、双精度浮点型都支持,不像Python只有双精度;

区分Char和String,意味着单引号、双引号不能随便混用;

Unit类型用于函数没有返回值时;

Null表示空值;

val定义的变量为常量,其值不能改变,而var定义的则是变量,值可以随便改,这里主要关注类型为集合时,可变与不可变如何理解,这点放到后面集合时再细说;

IF-ELSE val x = 1 println(if(x>0) x else 0) // 条件表达式类似三元运算符 println(if(x>1) x) // 缺省else就等价于else () println(if(x>1) x else if(x==1) "x:1" else ()) // 支持if、else if、else // 块表达式类似把条件表达式拉直 // 注意到当我们不指定类型时,就可以返回多种格式让编译器做运行时处理 val y = { if(x==0) "x=0" else if(x==1) x else 0 } println(y)

条件判断语句上看差异:

独特的三目运算符格式:if(条件) 满足返回A else 不满足返回B;

Scala的三目运算符其实是条件表达式的一种特定格式;

条件表达式的各个条件下返回值类型可以不一致;

可以通过写成块状来提高可读性,外层用{}包住;

循环

while:

// while循环 var n = 10 while(n>0) { println(n) n-=1 }

while循环看起来没什么特别的,实际使用也确实比较少。。。。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzfsz.html