在window 环境下使用spark - xgboost会出现一些问题,这里记录一下。
环境:window 7 + spark 2.31 + xgboost 8.1 + idea + maven
一.依赖以及代码
数据集下载地址
UCI Machine Learning Repository: Iris Data Setarchive.ics.uci.edupom依赖
<!-- https://mvnrepository.com/artifact/ml.dmlc/xgboost4j -->
<dependency><groupId>ml.dmlc</groupId><artifactId>xgboost4j</artifactId><version>0.81</version>
</dependency><!-- https://mvnrepository.com/artifact/ml.dmlc/xgboost4j-spark -->
<dependency><groupId>ml.dmlc</groupId><artifactId>xgboost4j-spark</artifactId><version>0.81</version>
</dependency>
测试代码
import org.apache.spark.ml.feature.{StringIndexer}
import org.apache.spark.sql.types.{DoubleType, StringType, StructField, StructType}
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.sql. SparkSession
import ml.dmlc.xgboost4j.scala.spark.{XGBoostClassificationModel, XGBoostClassifier}
/*** author :wy* todo : xgboost鸢尾花分类* Created by pc-admin on 2020-03-12 11:21**/
object xgboostIrisDataTest {def main(args: Array[String]): Unit = {val ss = SparkSession.builder().master("local[4]").appName("xgboostRisiDataTest").getOrCreate()val dataPath = "iris.data"val schema = new StructType(Array(StructField("sepal lenght", DoubleType, true),StructField("sepal width", DoubleType, true),StructField("petal lenght", DoubleType, true),StructField("petal width", DoubleType, true),StructField("class", StringType, true)))val rawInput = ss.read.schema(schema).csv(dataPath)// 把字符串class转换成数字数字classval stringIndexer = new StringIndexer().setInputCol("class").setOutputCol("classIndex").fit(rawInput)// 执行进行转换,并把原有的字符串class删除掉val labelTransformed = stringIndexer.transform(rawInput).drop("class")// 将多个字段合并成在一起,组成futureval vectorAssembler = new VectorAssembler().setInputCols(Array("sepal lenght", "sepal width", "petal lenght", "petal width")).setOutputCol("features")//将数据集切分成训集和测试集val xgbInput = vectorAssembler.transform(labelTransformed).select("features", "classIndex")val splitXgbInput = xgbInput.randomSplit(Array(0.9, 0.1))val trainXgbInput = splitXgbInput(0)val testXgbInput = splitXgbInput(1)// 注意!!!这个num_workers 必须小于等于 local[4] 线程数,否则会出现程序卡死现象.val xgbParam = Map("eta" -> 0.1f,"max_depth" -> 2,"objective" -> "multi:softprob","num_class" -> 3,"num_round" -> 100,"num_workers" -> 4)// 创建xgboost函数,指定特征向量和标签val xgbClassifier = new XGBoostClassifier(xgbParam).setFeaturesCol("features").setLabelCol("classIndex")// 开始训练val xgbClassificationModel: XGBoostClassificationModel = xgbClassifier.fit(trainXgbInput)// 预测val result = xgbClassificationModel.transform(testXgbInput)// 展示 result.show(1000)ss.stop()}
}
二.出现的Bug 以及解决方法
1.java.io.FileNotFoundException: File /lib/xgboost4j.dll was not found inside JAR.
进入 $MAVEN_HOMEconfrepositorymldmlc 找到 xgboost4j
找到你使用的版本,这里使用的是8.1,点击。
用winRAR打开.
发现确实缺少 File /lib/xgboost4j.dll文件。
进入点击以下链接。选择你使用的版本
criteo-forks/xgboost-jarsgithub.com点击红框下载jar包。
下载完成后,解压,你会在lib文件夹下找到这个文件。
用WinRAR打开xgboost4j-8.1.jar之后,把下载的 xgboost4j-0.81-criteo-20180821_2.11-win64.jarlib 中的xgboost4j.dll 直接拉进MAVEN_HOMEonfrepositorymldmlcxgboost4j0.81xgboost4j-8.1.jarbin里
在尝试运行一下,问题解决。
如果提示文件正在被使用,无法修改,请关闭idea即可。
2. XGBoostModel training failed
Exception in thread "main" ml.dmlc.xgboost4j.java.XGBoostError: XGBoostModel training failed
atml.dmlc.xgboost4j.scala.spark.XGBoost$.postTrackerReturnProcessing(XGBoost.scala:363)
at ml.dmlc.xgboost4j.scala.spark.XGBoost$.trainDistributed(XGBoost.scala:334)
at ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator.train(XGBoostEstimator.scala:139)
at ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator.train(XGBoostEstimator.scala:36)
at org.apache.spark.ml.Predictor.fit(Predictor.scala:90)
at ml.dmlc.xgboost4j.scala.spark.XGBoost$.trainWithDataFrame(XGBoost.scala:191)
如果你也出现了这个bug,那么恭喜你,咱们的节奏对上了,这个问题我搞了一下午总结一下网上的几种说法。
- 运行环境存在多个scala 和 java 版本
- spark版本和xgboost版本不对应,比如xgboost 9.0 必须对应spark 2.4以上版本,xgboost 8.1 必须对应spark 2.31以上版本。
我一一验证,最后的结论都是不行的,于是一气之下我重启了一下计算机,您猜怎么着???奇迹的问题解决了。。。
结论:先重启一下计算机,如果问题解决,你将节省一下午时间。。。
3 . 程序运行卡着不动的情况
出现这种情况就是你在初始化spark master的时候给的线程数小于你的work_number,切记:
master('local[m]')
work_number(n)
一定要 m >= n
三,运行结果
原标签: classIndex
预测标签 : prediction
真特喵的不容易~~~
参考资料:
sgboost AIP官方文档
XGBoost4J-Spark Tutorial (version 0.8+)xgboost.readthedocs.io一个情况和我类似的国际友人
https://github.com/dmlc/xgboost/issues/2780github.com