线性回归LinearRegression的Numpy实现

线性回归LinearRegression的Numpy实现

Basic

本文是对Andrew Ng的Machine Learning课程里编程作业的一个numpy实现。

Hypothesis 定义为 h θ ( X ) = X θ h_\theta (X) = X\theta hθ(X)=Xθ

一元线性回归的例子: h θ ( X ) = X θ = θ 0 + θ 1 x 1 h_\theta (X) = X\theta = \theta_0 + \theta_1x_1 hθ(X)=Xθ=θ0+θ1x1, 其中 θ = ( θ 0 , θ 1 ) T , X = ( 1 , x 1 ) \theta = (\theta_0, \theta_1)^T, X = (1, x_1) θ=(θ0,θ1)T,X=(1,x1)

损失函数 Cost Function

J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(θ)= \frac{1}{2m}\sum_{i=1}^{m} (h_\theta(x^{(i)}) -y^{(i)})^2 J(θ)=2m1i=1m(hθ(x(i))y(i))2 ,其中m为训练数据的个数。
因为使用Numpy实现,我们可以使用更为效率的向量化表示方法: J ( θ ) = 1 2 m ( X θ − y ) T ( X θ − y ) J(θ)= \frac{1}{2m} (X\theta - y)^T(X\theta - y) J(θ)=2m1(Xθy)T(Xθy),其中X的第i行就是表示第i个数据,而y则是对应的真实的值。


def compute_cost(X, y, theta):

    Hx = np.dot(X, theta)

return np.dot((Hx - y).transpose(), Hx - y) / (2 * X.shape[0])

梯度下降 Batch Gradient Descent

使用梯度下降算法更新theta的值,以最小化损失函数,在每一次迭代中都同步更新theta向量里的每一个元素,公式如下:

def gradient_descent(X, y, theta, learning_rate, iteration):

    cost_his = np.zeros((iteration, 1))

    cost_his[0] = compute_cost(X, y, theta)

    for i in range(1,iteration):

        Hx = np.dot(X, theta)

        theta = theta - (learning_rate / X.shape[0]) * (np.dot((Hx - y).transpose(), X)).transpose()

        cost_his[i] = compute_cost(X, y, theta)

    return theta, cost_his

其中 alpha 是 learning rate, 即学习率,控制每次梯度下降的大小, 若learning rate太小,则时间消耗太大,若learning rate太大,则梯度下降很有可能没有效果,损失函数可能越来越大,适得其反。

当然,我们在每一次迭代中也使用向量化的方法,公式可表示为: θ : = θ − α 1 m ( ( X θ − y ) T X ) T \theta := \theta - \alpha\frac{1}{m} ((X\theta - y)^TX)^T θ:=θαm1((Xθy)TX)T

特征标准化 Feature Normalization

因为每一个数据样本的特征数值的尺度可能会有很大的差别,例如某个特征数值的范围在[1, 10], 而另一个特征数值的范围在[10000, 100000],若不进行标准化,使用梯度下降时的效果就不佳,若是特征数值都相差无几,可用可不用。

通常用于 特征标准化的途径有两种, 一种叫做 min max normalization, 他会将所有特征数据按比例缩放到0-1的这个取值区间。 有时也可以是-1到1的区间. 还有一种叫做 standard deviation normalization, 他会将所有特征数据缩放成 平均值为0, 方差为1。
在这里我使用standard deviation normalization: X n o r m = X − X m e a n X s t d X_{norm} = \frac{X-X_{mean}}{X_{std}} Xnorm=XstdXXmean


def feature_normalize(X):

    mean = np.mean(X, axis=0, keepdims=True)

    std = np.std(X, axis=0, keepdims=True)

    X_norm = (X - mean) / std

    return X_norm

暴力求解 Normal Equation

在课上Ng一笔带过了Normal Equation, θ = ( X T X ) − 1 X T y \theta = (X^TX)^{-1}X^Ty θ=(XTX)1XTy

这是线性回归的closed-form solution。使用这个解法,不需要特征标准化,而且也无需迭代,一次就搞定。但是X仍然需要加一列全为一的列向量作为截距。


def normal_equation(X,y):

    a = np.dot(X.transpose(), X)

    b = np.dot(X.transpose(), y)

    return np.dot(np.linalg.inv(a), b)

你可能感兴趣的:(机器学习,机器学习,线性回归,numpy)