飞道的博客

Andrew Ng Machine learning——Work(One)——Linear regression——Univerate(Based on Python 3.7)

435人阅读  评论(0)
                     Python 3.7

所用数据链接::https://pan.baidu.com/s/1YGsencu8wrilvrjuSteGZQ
提取码:c3yy

Univerate linear regression

题目:为选定创办超市地点,我们有来自多个不同城市的人口(x)和利润(y) 数据,先希望根据这些数据利用线性回归来预测利润与人口的关系,从而选择超市创办地点。

1.0 package

首先引入相应的包,以便后续使用。

import numpy as np  #处理矩阵,转换数据格式必备
import pandas as pd #读取数据,加工数据
import matplotlib.pyplot as plt #绘图
1.1 load data

读入数据,代码如下:

def load_data(path):   #定义函数,名为load_data,有一个参数path
    data=pd.read_csv(path,header=None,names=['population','profit'])  
    #读取数据,其中path为数据路径,header代表列索引,默认为0,也就是以第一行为列索引,这里关闭默认,改用后面的names为列索引
    return data ,data.head(),data.describe()
    # 返回数据,表头以及数据的统计信息

查看返回值:

data,data_head,data_describe=load_data('ex1data1.txt')
print(data_head)
print(data_describe)

1.2 visualization data

读取完数据后,最好能够将其可视化,以加深对数据的直观认识。事实上这一步虽然不是算法的核心,但个人认为对于数据分布的直观认识往往也十分重要,下面给出代码:

def visualization_data():    
#定义函数,函数名称为cisualization_data,无传入变量
    fig,ax=plt.subplots(figsize=(6,6))
# fig可以理解为创建一个画布,ax可以理解为画布中的具体内容,figsize指明画布大小为6*6
    ax.scatter(data['population'],data['profit'])
#scatter指明画图类型为散点图,其中传入参数,前两个为位置参数,按位置对应依次为散点的x坐标和y坐标,第三个参数label指明了该图的名称
    ax.set_xlabel('population')
#设置横坐标名称为 population
    ax.set_ylabel('profit')
# 设置纵坐标名称为 profit
    ax.set_title('population vs profit')
# 设置该图主题为 population vs profit
    plt.show()
# 可视化

结果如下:

看起来很舒服,继续。

1.3 data preprocessing

所谓数据预处理似乎也谈不上,只是按照要求改变以下数据罢了,代码如下:

def data_preprocessing():
# 定义函数,名为data_processing,无传入参数
    data.insert(0,'one',1)
#将之前的data,在第0列(也就是我们认知的第一列)加一列1,并将索引设置为one
#这一步是为了后续的向量化
    col=data.shape[1]
# 返回data的列数(如果方括号里是0返回的则是行数)
    x=data.iloc[:,:col-1]
#类似切片,选取data中第1到第col-1列的所有行作为x
    y=data.iloc[:,col-1:]
# 选取data中最后一列所有行作为y
    return x,y
# 返回x,y 
x,y=data_preprocessing()
#print(x)
#print(y)
x=np.array(x.values)
y=np.array(y.values)
#将x,y转换为数组形式

结果如下:

目前一切正常

1.4 define costfunction

下面该定义损失函数了,先放图:

其中:

OK,看着还是比较友善,下面给出代码:

def costfunction(x,y,theta):
# 定义函数,名为costfunction,传入三个参数:x,y,theta
    h=x@theta.T
# 计算h_{theta}(x)
    temp=np.power((h-y),2)
# 实际上这并没有什么用,只是将计算分解,降低出错。
# power 中第一个参数,表示求次方的对象,第二个参数,表示求的次方数
    J=np.sum(temp-h)/(2*len(x))
# 计算式 
    return J
# 返回J
J=costfunction(x,y,theta)
print(J)
# 观察初始代价 32.0727......

好了,接下来就是梯度下降了

1.5 gradientdescend


更迭规则如上,下面给出代码:

def gradientdescend(x,y,theta,alpha,num_iter):
# 定义函数,名为gradientdescend ,传入参数x,y,theta,alpha,num_iter
    theta_t=np.array(np.zeros(theta.shape))
# 初始化theta
    cost=np.zeros(num_iter)
# 生成一个长度为迭代次数的数组,后续记录每一次迭代后的代价函数值
    m=len(x)
    for i in range(num_iter):
# 每次迭代均执行如下操作
        theta_t=theta-(alpha/m)*(x@theta.T-y).T@x
# 梯度下降
        theta=theta_t
# 将更新后的theta赋值
        cost[i]=costfunction(x,y,theta)
# 记录每一次代价函数值
    return theta,cost
# 返回
alpha=0.01
#指明学习率
iterations=1000
#指明迭代次数
fin_theta,cost=gradientdescend(x,y,theta,alpha,iterations)
fin_cost=costfunction(x,y,fin_theta)
print('fin_cost',fin_cost)
# 查看最终的代价函数值(迭代1000此后),大约为4.51595
1.6 visualization result

核心工作已做完,接下来就是可视化结果,代码如下:

x=np.linspace(data.population.min(),data.population.max(),200)
# 就是在data中从population列中最小的值到最大的值这个区间中,选取200个点
f=fin_theta[0,0]+(fin_theta[0,1]*x)
# 计算相应的纵坐标
fig,ax=plt.subplots(figsize=(8,8))
# 创建一个画布,尺寸为8*8
ax.plot(x,f,'black',label='predition')
# 指明要画的对象横坐标为x,纵坐标为f,颜色为黑色(个人喜好黑色,总感觉看起来很高雅
ax.scatter(data['population'],data['profit'])
# 指明现在要画散点图,并且横坐标为data中的population列,纵坐标为data中的profit列
ax.set_xlabel('population')
# 设置横坐标名称
ax.set_ylabel('profit')
# 设置纵坐标名称
ax.set_title('population vs profit')
# 设置图主题
plt.show()
#显示

结果如下:

之外,我们还可以可视化损失函数,代码如下:

fig,ax=plt.subplots(figsize=(6,6))
ax.plot(np.arange(iterations),cost,'r')
ax.set_xlabel('iterations')
ax.set_ylabel('costfunction')
ax.set_title('iterations VS costfunction')
plt.show()
#代码解释同上

结果如下:

至此,已经实现了对于单特征的线性回归。建议读者在读懂代码后,自己动手写,以便加深理解。

未经允许,请勿转载。

欢迎交流。


转载:https://blog.csdn.net/PRINCE2327/article/details/105943600
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场