Pyspark在窗口验证条件上应用线性回归

时间:2019-05-31 13:27:21

标签: pyspark linear-regression pyspark-sql

我有一个按 id base_date base_date_2 排序的数据框,并具有关联的。我已经计算了相同(id,base_date)的这些增量的累积总和。

df.show()  

+---+-------------+-------------+----------+------------------+
|id |  base_date  | base_date_2 |    value | base_date_cumsum |              
+---+-------------+-------------+----------+------------------+
| 1 |  2017-07-03 |  2014-09-09 |   1.0122 |        0         |              
| 1 |  2017-07-03 |  2015-02-11 |   1.6013 |        155       |               
| 1 |  2017-07-03 |  2015-09-11 |   1.6298 |        367       |               
| 2 |  2018-10-22 |  2014-06-24 |   1.6554 |        0         |         
| 2 |  2018-10-22 |  2014-10-17 |   2.1543 |        115       |             
| 2 |  2018-10-22 |  2015-05-27 |   2.2294 |        337       |
| 2 |  2018-10-22 |  2017-03-21 |   1.5201 |        1001      |              
| 2 |  2018-10-22 |  2017-09-23 |   0.9193 |        1187      |            
| 3 |  2018-06-07 |  2014-06-30 |   1.0495 |        0         |      
| 3 |  2018-06-07 |  2015-08-06 |   1.3706 |        402       |           
| 3 |  2018-06-07 |  2015-12-22 |   1.3643 |        540       |          
| 3 |  2018-06-07 |  2016-05-30 |   1.9342 |        700       |          
| 3 |  2018-06-07 |  2017-02-27 |   0.3606 |        973       |         
+---+-------------+-------------+----------+------------------+

出于功能工程的目的,我想在相同的(id,base_date)(即在不同的base_date_2上)和不同的时间段中计算线性回归的坡度系数 >(1个月,3个月,5个月和1年)。

要获得该系数,我找到了使用corrstddev的方法:

坡度= corr(base_date_cumsum,值)* stddev(value)/ stddev(base_date_cumsum)

然后我将其应用于适当的窗口:

my_window =  Window.partitionBy('t_chassis', 'base_date')

df = df.withColumn('slope_coef',
    (stddev(col('value')).over(my_window))*
    ((corr(col('base_date_cumsum'), col('value')).over(my_window))/
    (stddev(col('base_date_cumsum')).over(my_window))))

给予:

+---+-------------+-------------+----------+------------------+-------------+
|id |  base_date  | base_date_2 |    value | base_date_cumsum | slope_coef  |          
+---+-------------+-------------+----------+------------------+-------------+
| 1 |  2017-07-03 |  2014-09-09 |   1.0122 |        0         |  0.00159095 |
| 1 |  2017-07-03 |  2015-02-11 |   1.6013 |        155       |  0.00159095 | 
| 1 |  2017-07-03 |  2015-09-11 |   1.6298 |        367       |  0.00159095 | 
| 2 |  2018-10-22 |  2014-06-24 |   1.6554 |        0         | -0.00075601 |
| 2 |  2018-10-22 |  2014-10-17 |   2.1543 |        115       | -0.00075601 |
| 2 |  2018-10-22 |  2015-05-27 |   2.2294 |        337       | -0.00075601 |
| 2 |  2018-10-22 |  2017-03-21 |   1.5201 |        1001      | -0.00075601 |
| 2 |  2018-10-22 |  2017-09-23 |   0.9193 |        1187      | -0.00075601 |
| 3 |  2018-06-07 |  2014-06-30 |   1.0495 |        0         | -0.00035787 |
| 3 |  2018-06-07 |  2015-08-06 |   1.3706 |        402       | -0.00035787 |
| 3 |  2018-06-07 |  2015-12-22 |   1.3643 |        540       | -0.00035787 |
| 3 |  2018-06-07 |  2016-05-30 |   1.9342 |        700       | -0.00035787 |
| 3 |  2018-06-07 |  2017-02-27 |   0.3606 |        973       | -0.00035787 |
+---+-------------+-------------+----------+------------------+-------------+

现在,我想添加5个新列,它们分别计算完全相同的内容,但要在特定的时间段内分别计算: coeff_1m coeff_3m coeff_5m coeff_12m coeff_24m
我尝试过:

df = df.withColumn('coeff_1m',
   when((col('base_date_cumsum') <= 31),
   (stddev(col('value')).over(my_window))*
   ((corr(col('date_p1koa_delta_cumsum'), col('value')).over(my_window))/
   (stddev(col('date_p1koa_delta_cumsum')).over(my_window))))

df = df.withColumn('coeff_3m',
   when((col('base_date_cumsum') <= 92),
   (stddev(col('value')).over(my_window))*
   ((corr(col('date_p1koa_delta_cumsum'), col('value')).over(my_window))/
   (stddev(col('date_p1koa_delta_cumsum')).over(my_window))))

etc..

这对所有5列返回相同的系数。当base_date_cumsum确实超过阈值但系数没有变化时,它确实重复了几次,这肯定是从系数开始的。计算出更多的值。

0 个答案:

没有答案