学习内容:线性回归练习
学习时间:2020/9/24
教学视频、数据集等:
https://www.bilibili.com/video/BV1Xt411s7KY
代码实现:
https://github.com/boxes757/Machine-learning-exercises
学习笔记:
练习题目
- 假设你是一家餐厅的CEO,正在考虑开一家分店,根据该城市的人口数据预测其利润
(我们拥有不同城市对应的人口数据以及利润) - 假设你现在打算卖房子,想知道房子能卖多少钱?
(我们拥有房子面积和卧室数量以及房子价格之间的对应数据)
相关工具(包)
numpy(计算,处理多维数组)、pandas(数据分析)、matplotlib.pyplot(绘图框架)
参数
-
代价函数(损失函数)

注:除以2m的原因
对于计算最小的J(θ)来说,在1/m的基础上除以2并不影响结果,而在利用梯度下降法时会利用到对θ进行求导,求导过程中平方求导后可以和1/2相乘而抵消 -
梯度下降函数

读取数据
示例:data = pd.read_csv(‘01-linear regression/ex1data1.txt’, names=[‘population’,‘profit’])
注:read_csv中有多种参数,对于不同文件需要改变参数,参考下面网站
https://www.cnblogs.com/traditional/p/12514914.html
- pycharm中.head()函数不显示
pandas工具中的.head()函数作用是显示前五行的数据,而在pycharm中想要输出数据都需要使用print。所以应该写作print(xxx.head())。
注:.tail()可以查看最后五行数据,.describe()可以查看数据的一些基本情况(平均值)
数据准备
-
特征归一化:数据中的不同特征值(除了目标值的各列)可能会对目标值产生不同程度的影响。特征归一化可以使各特征值处于同一数量级,提高模型的收敛速度和精确度。
常见的有两种方式:
Z-score标准化:
z=xi−μδz=\frac{x_{i}-\mu}{\delta}z=δxi−μ其中μ和δ为对应特征的均值和标准差,量化后的特征将分布在[-1,1]
最大最小标准化:
z=xi−min(xi)max(xi)−min(xi)z=\frac{x_{i}-min(x_{i})}{max(x_{i}) - min(x_{i})}z=max(xi)−min(xi)xi−min(xi) -
对于代价函数中的X矩阵来说,第一列的1在进行矩阵乘法后,充当了方程的常数项。而在我们导入的数据中,仅有特征x1,x2,…,xn。所以我们应该对数据插入值为1的一列。
在指定列中插入数据:Dataframe.insert(loc, column, value, allow_duplicates=False)

