Spark的ml包提供了非常好用的调参功能,通过ParamGridBuilder构建待选参数(如:logistic regression的regParam),然后数据量小的时候可以用CrossValidator进行交叉验证,数据量大的时候可以直接用trainValidationSplit,这样Spark就会找到最佳的参数组合并训练模型。
千万不要小瞧这个功能,个人实际工作中的情况来看,logistic regression调整regParam参数,测试集的准确率可以从55%提升到83%(从质疑人生的意义到重新获得生活的希望)。但有个问题是CrossValidator和trainValidationSplit训练得到新model之后,你无从得知所使用最优的参数组合到底是什么,特别是1.6版本的TrainValidationSplitModel你甚至无法保存,这实在太不合理了,应该找时间去github上提个issue……
好在经过一番Google后,在老朋友StackOverflow上找到了解决方案:How to print best model params in Apache Spark Pipeline?
2015-10-21 12:57:33,831 [INFO org.apache.spark.ml.tuning.TrainValidationSplit] Best set of parameters: { hashingTF_79cf758f5ab1-numFeatures: 2000000, nb_67d55ce4e1fc-smoothing: 1.0 } 2015-10-21 12:57:33,831 [INFO org.apache.spark.ml.tuning.TrainValidationSplit] Best train validation split metric: 0.7358721053749735.
就是在训练的过程中INFO级别的日志里是有最优参数结果的,因为Spark在console里默认的日志打印级别是INFO,所以大家应该经常看到一大长串日志,而最优参数就埋没在这些日志里了。因此,这里不得不好好了解一下log4j的配置方法了,这里直接上相关的log4j配置文件,然后再进行解释:
log4j.rootCategory=INFO, console log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.target=System.err log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n # spark trainValidationSplit Best set of parameters log4j.logger.org.apache.spark.ml.tuning.TrainValidationSplit=INFO, FILE log4j.additivity.org.apache.spark.ml.tuning.TrainValidationSplit=false log4j.appender.FILE=org.apache.log4j.FileAppender log4j.appender.FILE.file=/home/logos/spark/tuning.log log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n
注:$SPARK_HOME/conf/目录下的log4j.properties文件将被Spark用作默认的log4j配置文件。
- log4j.rootCategory=INFO, console:这里是指定默认的级别为INFO,并且将日志打印在console这个appender里
- 以log4j.appender.console开头的都是console相关的配置,具体的意义可自行Google
- log4j.logger.org.apache.spark.ml.tuning.TrainValidationSplit=INFO, FILE这里是专门针对TrainValidationSplit这个类做定义,采用FILE这个appender
- log4j.additivity.org.apache.spark.ml.tuning.TrainValidationSplit=false代表不继承父Logger的appender
- log4j.appender.FILE开头的都是FILE相关的配置,如:指定日志输出的路径为/home/logos/spark/tuning.log
这样我们就可以打包好用于调参的spark jar包,然后让服务器在后台跑着程序,等着从日志文件里找到最优的参数组合了!
转载请注明出处:http://logos.name/