Xgboost: [حزم jvm] java.lang.NullPointerException: فارغ في ml.dmlc.xgboost4j.java.Booster.predict

تم إنشاؤها على ٣٠ يوليو ٢٠٢٠  ·  37تعليقات  ·  مصدر: dmlc/xgboost

تحدث استثناءات NPE عند توقعها من خلال JAVA API.

java.lang.NullPointerException: null
في ml.dmlc.xgboost4j.java.Booster.predict (Booster.java:309)
في ml.dmlc.xgboost4j.java.Booster.predict (Booster.java:375)
في com.tuhu.predict.predict.BaseModelPredict.predict (BaseModelPredict.java:71)
في com.tuhu.predict.predict.XgboostFindPageModelPredict.predict (XgboostFindPageModelPredict.java:53)
في com.tuhu.predict.service.impl.MlpFindPageFeatureServiceImpl.featureProcess (MlpFindPageFeatureServiceImpl.java:65)
في com.tuhu.predict.api.controller.MlpFindPageController.recommendPredict (MlpFindPageController.java:49)
في com.tuhu.predict.api.controller.MlpFindPageController $$ FastClassBySpringCGLIB $$ f694b9ff.invoke ()
في org.springframework.cglib.proxy.MethodProxy.invoke (MethodProxy.java:204)
في org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint (CglibAopProxy.java:746)
في org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:163)
في org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke (MethodBeforeAdviceInterceptor.java:52)
في org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:174)
في org.springframework.aop.aspectj.AspectJAfterAdvice.invoke (AspectJAfterAdvice.java:47)
في org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:174)
في org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke (AfterReturningAdviceInterceptor.java:52)
في org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:174)
في org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke (AspectJAfterThrowingAdvice.java:62)
في org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:174)
في org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceedingJoinPoint.java:88
في com.tuhu.springcloud.common.annotation.AbstractControllerLogAspect.doAround (AbstractControllerLogAspect.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (الطريقة الأصلية)
في sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
في sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
على java.lang.reflect.Method.invoke (Method.java:498)
في org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs (AbstractAspectJAdvice.java:644)
في org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod (AbstractAspectJAdvice.java:633)
في org.springframework.aop.aspectj.AspectJAroundAdvice.invoke (AspectJAroundAdvice.java:70)
في org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:174)
في org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke (ExposeInvocationInterceptor.java:92)
في org.springframework.aop.framework.ReflectiveMethodInvocation.proceed (ReflectiveMethodInvocation.java:185)
في org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept (CglibAopProxy.java:688)
على com.tuhu.predict.api.controller.MlpFindPageController $$ EnhancerBySpringCGLIB $$ 560ed775.recommendPredict ()
at sun.reflect.NativeMethodAccessorImpl.invoke0 (الطريقة الأصلية)
في sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
في sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
على java.lang.reflect.Method.invoke (Method.java:498)
في org.springframework.web.method.support.InvocableHandlerMethod.doInvoke (InvocableHandlerMethod.java:209)
في org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest (InvocableHandlerMethod.java:136)
في org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle (ServletInvocableHandlerMethod.java:102)
في org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod (RequestMappingHandlerAdapter.java:877)
في org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal (RequestMappingHandlerAdapter.java:783)
في org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle (AbstractHandlerMethodAdapter.java:87)
في org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:991)
في org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:925)
في org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:974)
في org.springframework.web.servlet.FrameworkServlet.doPost (FrameworkServlet.java:877)
على javax.servlet.http.HttpServlet.service (HttpServlet.java:661)
في org.springframework.web.servlet.FrameworkServlet.service (FrameworkServlet.java:851)
على javax.servlet.http.HttpServlet.service (HttpServlet.java:742)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:231)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في org.apache.tomcat.websocket.server.WsFilter.doFilter (WsFilter.java:52)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في com.tuhu.soter.starter.filter.SoterDefaultFilter.doFilter (SoterDefaultFilter.java:79)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في com.tuhu.boot.logback.filter.LogFilter.doFilter (LogFilter.java:54)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics (WebMvcMetricsFilter.java:158)
في org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics (WebMvcMetricsFilter.java:126)
في org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal (WebMvcMetricsFilter.java:111)
في org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal (HttpTraceFilter.java:90)
في org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في com.tuhu.boot.common.filter.HeartbeatFilter.doFilter (HeartbeatFilter.java:42)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
على com.tuhu.boot.common.filter.MDCFilter.doFilter (MDCFilter.java:47)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في org.springframework.web.filter.RequestContextFilter.doFilterInternal (RequestContextFilter.java:99)
في org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal (HttpPutFormContentFilter.java:109)
في org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal (HiddenHttpMethodFilter.java:93)
في org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:200)
في org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:107)
في org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:193)
في org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166)
في org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:198)
في org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:96)
في org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:496)
في org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:140)
في org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:81)
في org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:87)
في org.apache.catalina.valves.RemoteIpValve.invoke (RemoteIpValve.java:677)
في org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:342)
في org.apache.coyote.http11.Http11Processor.service (Http11Processor.java:803)
في org.apache.coyote.AbstractProcessorLight.process (AbstractProcessorLight.java:66)
في org.apache.coyote.AbstractProtocol $ ConnectionHandler.process (AbstractProtocol.java:790)
في org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun (NioEndpoint.java:1468)
في org.apache.tomcat.util.net.SocketProcessorBase.run (SocketProcessorBase.java:49)
على java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1149)
في java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:624)
في org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run (TaskThread.java:61)
في java.lang.Thread.run (Thread.java:748)

