pyspark 线性回归模型给出错误此列名称必须是数字类型,但实际上是字符串类型

Posted

技术标签:

【中文标题】pyspark 线性回归模型给出错误此列名称必须是数字类型,但实际上是字符串类型【英文标题】:pyspark linear regression model gives error this column name must be numeric type but was actually string type 【发布时间】:2018-03-08 09:36:17 【问题描述】:

我在 pyspark 中创建了一个多项式回归模型,在运行我的线性回归模型后,它给了我这个错误 "IllegalArgumentException: u'requirement failed: 列标签必须是 NumericType 类型,但实际上是 StringType 类型。"

请在这里帮助我,因为我花了很多时间来解决这个问题,但无法解决。

    lr_data=   loan_data.select('int_rate','loan_amnt','term','grade','sub_grade','emp_length','verification_status','home_ownership','annual_inc','purpose','addr_state','open_acc') 
    lr_data.printSchema()

    root
    |-- int_rate: string (nullable = true)
    |-- loan_amnt: integer (nullable = true)
    |-- term: string (nullable = true)
    |-- grade: string (nullable = true)
    |-- sub_grade: string (nullable = true)
    |-- emp_length: string (nullable = true)
    |-- verification_status: string (nullable = true)
    |-- home_ownership: string (nullable = true)
    |-- annual_inc: double (nullable = true)
    |-- purpose: string (nullable = true)
    |-- addr_state: string (nullable = true)
    |-- open_acc: string (nullable = true)

在多项式回归模型中,我的目标变量应该是 int_rate(这是字符串类型,可能这就是我在运行时遇到此错误的原因)。

但最初我尝试在回归模型中仅使用两个值,即 int_rate,loan_amnt。

这里是代码

    input_data=lr_data.rdd.map(lambda x:(x[0], DenseVector(x[1:2])))
    data3= spark.createDataFrame(input_data,["label","features",])
    data3.printSchema()

   root
   |-- label: string (nullable = true)
   |-- features: vector (nullable = true)

IMP:注意我尝试在 DenseVector 数组中使用其他变量,但它给我抛出了很长的错误,比如 float() 的无效文字:36 个月

   usr/local/spark/python/pyspark/sql/session.pyc in createDataFrame(self,    data, schema, samplingRatio, verifySchema)
    580 
    581         if isinstance(data, RDD):
    582  rdd, schema = self._createFromRDD(data.map(prepare), schema, samplingRatio)
   583         else:
   584             rdd, schema = self._createFromLocal(map(prepare, data), schema)
    if schema is None or isinstance(schema, (list, tuple)):
    380             struct = self._inferSchema(rdd, samplingRatio)
    381             converter = _create_converter(struct)
    382             rdd = rdd.map(converter)

   /usr/local/spark/python/pyspark/sql/session.pyc in _inferSchema(self,   rdd, samplingRatio)
    349         :return: :class:`pyspark.sql.types.StructType`
    350         """
    351         first = rdd.first()
    352         if not first:
    353             raise ValueError("The first row in RDD is empty, "

请告诉我如何在这个回归模型中选择超过 2 个变量。我想我必须对数据集中的每个变量进行类型转换。

   #spilt into two partition 
   train_data, test_data = data3.randomSplit([.7,.3], seed = 1)
   lr = LinearRegression(labelCol="label", maxIter=100, regParam= 0.3, elasticNetParam = 0.8)
   linearModel = lr.fit(train_data)

现在当我运行这个 linearmodel() 时,我得到了以下错误。

    IllegalArgumentException Traceback (most recent call  last)
   <ipython-input-20-5f84d575334f> in <module>()

----> 1 线性模型 = lr.fit(train_data)

     /usr/local/spark/python/pyspark/ml/base.pyc in fit(self,dataset,params) 
      62                 return self.copy(params)._fit(dataset)
      63             else:
      64                 return self._fit(dataset)
      65         else:
      66             raise ValueError("Params must be either a param map  or a list/tuple of param maps, "

      /usr/local/spark/python/pyspark/ml/wrapper.pyc in _fit(self, dataset)
      263 
      264     def _fit(self, dataset):
      265         java_model = self._fit_java(dataset)
      266         return self._create_model(java_model)
      267 

      /usr/local/spark/python/pyspark/ml/wrapper.pyc in _fit_java(self, dataset)
        260         """
        261         self._transfer_params_to_java()
        262         return self._java_obj.fit(dataset._jdf)
        263 
        264     def _fit(self, dataset):

       /usr/local/spark/python/lib/py4j-0.10.4-src.zip/py4j/java_gateway.py in __call__(self, *args)
        1131         answer = self.gateway_client.send_command(command)
        1132         return_value = get_return_value(
        1133             answer, self.gateway_client, self.target_id, self.name)

