研究机器学习的小伙伴应该都知道,机器学习主要有两大类模型:分类和回归。这里先大概说一下分类和回归的区别与联系,方便大家对机器学习其他模型有一个宏观的认识。
分类和回归
- 联系
其实分类和回归模型本质上是一样的,它们都是通过已有数据构建(求解)一个模型
,其中x表示一个n维的特征向量,y表示经过模型的处理后得到的输出结果,而模型
的具体表达式可以是千变万化的,这里我们不展开讨论。
- 区别
分类和回归的最主要区别在于模型的输出y,回归模型的输出y是一个连续性的数值型数据;分类模型的输出y是离散的标称型数据(比如输出[0,1],类别标签),就算y值不离散,也可以想办法让y变成离散的用于分类任务(比如感知机、逻辑回归,这个后面的文章会详细的讲解)。
这是机器学习系列的第一篇文章,今天讲解一下机器学习中最简单的一个模型:线性回归。
线性回归
既然是线性回归,顾名思义就可以知道它表示输入特征x和输出结果y之间线性相关,主要作用是根据已有的数据来拟合一个线性模型,使得该线性模型最逼近真实模型。
- 数学模型
上述就是线性模型,其中x表示一个n维的特征向量,w是一个n维向量,代表x每个分量的权重。
- 线性回归思想
线性模型已经有了,那么线性回归的目的是什么呢?对于一个给定数据集{(x1,y1),(x2,y2)...(xm,ym)},假设它们同属于一个线性模型,线性回归试图根据已有的数据估计出模型的未知参数(w,b)。求解模型的未知参数总得有一个规则或者判断标准,线性回归 希望估计出的模型
模型求解
现在问题就只剩下如何求解模型的参数(w,b)了,对付这类问题,一般是设计一个评价准则(损失函数),根据该准则采用最优化方法来求解未知参数。
- 损失函数
我们希望越接近越好,但是必须用一个数值标准来量化和的差异,所以我们定义了一个损失函数
- 目标函数
评价准则(损失函数)有了,那么线性回归的目标是什么呢?最小化与的误差!目标函数如下
- 最优化方法
线性回归模型可以采用最小二乘法或梯度下降法求解,本博客使用机器学习中最常用的梯度下降法进行求解,具体原理就不在这类展开了
代码实现
def GradientDescent(X, Y, lr, iters):
'''
全局梯度下降法,每次迭代以整个数据集更新参数
根据线性回归的损失函数求得梯度G=X.T*(X*theta-Y)
:param X: (m,n+1) m个数据,每个数据n维 每个数据n维,在数据前加一列1方便计算wx+b
:param Y: (m,1) m个数据对应的输出结果
:param lr: 学习率
:param iters: 迭代次数
:return: theta: (n+1,1) 权重(b+w)
'''
sample_num = X.shape[0]
dim = X.shape[1]
theta = np.zeros((1, dim)) # (n+1,1)
XT = np.transpose(X)
for i in range(iters):
Y_ = np.dot(X, theta) # 模型预测值
gradient = np.dot(XT, Y_-Y)/sample_num # theta的梯度 (n+1,1)
# 梯度更新
theta = theta - lr*gradient
return theta
def linearRegression(data, label, lr=0.1, iters=50):
sample_num = data.shape[0]
data = np.hstack((np.ones((sample_num, 1)), data)) # 在数据前加一列1方便计算wx+b
theta = GradientDescent(data, label, lr, iters)
return theta
def predict(x, theta):
x = np.hstack((np.ones((1)), x))
pre = np.dot(x, theta)
return pre
if __name__ == '__main__':
# load data
data = np.loadtxt('data.txt', delimiter=',')
X = data[:, 0:-1]
Y = np.array(data[:, -1])
# 线性回归模型拟合
theta = linearRegression(X, Y)
# 模型测试
x_test = np.array([1650, 3])
pre = predict(x_test, theta)
print(pre)