线性回归模型是机器学习中最简单的一个有监督学习模型,所谓有监督学习,就是在给出的训练数据样本中已经标定了样本的目标信息(如类别,预测值),算法模型通过学习这些数据样本,得到能较好的应用于未标定类别数据样本的模型参数。 线性回归模型根据一个样本的输入特征给出这个样本的目标值/预测值,
我们要根据房子的面积和房间数预测房子的房价,如下表
首先,给出一个初始的线性函数:
其中‘theta下标i’是该线性函数从X映射到Y的参数(或者说是权重)。我们可以将X0看作1,所以:
在等式的右边,theta和x均为向量。 定义价值函数(cost function):
其中'X上标i'表示第i组输入数据,我们用J(theta)来衡量:对于每一组theta的值,它得出的预测值和实际上的y的值的接近程度。
最小二乘法(LMS)
我们要得到一组theta值使得J(theta)能最小化,可以使用梯度下降法(gradient descent):从某个初始theta值开始,然后重复改变theta使J(theta)更小,直到收敛:
:=表示赋值,alpha是学习因子,在实际中调整。 我们先考虑只有一个训练实例时,化简:
所以得到:
这就是最小二乘法或Widrow-Hoff学习规则。 以上只是在一个训练实例的情况下,我们要考虑所有m个训练实例,有两种修改方法使之适用于一个训练集。 第一种:
这个方法每迭代一次就要遍历所有训练样例一次,这就是批量梯度下降法(batch gradient descent)。 第二种:
在这个算法中我们遍历了整个训练集,每使用一个训练样例,便仅根据这单个样例的结果修改参数。这个算法叫做随机梯度下降(stochastio gradient descent)或增量梯度下降(incremental gradient descent)。
通过以上两种方法计算出参数 之后我们便得到了最初的线性方程:
便可以根据这个方程预测出相应房屋面积和房间数的房价。
正则方程组法
在笔记一中我们用了梯度下降法来求出使价值函数 最小化的参数 的值,而使用另外一种正则方程组方法同样可以做到,而且不需要反复迭代。在这个方法中我们用价值函数J(theta)对theta求导,使之为0 。要达到这个目的,我们先介绍几个矩阵性质。
矩阵推导
我们定义函数f对矩阵A的求导为:
所以上式左边的梯度自身是一个m*n的矩阵。 再引入tr操作符,即线性代数中的“迹”。对于一个矩阵A,它的迹:
如果a是一个实数,那么tr a = a。如果AB是一个方阵,那么
以此类推:
最小二乘法回顾
python实现
在python中有很多库可以直接拿来用,这里我们用到了numpy,scikit-learn,建议各位安装anaconda,轻轻松松一下装好各种科学计算库。
import numpy as np
from sklearn import linear_model
import sklearn.preprocessing as prepro
from sklearn import cross_validation as cv
def load_data(filename):
"""read data into numpy array
return a numpy array
"""
return np.genfromtxt(open(filename, 'rb'), delimiter=',')
def split_data(X_data, y_data):
"""split the data as test_data and train_data
return X_train, X_test, y_train, y_test
"""
return cv.train_test_split(X_data, y_data, test_size=0.1, random_state=0)
def main():
data = load_data('ex1data2.txt')
X = data[:, 0:-1]
y = data[:, -1]
m = X.shape[0]
scaler = prepro.StandardScaler()
X = scaler.fit_transform(X)
X = np.insert(X, 0, values=1, axis=1)
X_train, X_test, y_train, y_test = split_data(X, y)
regr = linear_model.LinearRegression(fit_intercept=False)
regr.fit(X_train, y_train)
print("regr's coef:", regr.coef_)
print("score on test data:", regr.score(X_test, y_test))
example1 = np.array([[1650,3]])
example1 = scaler.transform(example1)
example1 = np.insert(example1, 0, values=1, axis=1)
print("Predicted price of a 1650 sq-ft, 3 br house:",regr.predict(example1))
if __name__ == "__main__":
main()
数据在这里:ex1data2.txt