التعليق الأكثر فائدة

حسنًا ، أعتقد أنه سيكون جاهزًا بحلول الغد.

ال 37 كومينتر

نظرًا لأن النموذج تم تدريبه من خلال Python Sklearn ، فقد حدثت حالات عدم توافق لاحقًا ، ولتوفير الوقت ، قام فريق الخوارزمية بنقل طبقة واحدة من نموذج XGB المدربين من Sklearn فوق حزمة Python XgBoost ، وأتساءل عما إذا كان هذا هو سبب ذلك.

image

ما هو إصدار XGBoost الذي تستخدمه؟ لقد أصلحنا سابقًا خطأً أن حزمة jvm لا تطرح الاستثناء بشكل صحيح عند فشل التوقع والاستمرار في وجود مخزن مؤقت فارغ للتنبؤ.

ما هو إصدار XGBoost الذي تستخدمه؟ لقد أصلحنا سابقًا خطأً أن حزمة jvm لا تطرح الاستثناء بشكل صحيح عند فشل التوقع والاستمرار في وجود مخزن مؤقت فارغ للتنبؤ.

يتم استخدام الإصدار 1.0 من النظام الأساسي للخوارزمية الخاص بالشركة ، ويتم استخدام الإصدار 0.9.0 من مشروع الخوارزمية بسبب مشكلات توافق الإصدار. استخدم زملاؤنا في الخوارزمية Python لتحويل ملف النموذج 1.0 إلى 0.9.0. أتساءل عما إذا كان سببه هذا التحول