1134 1135 对于 temp_args 中的 temp_arg:

       /usr/local/spark/python/pyspark/sql/utils.pyc in deco(*a, **kw)
        77                 raise QueryExecutionException(s.split(': ', 1)[1], stackTrace)
        78             if  s.startswith('java.lang.IllegalArgumentException: '):

---> 79 引发 IllegalArgumentException(s.split(': ', 1)[1], stackTrace) 80加薪 81返回装饰

        IllegalArgumentException: u'requirement failed: Column label must be of type NumericType but was actually of type StringType.'

请帮助我,我已经尝试了将字符串值转换为数字的所有方法,但没有任何区别。由于我的目标变量 int_rate 是默认的字符串类型,但它采用数字值。还有一个是我必须在我的回归模型中选择整个 lr 数据集。我怎样才能做到这一点。 在此先感谢:)

【问题讨论】:

【参考方案1】:

试试这个,

from pyspark.ml.linalg import Vectors
from pyspark.ml.regression import LinearRegression
from pyspark.sql.types import *
import pyspark.sql.functions as F

cols = lr_data.columns
input_data = lr_data.rdd.map(lambda x:(x['int_rate'], Vectors.dense([x[col] for col in cols if col != 'int_rate'])))\
                        .toDF(["label","features",])\
                        .select([F.col('label').cast(FloatType()).alias('label'), 'features'])

train_data, test_data = input_data.randomSplit([.7,.3], seed = 1)

lr = LinearRegression(labelCol="label", maxIter=100, regParam= 0.3, elasticNetParam = 0.8)
linearModel = lr.fit(train_data)

前提是您的所有列都可以转换为数字类型。

【讨论】:

非常感谢。我已经尝试了 int_rate 这个代码 from pyspark.sql.types import IntegerType loan_data = loan_data.withColumn("int_rate", loan_data.int_rate.cast(IntegerType())) 并将 int_rate 转换为数字类型,但在运行 data3= spark 之后。 createDataFrame(input_data,["label","features"]) 它给了我“ValueError:某些类型无法由前 100 行确定,请通过采样重试”的错误任何建议 ValueError: 某些类型不能由前100行确定,请在运行后采样重试 data3= spark.createDataFrame(input_data,["label","features"]) 尝试将createDataFrame中的samplingRatio设置为更高的值(例如:0.4) data3= spark.createDataFrame(input_data, ["label","features"],"samplingRatio", "0.5") data3.show(5, truncate = False) -----+ ---------+ |标签|特征| +-----+---------+ |null |[5000.0] | |空 |[2500.0] | linearModel = lr.fit(train_data) 现在这给了我这个错误。我在 int_rate 中的所有值都为 NULL?错误:你的要求失败:列标签必须是 NullType 类型,但实际上是 NullType 类型。' 他们从一开始就为空吗?

以上是关于pyspark 线性回归模型给出错误此列名称必须是数字类型,但实际上是字符串类型的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark 线性回归梯度下降交叉验证

pyspark使用数据帧运行线性回归

使用线性回归模型预测单个值时出错

如何将从逻辑回归模型获得的系数映射到pyspark中的特征名称

跟着AI学AI: 线性回归模型

机器学习--线性回归模型原理