机器学习笔记【一】- 线性回归(末):统计学推导以及局部加权线性回归算法实例

本节为吴恩达教授机器学习笔记第一部分:线性回归最后一部分,包括:最小化J的统计学推导以及局部加权线性回归(含代码及一个应用例子)。

3. 统计学解释

  假设输入与目标变量有如下关系:
在这里插入图片描述
  其中 ϵ ( i ) \epsilon^{(i)} ϵ(i)是一个误差项,用于捕获没有建模的影响因素,或者是随机噪音。更进一步地,假设该项独立同分布,并且符合正态分布,则有:
在这里插入图片描述
  也就是说:
在这里插入图片描述
  这个记号表示的是给定 x ( i ) x^{(i)} x(i) θ \theta θ y ( i ) y^{(i)} y(i)的分布情况,因为 θ \theta θ不是随机变量,所以也可以写为:
在这里插入图片描述
  给定输入与参数 θ \theta θ的条件下, y y y的概率为:
在这里插入图片描述
  利用似然函数:
在这里插入图片描述
  在变量互相独立的前提下有:
在这里插入图片描述
  在给定上述概率模型的情况下,可以通过极大似然方法来选择 θ \theta θ的值,使得数据概率更高,为此,可以通过最大化极大似然函数的对数似然函数,有:
在这里插入图片描述
  可以看出,最大化对数似然函数也就是最小化
在这里插入图片描述
  至此,概率方法给出了和我们原始最小均方代价函数相同的答案。

4. 局部加权线性回归

  原始线性回归算法的过程是:
在这里插入图片描述
  局部加权线性回归则是:
在这里插入图片描述
  其中 ω ( i ) \omega ^{(i)} ω(i)是非负权重,如果权重过大,很难减小 J J J的值,如果权重很小,误差项就会很容易忽略,一个折中的选择是:
在这里插入图片描述
  可以看出距离待确定样本越远,权重越小,公式中参数 τ \tau τ为bandwidth参数,表示分布最大值到最小值变化的速度,越大,变小越快,分布的图形就越“尖锐”。
  局部加权线性回归不同于标准线性回归,其是一种无参数算法。标准线性回归中,得到参数 θ \theta θ之后的预测过程,是不需要训练数据集参与的,而局部加权线性回归则依赖于训练集,这样会导致运算量的增加,为此有KDTree方法来优化(《统计学习方法》第三章)。


  之前闲的无聊,用局部加权线性回归还跑过一个不小的数据集,如下,核心的代码很简单,但是处理数据花的时间就老长了,感兴趣可以看看数据集和全部的预处理代码,链接在此

from Preprocess import *
from numpy import *
from scipy import linalg

class Train:
    def __init__(self):
        self.prepro = PrePro()
        self.matrix_complete = self.prepro.process_train()
        self.feature_train, self.feature_test, self.label_train, self.label_test, self.traindata, self.labelVector \
            = self.prepro.generate(self.matrix_complete)

    def lwlr(self, testPoint, xArr, yArr, k):
        # xMat = np.mat(xArr)
        # yMat = np.mat(yArr).T
        xMat = xArr
        yMat = mat(yArr).T
        m = shape(xMat)[0]
        weights = mat(eye((m)))
        for j in range(m):
            diffMat = testPoint - xMat[j, :]
            diffMat = mat(diffMat)
            a = diffMat * diffMat.T / (-2.0 * k ** 2)
            weights[j, j] = math.exp(a)
        xTx = xMat.T * (weights * xMat)
        temp_d=zeros([2,2])
        temp_d[0][0]=xTx[0].tolist()[0][0]
        temp_d[0][1]=xTx[0].tolist()[0][1]
        temp_d[1][0]=xTx[1].tolist()[0][0]
        temp_d[1][1]=xTx[1].tolist()[0][1]
        xTx=temp_d
        xTx=mat(xTx)
        if linalg.det(xTx) == 0.0:
            print("This matrix is singular, cannot do inverse")
            return
        ws = xTx.I * (xMat.T * (weights * yMat))
        return testPoint * ws

    def lwlrTest(self, testArr, xArr, yArr, k=1.0):  # loops over all the data points and applies lwlr to each one
        m = shape(testArr)[0]
        yHat = zeros(m)
        for i in range(m):
            yHat[i] = self.lwlr(testArr[i], xArr, yArr, k)
        return yHat

if __name__ == '__main__':
    trainer = Train()
    temp=0
    y_hat = trainer.lwlrTest(trainer.feature_test, trainer.feature_train, trainer.label_train, k=0.3)
    for i in range(len(y_hat)):
        temp=temp+(y_hat[i]-trainer.label_test[i])**2
    score=temp/(len(y_hat))
    score=math.sqrt(score)
    print(score)
    #print(trainer.label_test,y_hat)

  另外还有一个用tensorflow写的线性回归,链接在此,代码如下:

# -*-coding:utf-8-*-
import random

import numpy as np
import tensorflow as tf
import tensorflow.contrib.eager as tfe

# 开启eager API
tfe.enable_eager_execution()

# 生成数据
num_inputs = 2
num_examples = 1000
true_w = [2, -3.4]
true_b = 4.2

tmp_list1 = [np.random.normal() for i in range(num_examples)]
tmp_list2 = [np.random.normal() for i in range(num_examples)]
features = np.vstack((tmp_list1, tmp_list2)).transpose()

labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels = labels + np.random.normal(scale=0.01)
labels = labels.reshape(1000, 1)

# 读取数据
batch_size = 10


# 每次随机读取十个数据
def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    # 样本的读取顺序是随机的。
    random.shuffle(indices)
    for i in range(0, num_examples, batch_size):
        j = np.array(indices[i: min(i + batch_size, num_examples)])
        # take 函数根据索引返回对应元素。
        yield np.hstack(
            ((features[:, 0].take(j)).reshape(-1, 1), (features[:, 1].take(j)).reshape(-1, 1))), labels.take(j)


# 权重和偏置
W = tfe.Variable(np.array([np.random.randn() for i in range(2)]).reshape(2, 1))
b = tfe.Variable(np.array(np.random.randn()))


# 线性回归公式函数(Wx + b)
def linear_regression(inputs):
    return tf.add(tf.matmul(inputs
                            , W), b)


# 均方误差函数,计算损失
def mean_square_fn(model_fn, inputs, labels):
    return tf.reduce_sum(tf.pow(model_fn(inputs) - labels, 2)) / (2 * num_examples)


# 参数
learning_rate = 0.01
display_step = 100
num_epochs_random_data = 3
num_epochs_entire_data = 3000
# 随机梯度下降法作为优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
# 计算梯度
grad = tfe.implicit_gradients(mean_square_fn)

# 优化之前,初始化损失函数
print("Initial cost= {:.5f}".format(
    mean_square_fn(linear_regression, features, labels)),
      "W=", W.numpy(), "b=", b.numpy())


# 每次选取全部数据训练
for step in range(num_epochs_entire_data):
    optimizer.apply_gradients(grad(linear_regression, features, labels))
    if (step + 1) % display_step == 0 or step == 0:
        print "Epoch:", '%d' % (step + 1), \
            "\n", "cost=", "{:.5f}".format(mean_square_fn(linear_regression, features, labels)), \
            "\n", "W=", W.numpy(), "\n", \
            "b=", b.numpy()

欢迎扫描二维码关注微信公众号 深度学习与数学   [每天获取免费的大数据、AI等相关的学习资源、经典和最新的深度学习相关的论文研读,算法和其他互联网技能的学习,概率论、线性代数等高等数学知识的回顾]
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值