【001】Python实现,单一变量的线性回归问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/shipsail/article/details/89304413

在下自我介绍

本文讲述 单一变量的直线回归!!!!!!

Hello,你们可以叫我弛仔,这算是人生中第一篇正式的分享博客。我呢是大一的学生,对机器学习(Machine Learning)感兴趣。
hhh,也是刚刚接触这方面的学习,想在这里分享初学者的经验,并且给出一些踩过的坑。

还有,我不是大佬哈!!!欢迎各位跟我一起学习!!!
在这里插入图片描述
最终的回归结果!

一些概念

拟合是什么?

在我看来,拟合就是把平面上一系列的点,用一条光滑的曲线连接起来。

因为点很复杂,我们可以用各种函数去组合来达到我们的目的。

泛化能力是什么?

训练集在训练后,能够预测位置数据的能力。

简单的了解下即可。

过拟合是什么?

过拟合,可能我们选择模型时过于复杂,在训练时表现极好,实战却不行了~

欠拟合是什么?

与过拟合相反,即训练时的效果就不佳~那就更不要说实战拉!

线性回归

假设函数(hypothesis)

假设函数(Hypothesis),这个函数可以是简单的直线,也可以是复杂的多项式组合。(我认为他就是数学模型,可能不对,若有出入望指正)

代价函数(cost function)

在这里插入图片描述
我的图应该很形象的解释了他的意义了吧?我们可以由此计算出所有点的预测值y 与 假设函数h(x)的差,通过平方(平方是为了化负为正)后取均值再除以2,吴恩达老师的课程上就是这么讲哒,通常下除以2,为了能更进一步的将代价最小化吧??

线性回归目标(Goal)

我们的目标:为了让预测值与函数值的误差最小化

即 minimizeJ(theta)

所以引入了梯度下降(Gradient Descent)

梯度下降也可以简单理解,多维也使很好理解的,我先再次梳理下最基础的梯度下降
在这里插入图片描述
这只是举了个例子,对J函数求导后,我们发现局部上,导数永远指向最小值处。
所以有了梯度下降的公式:
在这里插入图片描述
这需要用到高数中的偏导知识,如果你已经学过导数,那么偏导也是很简单的~
具体推导过程,可以自己动手算一算!

上代码

import sklearn as sk
"""
单变量的线性回归基础
单变量:一个特征哈!!!
"""


from sklearn.datasets import load_boston
import numpy as np

#输出数据的结构
def print_data(data):
    print("Shape:",data.shape,"\n")
    print("Feature:",data['feature_names'], "\n")
    print("Keys:",data.keys(), "\n")

"""
#   计算CostFunction 代价函数
#   X为特征矩阵
#   y为目标
#   theta为theta系数 1 X n 的矩阵
"""
def computerCost(X ,y ,theta):
    num = len(y)
    y = y.reshape(num,1)
    result = np.power((X.dot(theta.transpose()) - y),2)
    return np.sum(result) /(2* num)


"""
    梯度下降函数
#   Param X train Feature
#   Param y train Target
#   Param theta h(x)=theta(0)+theta(1)*x1
#   Param times 迭代的次数
"""
def gridientDescent(X,y,theta,times,learn_rate):
    number = len(y) #获取训练数据的数量
    X[:,1] = X[:,1]/100 #特征缩放
    temp = np.zeros(theta.shape) #用于更新theta
    cost = np.zeros(times) #记录每次迭代后代价函数的值
    paramters = len(theta[0]) #参数的个数

    for i in range(times):
        y = y.reshape(number,1)
        H = X.dot(theta.transpose())
        E = H - y
        #print("Y SHAPE:",y.shape)
        #print("H SHAPE:",H.shape)
        #print("E SHAPE:",E.shape)
        for j in range(paramters):#更新theta
            XT = X.transpose()
            XT = XT[j,:]
            XT = XT.reshape(1,len(XT))
            #print("XT",XT.shape)
            term = XT.dot(E)
            temp[0, j] = theta[0, j] - ((1 / number) * learn_rate * term)

        theta = temp
        print(computerCost(X,y,theta))
    return theta


if __name__ == '__main__':
    """
        准备好了吗?我们开始操作咯!
    #   首先获取我们的数据
    """
    Boston = load_boston()
    BostonData = Boston.data ##特征数据
    BostonTarget = Boston.target ##房价
    BostonFeatureName = Boston.feature_names
    print(BostonFeatureName)
    """我们使用AGE 这个特征做本次的单特征回归"""
    BostonAge = BostonData[:10,6]
    BostonAgeTarget = BostonTarget[:10]
    print('TARGET SHAPE :',BostonAgeTarget.shape)
    print("DATA SHAPE:",BostonAge.shape)
    """发现一共有506条数据,我们获取其中前10行"""
    print("DATA:\n",BostonAge)




    #给X加入一列,因为theta0 是一个常数项
    X = np.column_stack((np.ones(len(BostonAgeTarget)),BostonAge))
    theta = np.array([[0,0]]) #参数矩阵
    times  = 100000 #迭代次数
    step = 0.02 #步长
    g = gridientDescent(X,BostonAgeTarget,theta,times,step)

    """将数据可视化"""
    import matplotlib.pyplot as plt

    font = {
    'family': 'SimHei',
    'weight': 'bold',
    'size': '10'
    }
    plt.rc('font', **font)
    plt.rc('axes', unicode_minus=False)
    plt.xlabel("Feature Age")
    plt.ylabel("House Price")
    plt.title("Boston Price Data By Age")
    plt.scatter(x=BostonAge,
                y=BostonAgeTarget,
                c='b',
                alpha=.8,
                label='训练数据')

    #画出拟合直线
    x = np.linspace(BostonAge.min(), BostonAge.max(), 100)
    f = g[0, 0] + (g[0, 1] * x /100) #注意除以100,因为我们做过特征缩放
    plt.plot(x, f, 'r', label='预测函数')
    plt.legend(loc=2)
    plt.show()


编码中遇到的坑

  1. 为了每一步都简介明了,代码中加入了很多不必要的中间变量,真正实践的时候不需要这么复杂哦~
  2. 矩阵的shape,比如读入target y 后,他的shape 是一维的,但是矩阵是二维的,所以会出现无法做运算。
  3. 尽量输出Shape,通过矩阵运算法则 ,这样可以更快的找到编码可能出错的位置
  4. 矩阵运算的乘法 * 和 np.dot() 是不同的
  5. 最后矩阵的求解:这是矩阵哦!!大家用学过的线性代数推导一下就明白拉(提示:由见到推复杂,由一个元素推整个矩阵)
    在这里插入图片描述

感谢

谢谢大家看完~继续钻研吧!

猜你喜欢

转载自blog.csdn.net/shipsail/article/details/89304413