我在Python中使用numpy实现线性回归。我的平方成本函数的实现如下:
square_cost(w, datax, datay): ndata = datax.shape[1] return (1/ndata)*np.sum((h(w, datax)-datay)**2)
所有参数都是二维的ndarray,但datay和结果只有一个高度。
后来我看到了另一种实现:
square_cost(w, datax, datay): ndata = datax.shape[1] diff = h(w, datax)-datay return (1/ndata)*diff.dot(diff.T)
我认为我的第一个实现最清晰,但第二个实现因为使用了点积,是否更快呢?
回答:
设置
import numpy as npnp.random.seed([3, 1415])x = np.random.rand(1000000, 1)y = np.random.rand(1000000, 1)%%timeitdiff = x - ydiff.T.dot(diff)
100次循环,最佳3次:每次循环3.66毫秒
%%timeitdiff = x - ynp.square(diff).sum()
100次循环,最佳3次:每次循环6.85毫秒
我认为是的。点积更快。
编辑:
为了完整性,并回应评论中@Eric对原始问题提出的担忧。
在手头的回归中,内生变量(y)的维度是n x 1。因此,我们可以安全地假设第二维度的大小始终为1。
然而,如果它的尺寸大于1,比如说m,(这绝对是可能的,只是不是原问题所需的),那么我们将看到外生变量(X)的维度是n x k,内生变量(Y)的维度是n x m。这意味着参数矩阵Theta的大小为k x m。仍然完全合理。关键在于,为了计算平方误差和,我们需要做(X * Theta – Y)的平方和。(X * Theta – Y)的内积不再适合作为计算成本函数的手段,其性能也无关紧要。为了得到合适的结果,我们需要将(X * Theta – Y)重塑为一个维度,然后取内积。在这种情况下,我们对一个维度所做的相同分析仍然是最合适的分析。
尽管如此,我运行了以下代码:
idx = pd.Index(np.arange(1000, 501000, 1000)).sort_values()ddd = pd.DataFrame(index=idx, columns=['dot', 'dif'])def fill_ddd(row): i = row.name x = np.random.rand(i, 1) s = pd.datetime.now() for _ in range(100): x.T.dot(x) row.loc['dot'] = (pd.datetime.now() - s).total_seconds() / 100. s = pd.datetime.now() for _ in range(100): np.square(x).sum() row.loc['dif'] = (pd.datetime.now() - s).total_seconds() / 100. return rownp.random.seed([3, 1415])ddd.apply(fill_ddd, axis=1) ddd.plot()
点积是明显的赢家,并且更加一致。