知识回顾
线性回归问题
线性回归:通过提供的多组数据,构建线性方程去来预测结果。单变量线性回归和多变量线性回归的区别在于:决定预测结果的输入特征是一个还是多个。
假设函数:算法的解决方案。输入特征通过假设函数得到预测结果。
代价函数
作用:呈现预测结果和目标结果的差距
公式:
代价函数可以简写为:
对于不同问题,根据假设函数或激活函数(后神经网络内容)不同cost函数也不同,线性回归一般即为平方误差。
梯度下降算法
目的:优化模型参数,以达到最小化损失函数的效果。
思路:选择参数集合进行模拟,找到局部最小值。具体来说,选取初始点开始,按照下降的方向进行迭代,每次迭代更新参数,使得目标函数的值逐渐减小,直到达到最小值。
核心公式:
公式求导化简后:
算法代码实现
代价函数
import numpy as np
'''
参数说明:
X:输入矩阵(行数:样本个数,列数:参数个数/特征个数)
y:输出目标(行数:样本个数,列数:回归类——1个结果)
theta:参数(1行,列数:参数个数/特征个数)
'''
def computeCost(X,y,theta):
error = np.power((X * theta.T - y), 2)
return np.sum(inner) / (2*len(X))
梯度下降算法
'''
参数说明:
alpha: 学习率
epoch: 迭代次数
m: 样本的个数 = 输入矩阵X的行数
num_Param: 参数的个数
temp_theta: 记录临时参数。初始化全0,形状与theta一致(1行,列数:参数个数/特征个数)
Theta: 记录每轮的参数集合
Cost: 记录每次训练的代价 cost[i]=第i次训练的代价函数值
相关方法说明:
matrix() 创建矩阵
zeros() 全0处理,第一个参数为其形状
shape() 用于返回numpy数组或矩阵的形状。shape[0] -- 行数;shape[1] -- 列数
计算步骤:
1.更新梯度并记录
2.记录当前参数对应的Cost
'''
def gradientDescent(X, y, theta, alpha, epoch):
m = X.shape[0]
num_Param = theta.shape[1]
temp_theta = np.matrix(np.zeros((theta.shape)))
Theta = np.matrix(np.zeros((epoch, num_Param)))
Cost = np.matrix(np.zeros((epoch, 1)))
for i in range(epoch):
temp_theta = theta - (alpha / m) * (X * theta.T - y).T * X
theta = temp_theta
Theta[i] = theta
Cost[i] = computeCost(X, y, theta)
return theta, Theta, Cost
作业练习
题目概要:提供城市利润和人口数据,利用这些数据集去预测不同人口数据所对应的利润,并绘制对应的线性模型和代价函数图。
分析: 单变量线性回归问题,人口数据 - - 输入特征,城市利润 - - 输出结果。
导入相关库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
读取数据
'''
1.读取数据
参数介绍:
path:数据路径
data:目的读取的数据
pandas库相关方法介绍:
读取数据:pd.read_csv()
查看数据:head(n) n为读取的行数,默认为5
统计数据:describe() 用来对数据集进行统计描述,包括计数、均值、标准差、最小值、25%分位数、中位数、75%分位数、最大值等。
'''
path = r'D:\code\Machine\ex1-linear regression\ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
#验证
#print(data.head())
#print(data.describe())
数据可视化
'''
2.数据可视化
Matplotlib(Python_绘图库)
plot()的参数介绍:
kind设置图标类型,scatter为散点图
x,y为坐标轴数据
figsize为打开窗口大小
title为图标标题
'''
data.plot(kind='scatter', x='Population', y='Profit', figsize=(12, 8), title='data')
plt.show()
数据处理
'''
3.数据处理
涉及方法介绍:
insert(插入目标列号,列名,插入值)
iloc[获取行,获取列] 通过行号和列号来选取数据
'''
# 增加全1的第一列方便计算
data.insert(0, 'ones', 1)
cols = data.shape[1] # 获取数据列数
# 切片获取,前几列为输入值x,最后一列为目标结果y
x = data.iloc[:, 0:cols - 1] # x是所有行,去掉最后一列
y = data.iloc[:, cols - 1:cols] # y是所有行,最后一列
#输出验证
print(x.head())
print(y.head())
# 用矩阵表示
X = np.matrix(x.values)
y = np.matrix(y.values)
theta = np.matrix(np.zeros((1, 2))) # 初始化一组参数全为0
'''
检查维度
print(X.shape) mx2
print(Y.shape) mx1
print(theta.shape) 1x2 (两个参数)
'''
m = X.shape[0] # 样本个数
num_Param = theta.shape[1] # 参数个数
代价函数
def computeCost(X, y, theta):
inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner) / (2 * len(X))
梯度下降算法
def gradientDescent(X, y, theta, alpha, epoch):
temp_theta = np.matrix(np.zeros((theta.shape)))
Theta = np.matrix(np.zeros((epoch, num_Param)))
Cost = np.matrix(np.zeros((epoch, num_Param)))
for i in range(epoch):
temp_theta = theta - (alpha / m) * (X * theta.T - y).T * X
theta = temp_theta
Theta[i] = theta
Cost[i] = computeCost(X, y, theta)
return theta, Theta, Cost
模拟并预测
#初始化
alpha = 0.01
epoch = 3800
final_theta, Theta, Cost = gradientDescent(X, y, theta, alpha, epoch)
#预测人口3500和7000对应的城市利润
y1 = (1, 3.5) * final_theta.T
print(y1)
y2 = (1, 7) * final_theta.T
print(y2)
得到两个预测利润如图:
绘制图像
'''
5.绘制线性模型和代价函数
涉及方法介绍:
linspace(start=, stop=, num=) start表示数列的起始值,stop表示数列的结束值,num表示数列的长度(默认为50)
legend()向图表中添加图例 子图1有两个图像数据,添加图例说明情况
'''
x = np.linspace(start=data.Population.min(), stop=data.Population.max(), num=100)
h = final_theta[0, 0] + final_theta[0, 1] * x
#创建一个带有两个子图的画布
figure, ax = plt.subplots(nrows=1, ncols=2)
#子图1-ax[0]-线性回归图
ax[0].plot(x, h, 'r', label='Prediciton') #第一个子图:x为横坐标,h为纵坐标,r-线条为红色,名字为Prediciton
ax[0].scatter(data.Population, data.Profit, label='Training Data') #将已有数据以散点图呈现
ax[0].legend(loc=2) #表示图例在左上角,也就是第二象限的位置。
#分别给x轴、y轴还有图像标题命名
ax[0].set_xlabel('Population')
ax[0].set_ylabel('Profit')
ax[0].set_title('Predicted Profit vs. Population Size')
#子图2-ax[1]-代价函数图
ax[1].plot(np.arange(epoch), Cost, 'r')
ax[1].set_xlabel('Iteration')
ax[1].set_ylabel('Cost')
ax[1].set_title('Error vs. Training Epoch')
plt.show()
结果图
碎碎念
多复盘多练习!!!
代码基础薄弱也要克服畏难心理。先把相关知识理解明白,再反复复盘动手练习。
参考
https://github.com/fengdu78/Coursera-ML-AndrewNg-Notes/blob/master/code/ex1-linear%20regression/ML-Exercise1.ipynb
https://blog.csdn.net/weixin_48577398/article/details/117134767