KAfka Streaming - Spark ML 을 이용했는데 머신 러닝 자체가 개발량이 많지 않아 spark-shell 로 한줄 한줄 검증하고 실제 Spark App. 은 SBT로 개발했다.
※ spark는 spark shell을 통해 한줄 한줄 실행해보며 결과를 확인할 수 있는 REPL(Read-Evaluate-print Loop)환경을 제공하므로 손쉬운 개발과 테스트가 가능하다.
개발자라면 책은 아파치 스파크 입문이 개발에 맞춰서 쓰여있으므로 이해하기 쉽다.
머신러닝은 개발량 보다는 알아야 하는 통계 지식이 우선된다.
기초 통계학이 아니라 응용 통계학에 가깝다.
알고리즘 선택은 해당 알고리즘의 목적에 대해 공부하면 할 수 있다 쳐도 파라메터 설정을 어떻게 할 것이며 출력되는 결과를 어떻게 이해할 것인지. 모델에 대한 검증...등등
개발자는 절대 머신러닝을 혼자 할 수 없다.
머신러닝 개발량 이야기하다가 삼천포로 빠졌네..
이번 과제에서 쓰는 build.sbt 는 아래와 같다.
name := "spark-congestion-score-app"
version := "1.0"
scalaVersion := "2.11.11"
val sparkVersion = "2.2.0"
libraryDependencies ++= Seq (
"org.apache.spark" %% "spark-core" % sparkVersion % "provided", // spark runtime already provides jars
"org.apache.spark" %% "spark-streaming" % sparkVersion % "provided",
"org.apache.spark" %% "spark-streaming-kafka-0-8" % sparkVersion ,
"org.apache.spark" %% "spark-mllib" % sparkVersion % "provided",
// not relevant, just allows me to pass command line options to spark job
"args4j" % "args4j" % "2.33",
"com.bizo" % "args4j-helpers_2.10" % "1.0.0",
"org.clojars.erp12" % "jdbc-vertica" % "7.2.3"
)
/* without this explicit merge strategy code you get a lot of noise from sbt-assembly
complaining about not being able to dedup files */
assemblyMergeStrategy in assembly := {
case PathList("org","aopalliance", xs @ _*) => MergeStrategy.last
case PathList("javax", "inject", xs @ _*) => MergeStrategy.last
case PathList("javax", "servlet", xs @ _*) => MergeStrategy.last
case PathList("javax", "activation", xs @ _*) => MergeStrategy.last
case PathList("org", "apache", xs @ _*) => MergeStrategy.last
case PathList("com", "google", xs @ _*) => MergeStrategy.last
case PathList("com", "esotericsoftware", xs @ _*) => MergeStrategy.last
case PathList("com", "codahale", xs @ _*) => MergeStrategy.last
case PathList("com", "yammer", xs @ _*) => MergeStrategy.last
case "about.html" => MergeStrategy.rename
case "META-INF/ECLIPSEF.RSA" => MergeStrategy.last
case "META-INF/mailcap" => MergeStrategy.last
case "META-INF/mimetypes.default" => MergeStrategy.last
case "plugin.properties" => MergeStrategy.last
case "log4j.properties" => MergeStrategy.last
case "overview.html" => MergeStrategy.last // Added this for 2.1.0 I think
case x =>
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}
/* including scala bloats your assembly jar unnecessarily, and may interfere with spark runtime */
assemblyOption in assembly := (assemblyOption in assembly).value.copy(includeScala = false)
assemblyJarName in assembly := "spark-congestion-score-app.jar"
/* you need to be able to undo the "provided" annotation on the deps when running your spark
programs locally i.e. from sbt; this bit reincludes the full classpaths in the compile and run tasks. */
fullClasspath in Runtime := (fullClasspath in (Compile, run)).value