أقترح الانتظار حتى 1.2 (https://github.com/dmlc/xgboost/issues/5734) وحاول مرة أخرى ، لدينا بعض إصلاحات الأخطاء المهمة في هذا الإصدار. كما أود أن أقترح استخدام نفس إصدار xgboost أو إصدار أحدث للتنبؤ. نموذج XGBoost الثنائي متوافق مع الإصدارات السابقة ، والمضي قدمًا ، ويوصى بالنموذج المستند إلى JSON.

لقد أصبت نفس المشكلة مع 1.2.0. لذا فإن المشكلة لا تزال هنا.

أنا أيضا لدي نفس المشكلة.
لقد استخدمت xgboost4j لإنشاء النموذج.

ايوجد اي عمل في هذه المنطقه؟

هذه مشكلة كبيرة بالنسبة لي ، إنها وظائف فاشلة في الإنتاج.

ranInc هل تستخدم أحدث إصدار من XGBoost؟ حتى الآن لا ندرك السبب الدقيق لهذه المشكلة. سنقوم بمعالجتها على أساس بذل أفضل الجهود ، ونظرًا لعدم وجود ضمان بخصوص موعد معالجة المشكلة ، أقترح عليك التحقيق في بديل في غضون ذلك.

ranInc يمكنك مساعدتنا من خلال توفير مثال صغير لبرنامج يمكننا (المطورين) تشغيله على أجهزتنا الخاصة.

أنا أقوم بتشغيل 1.2.0 ، أحدث جرة في مستودع مافن.
البديل بالنسبة لي هو العودة إلى saprk 2.4.5 واستخدام xgboost 0.9 - وهذا ما أفعله الآن.

على سبيل المثال: سأحاول تحديد النموذج / البيانات المحددة التي تسببت في فشل الوظيفة لاحقًا.

أهلا،
لقد وجدت النموذج / البيانات المحددة.
أنا أرفقه في هذا التعليق.
xgb1.2_bug.zip

هذه هي الطريقة التي تعيد بها إنشاء الخطأ (ضع في اعتبارك أنه إذا لم تقم بإعادة التقسيم هنا ، فإنها تعمل - لذلك فهي تتعلق بكمية البيانات أو نوع البيانات في كل قسم):

from pyspark.ml.pipeline import PipelineModel
from pyspark.sql import SparkSession
from pyspark.sql.dataframe import DataFrame

df = spark.read.parquet("/tmp/6620294785024229130_features").repartition(200).persist()
df.count()

model = PipelineModel.read().load("/tmp/6620294785024229130_model_xg_only")

predictions = model.transform(df)

predictions.persist()
predictions.count()
predictions.show()

هل لديك أي فكرة متى يمكن معالجة هذا؟
هذا يمنعني من استخدام شرارة 3.0 ...

ranInc ليس بعد. سنخبرك عندما نلتف حول إصلاح الخطأ. أيضا ، هل يمكنك نشر الرمز في سكالا؟ لا أعتقد أننا دعمنا رسميًا استخدام PySpark مع XGBoost.

      import org.apache.spark.ml.{Pipeline, PipelineModel}
      val df = spark.read.parquet("/tmp/6620294785024229130_features").repartition(200).persist()
      df.count()

      val model = PipelineModel.read.load("/tmp/6620294785024229130_model_xg_only")

      val predictions = model.transform(df)

      predictions.persist()
      predictions.count()
      predictions.show()

مؤشر آخر ،
يبدو أن المشكلة ترجع إلى أن جميع الميزات التي يتم إرسالها ليتم توقعها هي أصفار / مفقودة.

أعتقد أن لا أحد يعمل على هذا؟
هذا يعني في الأساس أن xgboost لا يعمل على شرارة 3 على الإطلاق.

أجل ، آسف ، أيدينا ممتلئة تمامًا الآن. سوف نتغلب على هذه المشكلة في مرحلة ما. أطلب بكل احترام صبركم. شكرا.

ranInc أمضيت بعض الوقت اليوم لذا حاولت تشغيل البرنامج النصي الذي قدمته هنا. لقد قمت بإعادة إنتاج الخطأ java.lang.NullPointerException .

الغريب أن أحدث إصدار من التطوير ( master Branch) لا يتلف بنفس الطريقة. بدلا من ذلك ، ينتج خطأ

استثناء في موضوع org.apache.spark.SparkException "الرئيسي": تم إحباط المهمة بسبب فشل المرحلة: فشل المهمة 0 في المرحلة 7.0 مرة واحدة ، الفشل الأخير: فقدت المهمة 0.0 في المرحلة 7.0 (TID 11 ، d04389c5babb ، برنامج تشغيل المنفذ): ml.dmlc.xgboost4j.java.XGBoostError: [00:36:10] /workspace/src/learner.cc:1179: فشل التحقق: learner_model_param_.num_feature> = p_fmat-> Info (). num_col_ (1 مقابل 2) : عدد الأعمدة لا يتطابق مع عدد الميزات في المعزز.

سأحقق أكثر.

أعتقد أن رسالة الخطأ منطقية الآن ، فالمدخلات الخاصة بك بها ميزات أكثر من نموذج التنبؤ.

قبل أن تستمر حزمة jvm بعد فشل xgboost ، مما يؤدي إلى وجود مخزن مؤقت فارغ للتنبؤ. لقد أضفت شيكًا حارسًا مؤخرًا.

فقط تأكد من أن عدد الأعمدة في مجموعة بيانات التدريب أكبر من أو يساوي مجموعة بيانات التنبؤ الخاصة بك.

أهلا،
تم إنشاء النموذج باستخدام نفس القدر من الميزات.
في شرارة يستخدم عمود متجه واحد وليس عدة أعمدة.
على أي حال ، فإن حجم المتجه هو نفسه دائمًا ، للتوافق والتنبؤ - 100٪ متأكد من ذلك.

هذا له علاقة بالصفوف التي تحتوي على جميع الميزات الصفرية / المفقودة.
يمكنك أن ترى أنه إذا قمت بتصفية الصفوف التي تحتوي على جميع الميزات الصفرية من إطار البيانات - فهي تعمل بشكل جيد.

ranInc هل يمكنك نشر برنامج Scala الكامل الذي أنشأ النموذج؟ يبدو أن رسالة الخطأ تشير إلى أن نموذجك قد تم تدريبه باستخدام ميزة واحدة.

لا أعتقد أنه سيساعد كثيرًا لأن الشفرة عامة جدًا وتحتوي على بعض المحولات الاسترضائية ،
الكود نفسه هو في الغالب pyspark وليس scala.

أفضل طريقة لمعرفة أن عدد الميزات لا يمثل مشكلة هي فقط تصفية الصفوف التي تحتوي على جميع الميزات الصفرية واستخدام النموذج - يعمل هذا بدون مشكلة.
يمكنك أيضًا الاحتفاظ بجميع الصفوف وإعادة تقسيم إطار البيانات لاستخدام قسم واحد ، وهذا يعمل أيضًا.

ranInc لقد قمت بتصفية الصفوف التي بها صفر وما زلت تواجه نفس الخطأ ( java.lang.NullPointerException ):

...
df.na.drop(minNonNulls = 1)
...

أليست هذه هي الطريقة الصحيحة للقيام بذلك؟

لا أعتقد أنه سيساعد كثيرًا لأن الشفرة عامة جدًا ولديها بعض المحولات الاسترضائية

أرغب في معرفة عدد الميزات التي يتم استخدامها في التدريب وفي وقت التوقع. رسالة الخطأ

ml.dmlc.xgboost4j.java.XGBoostError: [00:36:10] /workspace/src/learner.cc:1179: فشل التحقق: learner_model_param_.num_feature> = p_fmat-> Info (). num_col_ (1 مقابل 2) : عدد الأعمدة لا يتطابق مع عدد الميزات في المعزز.

يشير إلى أن النموذج قد تم تدريبه بميزة واحدة ويتم التنبؤ بميزتين.

في الوقت الحالي ، لدي فقط حق الوصول إلى إطار البيانات والنموذج المتسلسل الذي قمت بتحميله. أفتقر إلى نظرة ثاقبة حول ما تم إدخاله في تدريب النموذج وما الخطأ الذي حدث ، مما أعاقني عن استكشاف المشكلة وإصلاحها بشكل أكبر. إذا كان برنامجك يحتوي على بعض المعلومات الخاصة ، فهل من الممكن إنتاج مثال نظيف؟

  1. لا ، يمكنك فعل هذا:
import org.apache.spark.ml.linalg.{SparseVector, Vector}
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions.{callUDF, col}
.......
 val isVectorAllZeros = (col: Vector) => {
        col match {
          case sparse: SparseVector =>
            if(sparse.indices.isEmpty){
              true
            }else{
              false
            }
          case _ => false
        }
      }

      spark.udf.register("isVectorAllZeros", isVectorAllZeros)
      df = df.withColumn("isEmpty",callUDF("isVectorAllZeros",
        col("features_6620294785024229130"))).where("isEmpty == false")

يمكنك أيضًا إعادة تقسيم إطار البيانات على النحو التالي:

....
df = df.repartition(1)
....
  1. أنا أفهم ، لكن الكود لن يمنحك الكثير ، لأنه يستخدم VectorAssembler ، ولن تتمكن من معرفة عدد الميزات التي تم استخدامها بالفعل ،
    لكنني متأكد بنسبة 100٪ من أنها استخدمت نفس القدر من الميزات.

لكنني متأكد بنسبة 100٪ من أنها استخدمت نفس القدر من الميزات.

كيف يمكنك التأكد من ذلك ، إذا تسبب VectorAssembler في وجود عدد متغير من الميزات؟

تقوم VectorAssembler دائمًا بإنشاء نفس القدر من الميزات ، فهي تحتاج فقط إلى أسماء الأعمدة للاستيلاء عليها.
يتم استخدام الكود نفسه لإنشاء آلاف النماذج ، لذلك فهو عام جدًا ويحصل بشكل أساسي على قائمة بالأسماء لاستخدامها.

قد أتمكن من تشغيل إنشاء النموذج مرة أخرى وإرسال إطار البيانات المستخدم للنموذج - أو أي بيانات أخرى تحتاجها.
سيستغرق ذلك بعض الوقت بالنسبة لي ، وإذا استخدمت ما عرضته من قبل ، فسترى أن النموذج يعمل بشكل جيد مع ميزتين.

ranInc دعني أطرح سؤالاً آخر: هل من الصحيح أن نقول إن البيانات النموذجية بها عمود متفرق (VectorAssembler) يحتوي على ميزتين على الأكثر ؟

رقم.
VectorAssembler هو Trasformer الذي يمسك أعمدة متعددة ويضعها في عمود Vector واحد.
تُستخدم النواقل دائمًا للنماذج الملائمة والتنبؤ بالشرارة.

يحتوي مثال إطار البيانات هنا على عمود متجه.
بعض الصفوف متفرقة ، والبعض الآخر كثيف - وكلها لها ميزتان.

ranInc لذلك كل الصفوف لها ميزتان ، بعض القيم مفقودة والبعض الآخر ليس كذلك. فهمتك. سأحاول اقتراحك حول تصفية الصفوف الفارغة.

كما قد تكون خمنت ، أنا جديد تمامًا على نظام Spark البيئي ، لذلك قد يكون تصحيح الأخطاء صعبًا للغاية. نحن بحاجة حاليًا إلى المزيد من المطورين الذين يعرفون المزيد عن برمجة Spark و Scala بشكل عام. إذا كنت تعرف شخصًا شخصًا ما يرغب في مساعدتنا في تحسين حزمة JVM الخاصة بـ XGBoost ، فيرجى إخبارنا بذلك.

ranInc حاولت تصفية الصفوف الفارغة وفقًا لاقتراحك:

البرنامج أ: مثال على البرنامج النصي ، بدون تصفية للصفوف الفارغة

import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.{Pipeline, PipelineModel}
import org.apache.spark.ml.linalg.{SparseVector, Vector}
import org.apache.spark.sql.functions.{callUDF, col}

object Main extends App {
  val spark = SparkSession
      .builder()
      .appName("XGBoost4J-Spark Pipeline Example")
      .getOrCreate()

  val df = spark.read.parquet("/home/ubuntu/data/6620294785024229130_features").repartition(200).persist()
  df.show()

  val model = PipelineModel.read.load("/home/ubuntu/data/6620294785024229130_model_xg_only")

  val predictions = model.transform(df)

  predictions.persist()
  predictions.count()
  predictions.show()
}

البرنامج ب: مثال مع تصفية صف فارغ

import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.{Pipeline, PipelineModel}
import org.apache.spark.ml.linalg.{SparseVector, Vector}
import org.apache.spark.sql.functions.{callUDF, col}

object Main extends App {
  val spark = SparkSession
      .builder()
      .appName("XGBoost4J-Spark Pipeline Example")
      .getOrCreate()

  val isVectorAllZeros = (col: Vector) => {
    col match {
      case sparse: SparseVector => (sparse.indices.isEmpty)
      case _ => false
    }
  }
  spark.udf.register("isVectorAllZeros", isVectorAllZeros)

  val df = spark.read.parquet("/home/ubuntu/data/6620294785024229130_features").repartition(200).persist()
                .withColumn("isEmpty", callUDF("isVectorAllZeros", col("features_6620294785024229130")))
                .where("isEmpty == false")
  df.show()

  val model = PipelineModel.read.load("/home/ubuntu/data/6620294785024229130_model_xg_only")

  val predictions = model.transform(df)

  predictions.persist()
  predictions.count()
  predictions.show()
}

بعض الملاحظات

  • مع الإصدار 1.2.0 المستقر ، انتهت أخطاء البرنامج A java.lang.NullPointerException . قبل NPE مباشرة ، يتم عرض التحذير التالي في سجل تنفيذ Spark:
WARNING: /xgboost/src/learner.cc:979: Number of columns does not match number of features in booster. Columns: 0 Features: 1
  • مع الإصدار 1.2.0 المستقر ، يكتمل البرنامج B بنجاح دون أخطاء.
  • مع إصدار التطوير (أحدث فرع master ، الالتزام 42d31d9dcb6f7c1cb7d0545e9ab3a305ecad0816) ، يفشل كل من البرنامج A والبرنامج B مع الخطأ التالي:
[12:44:57] /home/ubuntu/xgblatest/src/learner.cc:1179: Check failed: learner_model_param_.num_feature >= p_fmat->Info().num_col_ (1 vs. 2) : Number of columns does not match number of features in booster.                                                                                                        
Stack trace:                                                                                                                                   
  [bt] (0) /tmp/libxgboost4j14081654332866852928.so(dmlc::LogMessageFatal::~LogMessageFatal()+0x79) [0x7f7ef62c4e19]                             [bt] (1) /tmp/libxgboost4j14081654332866852928.so(xgboost::LearnerImpl::ValidateDMatrix(xgboost::DMatrix*, bool) const+0x20b) [0x7f7ef63f5f0b]                                                                                                                                              
  [bt] (2) /tmp/libxgboost4j14081654332866852928.so(xgboost::LearnerImpl::Predict(std::shared_ptr<xgboost::DMatrix>, bool, xgboost::HostDeviceVector<float>*, unsigned int, bool, bool, bool, bool, bool)+0x3c3) [0x7f7ef6400233]                                                             
  [bt] (3) /tmp/libxgboost4j14081654332866852928.so(XGBoosterPredict+0xec) [0x7f7ef62caa3c]                                                      [bt] (4) /tmp/libxgboost4j14081654332866852928.so(Java_ml_dmlc_xgboost4j_java_XGBoostJNI_XGBoosterPredict+0x47) [0x7f7ef62befd7]             
  [bt] (5) [0x7f80908a8270]

وهو أمر غريب لأنه وفقًا لـ ranInc ، تم تدريب النموذج ببيانات ذات ميزتين.

  • لقد أنشأت الإصدار 1.2.0-SNAPSHOT من المصدر (الالتزام 71197d1dfa27c80add9954b10284848c1f165c40). هذه المرة ، فشل كل من البرنامج "أ " والبرنامج "ب" مع ظهور خطأ غير مطابق للميزة ( learner_model_param_.num_feature >= p_fmat->Info().num_col_ (1 vs. 2) : Number of columns does not match number of features in booster ).
  • كان الاختلاف في السلوك بين الإصدار المستقر 1.2.0 و 1.2.0-SNAPSHOT غير متوقع وجعلني أشعر بالتوتر الشديد. على وجه الخصوص ، رسالة التحذير من 1.2.0
WARNING: /xgboost/src/learner.cc:979: Number of columns does not match number of features in booster. Columns: 0 Features: 1

لم يتم العثور على الإصدار 1.2.0 من C ++ codebase. بدلاً من ذلك ، تم العثور على التحذير في الفرع release_1.0.0 :
https://github.com/dmlc/xgboost/blob/ea6b117a5737f5beb2533fc89b3f3fcd72ecc04e/src/learner.cc#L972 -L982
فهل هذا يعني أن ملف 1.2.0 JAR على Maven Central يحتوي على libxgboost4j.so من 1.0.0 ؟؟ 🤯 😱

  • في الواقع ، يحتوي ملف 1.2.0 JAR من Maven Central على libxgboost4j.so وهو في الواقع 1.0.0 (!!!). لمعرفة ذلك ، قم بتنزيل xgboost4j_2.12-1.2.0.jar من Maven Central واستخرج ملف libxgboost4j.so . ثم قم بتشغيل برنامج Python النصي التالي للتحقق من إصدار ملف المكتبة:
import ctypes

lib = ctypes.cdll.LoadLibrary('./libxgboost4j.so')

major = ctypes.c_int()
minor = ctypes.c_int()
patch = ctypes.c_int()

lib.XGBoostVersion(ctypes.byref(major), ctypes.byref(minor), ctypes.byref(patch))
print((major.value, minor.value, patch.value))  # prints (1, 0, 2), indicating version 1.0.2
  • بغض النظر عن مشكلة 1.0.0 ، نرى بوضوح أن نموذج XGBoost المدرب قد تعرف على ميزة واحدة فقط ( learner_model_param_.num_feature == 1 ). ربما تحتوي بيانات التدريب على ميزة كانت فارغة 100٪ ؟؟ تضمين التغريدة

هل تريد مني الحصول على إطار البيانات المستخدم لإنشاء النموذج؟
إذا تمكنت من الحصول عليها ، أعتقد أنه يمكنني إنشاء رمز scala بسيط يقوم بإنشاء النموذج.

ranInc أشك في أن إحدى السمتين في بيانات التدريب تتكون بالكامل من قيم مفقودة ، حيث حدد learner_model_param_.num_feature إلى 1. لذا نعم ، ستكون رؤية بيانات التدريب مفيدة للغاية.

حسنًا ، أعتقد أنه سيكون جاهزًا بحلول الغد.

تم إنشاء # 6426 لتتبع مشكلة عدم تطابق libxgboost4j.so . هنا (# 5957) دعنا نواصل المناقشة حول سبب تعيين learner_model_param_.num_feature على 1.

يبدو أنك مخطئ ، فبيانات التدريب لا تحتوي على قيم مفقودة.
في رمز المثال هنا ، بدلاً من الترحيل على إعادة التقسيم لإعادة إنتاج الفشل ، استخدمت بدلاً من ذلك صفًا واحدًا فقط (لا يحتوي إلا على ميزات صفرية) للتنبؤ.

features_creation.zip

import ml.dmlc.xgboost4j.scala.spark.XGBoostRegressor
import org.apache.spark.ml.Pipeline
import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.PipelineModel
import org.apache.spark.sql.DataFrame

val df = spark.read.parquet("/tmp/6620294785024229130_only_features_creation").persist()
df.count()

val regressor = new XGBoostRegressor()
    .setFeaturesCol("features_6620294785024229130")
    .setLabelCol("label_6620294785024229130")
    .setPredictionCol("prediction")
    .setMissing(0.0F)
    .setMaxDepth(3)
    .setNumRound(100)
    .setNumWorkers(1)

val pipeline = new Pipeline().setStages(Array(regressor))
val model = pipeline.fit(df)

val pred = spark.read.parquet("/tmp/6620294785024229130_features").persist()
pred.count()
pred.where("account_code == 4011593987").show()
model.transform(pred.where("account_code == 4011593987")).show()
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات