线性回归:Autograd无法使用Pandas数据类型吗?

时间:2019-01-23 21:51:59

标签: python pandas linear-regression autograd

出于学习目的,我正在尝试从头开始进行线性回归(在代码和数学知识方面)。

我从循环转到NumPy,然后从手动计算梯度到使用Autograd。现在,我正在尝试将我的代码转换为使用Pandas而不是NumPy。但是似乎Autograd不适用于DataFrameSeries,因为我不断收到此错误:

TypeError: Can't differentiate w.r.t. type <class 'pandas.core.series.Series'>
# or DataFrame

我已经完成了对偶数的基本实现,所以我知道自动求差在基本级别上如何工作,但是autograd太复杂了,堆栈跟踪对我没有用。

这是代码的相关部分:

import autograd.numpy as np
import pandas as pd
from autograd import grad

raw_data = pd.read_csv('FiveCitiePMData/BeijingPM20100101_20151231.csv')
df = raw_data.filter(['HUMI','TEMP', 'PM_US Post'], axis=1).dropna()

class LinRegModel:
    def __init__(self, dataset):
        self.X = dataset.iloc[:,:-1].copy()  # all but last column
        self.X.insert(0, 'dummy', 1)         # padding (w_0)
        self.y = dataset.iloc[:,-1].copy()   # last column

    def __cost__(self, weights):
        errors = self.X @ weights - self.y
        return np.square(errors).mean() # no need to div by 2 because autodiff

    def train(self, epsilon=0.001, learning_rate=0.01):
        self.weights = pd.Series(0.0, index=list(self.X)) # np.zeros((self.X.shape[1], 1))
        grad_cost = grad(self.__cost__)
        last_cost = 0
        while True:
            self.weights -= learning_rate * grad_cost(self.weights)
            this_cost = self.__cost__(self.weights)
            if abs(this_cost - last_cost) < epsilon:
                break
            last_cost = this_cost

lrm = LinRegModel(df)

无论__cost__(weights)是NumPy数组,Pandas系列还是Pandas DataFrame,weights函数都可以正常工作。但这会给我上面的错误:

grad_cost(self.weights)

如果我这样做:

grad_cost(np.array(self.weights))

然后挂起,最终我得到了:

TypeError: Could not convert Autograd ArrayBox with value 523236993.0 to numeric

我唯一能使它工作的方法是这样做:

def __cost__(self, weights):
        errors = np.array(self.X) @ np.array(weights) - np.array(self.y)
        return np.square(errors).mean()

grad_cost(np.array(self.weights))

但这不是一个非常优雅或可读的解决方案。

我是否缺少有关Autograd或Pandas的东西?

0 个答案:

没有答案