图片来自:https://blog.csdn.net/W_weiying/article/details/85247436 -
切片处理
.iloc()函数 中括号
示例:X = data.iloc[:,0:-1] 表示需要所有行,列从0(第一列)到 -1(-1不包括,所以到倒数第二列)
Y = data.iloc[:,-1] 表示需要所有行的最后一列 -
转换dataframe为矩阵
我们导入数据后或是切片后,这些数据格式都为dataframe,在稍后计算时,需要将他们转换为矩阵格式
示例:X.values 无括号 注:可用print(X.shape)查看矩阵维数
若有如(97,)的维数(1没有显示),用Y=Y.reshape(97,1)修改并验证矩阵维数,否则会出现计算错误
代价函数表达式
J(θ)=12m∑i=1m(X⋅θ−Y)2J(\theta)=\frac{1}{2m}\sum _ { i = 1 } ^ { m}( X\cdot\theta - Y)^{2}J(θ)=2m1∑i=1m(X⋅θ−Y)2
X · θ - Y 其实是矩阵的运算,得到的是一个m×1的矩阵,每行是各个样本数据的特征值(x1,x2,…,xn)代入线性回归方程所得的值与其正确目标值(最后一列,被分割去了Y矩阵)的差值。
-
numpy.sum()
示例:np.sum(a,axis = 0) a是数组或是矩阵等
参考:https://zhuanlan.zhihu.com/p/85790648
当axis缺省时,即将数组/矩阵中的元素全部加起来
因为上述的得到m×1的矩阵,所以我们可以直接用.sum()求和矩阵各行相加的值 -
numpy中@表示矩阵相乘
X · θ → X @ θ -
θ矩阵初始化(一般给θ矩阵赋予零矩阵)
zeros(shape, dtype=float, order=‘C’)
返回来一个给定形状和类型的用0填充的数组;
shape: (m,n) 矩阵的形状
dtype:数据类型,可选参数,默认numpy.float64 -
np.power(a,b) 进行a^b运算
-
获取矩阵行数
代价函数中的1/2m,m代表矩阵行数,即样本数。
可由len(X)获取矩阵行数,也可用X.shape[0]获取行数([1]获取列数)
梯度下降表达式
θ=θ−α1mXT(X⋅θ−Y)\theta=\theta - \alpha\frac{1}{m}X^{T}(X\cdot\theta - Y)θ=θ−αm1XT(X⋅θ−Y)
定义方法:def GradientDescent(X,Y,theta,alpha,times): 此函数中不断地变更θ,再代入代价函数,将所得到的代价函数值追加进入costs(列表)中(每个值与其迭代次数可绘制图),结束后返回存储代价值变化的costs列表,以及θ。
-
创建列表存储梯度的变化值
用 costs = [] 可以创建列表
用 costs.append(cost) 可以向列表中追加cost的值(即当前代价函数的值) -
利用循环 for i in range(times) 不断地进行梯度下降
注:range(start, stop[, step])
start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1) -
对于表达式中的α,一般取较小值
注:如果α太小,梯度下降速率会很慢
如果阿尔法太大,可能导致梯度无法收敛甚至发散
可以按如下规律进行选取:0.001,0.003,0.01,0.03,0.1,0.3,1
正规方程
在线性回归中,正规方程可以看作是一种梯度下降的代替方法。
下列给出公式:
θ=(XT⋅X)−1⋅XT⋅Y\theta = (X^T \cdot X)^{-1} \cdot X^T \cdot Yθ=(XT⋅X)−1⋅XT⋅Y
通过该公式,可以直接把θ计算出来
正规方程与梯度下降法优缺点:
| 正规方程 | 梯度下降法 |
|---|---|
| 不需要选择不同α | 缺点:需要选择不同α |
| 不需要多次迭代 | 需要多次迭代 |
| 不需要特征归一化 | 需要特征归一化 |
| 缺点:当特征数量很大时,求解时间慢(O(n^3)) | 优点:特征数量很大时(>10000),也能较好地工作 |
若XT⋅XX^T \cdot XXT⋅X 不可逆,可以考虑下列情况:
- 特征中包含一些线性依赖的特征
- 样本数量≤特征数量,需要删除一些特征,或考虑使用特征归一化
绘图
fig,ax = plt.subplots() 其中ax为图的实例
… …
plt.show()
参考:https://blog.csdn.net/sinat_35930259/article/details/80002213
-
.plot()的参数

线条、坐标点样式:https://blog.csdn.net/xuxinrk/article/details/80051238 -
表示坐标的时候,用到np.arange() 注:np.arange()与range()类似,注意区分,前者用在画图中,后者多数用在循环中,且注意拼写。
示例:a = np.arange(4)
输出:[0 1 2 3]
for i in range(4):
print(i);
输出:0 1 2 3 (每步输出1个,范围从0到3)
-
可以用np.linspace分配数值,用来做坐标轴的值
示例:np.linspace(0,25,100)代表产生以0~25的100个间距相等的数 -
ax.scatter() 绘制散点图
-
ax.plot() 绘制线性图
示例:
ax.plot(np.arange(times),costs,’-’,label=‘cost’)
ax.legend() 其作用是将图像中线或点代表的东西(即将上一行的label显示出来)ax1.scatter(X[:,1],Y,label=‘training data’)
ax1.plot(x,y_,’-b’,label=‘test data’)
ax1.legend() -
ax.set()可以设置横纵轴的名字,标题的名字
示例:ax.set(xlabel=‘times’,ylabel=‘cost’,title=‘times & cost’)
结果展示
- 单变量线性回归


- 多变量线性回归
不同 α\alphaα 下迭代次数与损失函数值的关系:

总结
线性回归的主要步骤:
- 读取数据
- 数据特征归一化
- 数据加列(值为1)以及切片(后转矩阵)
- 代价函数(返回代价函数的值,初始化θ为零矩阵)
- 梯度下降函数(α取较小的值、返回存储代价值变化的costs列表,以及θ)
--线性回归练习&spm=1001.2101.3001.5002&articleId=108785386&d=1&t=3&u=1720e1d0ac2e4845b94c78391bbf2ed9)
3617

被折叠的 条评论
为什么被折叠?



