Python实现一个简单的机器学习样例

样例来自斯坦福大学机器学习课程,其叙述如下:现有47个房子的面积和价格,需要建立一个模型对新的房价进行预测。简单来说就是:

  • 输入的数据只有一维,亦即房子的面积。
  • 目标的数据也只有一维,亦即房子的价格。
  • 需要做的,就是根据已知的房子的面积和价格的关系进行机器学习。

下面就是具体的操作步骤。

1. 获取与处理数据

原始数据集的前10个样本如下表所示

房子面积房子价格
2104399900
2400369000
3000539900
1534314900
1380212000
1600329900
1416232000
1985299900
1427198999
1494242500

查看完整的数据集可以点击这里。虽然该数据集比较简单,但可以看到其中的数字都相当大。保留它原始形式确实可能是有必要的,但一般而言,我们应该对它做简单的处理以期望降低问题的复杂度。在本例中,采取常用的将输入数据标准化的做法,其数学公式为:
X = X − X ‾ s t d ( X ) X=\frac{X-\overline{X}}{std(X)}\quad X=std(X)XX
其中 X ‾ \overline{X} X表示X(房子面积)的均值、std(X)表示X的标准差。代码实现如下:

# 导入需要用到的库
import numpy as np
import matplotlib.pyplot as plt

# 定义存储输入数据(x)和目标数据(y)的数组
x, y = [], []
# 遍历数据集,变量sample对应的正是一个个样本
for sample in open("/home/zyc/house_price/prices.txt","r"):
# 由于数据是用逗号隔开的,所以调用Python中的split方法并将逗号作为参数传入
	_x, _y = sample.split(",")
	# 将字符串数据转化为浮点数
	x.append(float(_x))
	y.append(float(_y))
# 读取完数据后,将它们转化为Numpy数组以方便进一步的处理
x, y = np.array(y)
# 标准化
x = (x - x.mean()) / x.std()
# 将原始数据以散点图的形式画出
plt.figure()
plt.scatter(x, y c="g", s=6)
plt.show()

上面这段代码的运行结果如下图所示。

预处理后的数据散点图
这里横轴是标准化后的房子面积,纵轴是房子价格。

2. 选择与训练模型

在弄好数据之后,下一步就要开始选择相应的学习方法和模型了。幸运的是,通过可视化原始数据,可以非常直观的感受到:很有可能通过线性回归中的多项式拟合来得到一个不错的结果。

# 在(-2,4)这个区间上取100个点作为画图的基础
x0 = np.linspace(-2, 4, 100)
# 利用Numpy的函数定义训练并返回多项式回归模型的函数
# deg参数代表著模型参数中的n,亦即模型中多项式的次数
# 返回的模型能够根据输入的x(默认是x0),返回相对应的预测的y
# lambda函数为匿名函数
def get_model(deg):
	return lambda input_x=x0: np.polyval(np.polyfit(x, y, deg), input_x)

3. 评估与可视化结果

模型建好之后,我们就要尝试判断各种参数下模型的好坏了。为简洁起见,我们采用n=1,4,10这三组参数进行评估。由于我们训练的目的是最小化损失函数,所以用损失函数来衡量模型的好坏似乎是一个合理的做法。

# 根据参数n、输入的x、y返回相应的损失
def get_cost(deg, input_x, input_y):
	return 0.5 * ((get_model(deg)(input_x) - input_y) ** 2).sum()
	# 定义测试参数集并根据它进行各种实验
	test_set = (1, 4, 10)
	for d in test_set:
		# 输出相应的损失
		print(get_cost(d, x, y))

所得的结果是:当n=1,4,10时,损失的头两位数字分别是96、94和75。这么看来似乎是n=1最差,这么看是看不出来了,接下来画图看一下

# 画出相应的图像
plt.scatter(x, y, c="g", s=20)
for d in test_set:
	plt.plot(x0, get_model(d)(), label="degree = {}".format(d))
# 将横轴、纵轴的范围分别限制在(-2,4)、(10^5,8*10^5)
plt.xlim(-2, 4)
plt.ylim(1e5, 8e5)
# 调用legend方法使曲线对应的label正确显示
plt.legend()
plt.show()

上面这段代码运行结果如下图所示
线性回归的可视化
其中,三条线分别代表n=1,n=4,n=10的情况。可以看出,n=4开始模型就已经开始出现过拟合现象了,到n=10的时候模型已经变得非常不合理。所以我们直接选择n=1作为模型的参数才是最好的选择。

  • 5
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值