《机器学习与数据挖掘》实验一
实验题目: 使用梯度下降法训练线性回归模型
实验目的: 掌握线性回归的基本原理,以及梯度下降法和最小二乘法;
实验环境(硬件和软件) Anaconda/Jupyter notebook/Pycharm
实验内容:
(1)编码实现基于梯度下降的单变量线性回归算法,包括梯度的计算与验证;
(2)画数据散点图,以及得到的直线;
(3)画梯度下降过程中损失的变化图;
(4)基于训练得到的参数,输入新的样本数据,输出预测值;
实验步骤:
1.读取所提供的数据文件并获取对应的矩阵
import numpy as np
import matplotlib.pyplot as plt
train = np.loadtxt('./data1.txt',delimiter=',',skiprows=1) #读取txt文件
train_x = train[:,0]
train_y = train[:,1]
train_x
type(train_x)
train_x.shape
2.数据散点图
plt.plot(train_x,train_y,'o')
plt.show()
3.初始化参数
theta0 = np.random.rand()
theta1 = np.random.rand()
4.写预测函数
def f(x):
return theta0 + theta1 * x
5.确定目标函数
def D(x,y):
return 0.5 * np.sum((y-f(x))**2)
6.标准化
mu = train_x.mean()
sigma = train_x.std()
def standardize(x):
return (x - mu)/sigma
train_z = standardize(train_x)
7.绘图1
plt.plot(train_z,train_y,'o')
plt.show()
8.
ETA = 1e-3 # 学习率
diff = 1 #误差的差值
count = 0 #更新的次数
error = D(train_z,train_y)
while diff > 1e-2:
tmp_theta0 = theta0 - ETA * np.sum((f(train_z)-train_y))
tmp_theta1 = theta1 - ETA * np.sum((f(train_z)-train_y)*train_z)
theta0 = tmp_theta0
theta1 = tmp_theta1
current_error = D(train_z,train_y)
diff = error - current_error
error = current_error #计算与上一次误差的差值
# 输出日志
count += 1
log = '第 {} 次 : theta0 = {:.3f}, theta1 = {:.3f}, 差值 = {:.4f}'
print(log.format(count, theta0, theta1, diff))
9. 绘图2
x = np.linspace(-1,3,100)
plt.plot(train_z,train_y,'o')
plt.plot(x,f(x))
plt.show()
10. 新的数据样本预测
实验心得:
了解到python中numpy库中的loadtxt的用法:
numpy中有两个函数可以用来读取文件,主要是txt文件,下面介绍
loadtxt, 其一般用法为
numpy.loadtxt(fname, dtype=, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)
1.fname
import numpy as np
# 首先给出最简单的loadtxt的代码,实际上就是直接写文件名, 其他关键字参数都是默认的.
a = np.loadtxt('out.txt')
print(a) # a为浮点数的原因为Python默认的数字的数据类型为双精度浮点数
2.skiprows
# 设置skiprows=2, 就会跳过前两行,数据类型设置为字符串.
a = np.loadtxt('out.txt',dtype=str,skiprows=2)
print(a)
3.comment
#这里的comment的是指, 如果行的开头为#就会跳过该行
a = np.loadtxt('out.txt',dtype=str,skiprows=1,comments='#')
print(a)
4.delimiter
import numpy as np
#参数 delimiter 可以指定各种分隔符、针对特定列的转换器函数、需要跳过的行数等
a = np.loadtxt('out.txt',dtype=str,delimiter=' ')
print(a)
5.usecols
import numpy as np
#usecols是指只使用0,2两列
a = np.loadtxt('out.txt',dtype=str,delimiter=' ',usecols=(0,2))
print(a)
6.unpack
import numpy as np
# unpack是指会把每一列当成一个向量输出, 而不是合并在一起
a = np.loadtxt('out.txt',dtype=str,delimiter=' ',unpack=True)
print(a)
b,c= np.loadtxt('out.txt',dtype=str,delimiter=' ',usecols=(0,1),unpack=True)
print(b,c)
7.converters
import numpy as np
# 介绍converters参数, 这个是对数据进行预处理的参数
#我们可以先定义一个函数, 这里的converters是一个字典, 表示第1列使用函数func来进行预处理
def func(x):
return int(x)+1
a = np.loadtxt('out1.txt',dtype=int,delimiter=' ',converters={1:func})
print(a)