1. 从零开始:为什么用线性回归预测房价是AI入门的绝佳选择
如果你对人工智能感兴趣,想动手做点东西,但又觉得那些复杂的模型和算法离自己太远,那我强烈建议你从“用线性回归预测房价”这个项目开始。这就像学编程先写“Hello World”一样,是机器学习领域的经典入门项目。我刚开始接触AI的时候,也是从这个项目上手,它帮我绕开了很多抽象的理论,直接看到了代码如何驱动模型、数据如何变成预测结果,那种亲手搭建一个“智能”系统的成就感,是看多少教程都换不来的。
为什么是房价预测呢?首先,房价是我们生活中非常熟悉的概念,它受面积、地段、房龄、学区等多种因素影响,这种“多因素决定一个结果”的逻辑,天然就是线性回归模型的用武之地。线性回归的核心思想,就是找到一条直线(或者一个超平面),来最好地拟合这些因素和房价之间的关系。你可以把它想象成,我们手头有一堆波士顿地区房屋的“体检报告”(比如犯罪率、房间数、税率等13项指标),而线性回归模型就是一个聪明的“估价师”,它通过学习历史报告和最终房价,总结出一套自己的估价公式。下次你只要输入一套新房子的13项指标,它就能根据公式给你估个价。
这个项目麻雀虽小,五脏俱全。你会完整地走一遍机器学习项目的标准流程:获取数据 -> 理解数据 -> 清洗预处理 -> 构建模型 -> 训练模型 -> 评估优化。这个过程里,你会遇到并亲手解决很多实际问题,比如数据怎么读进来、数字大小差异太大怎么办、模型怎么才算“学得好”、学得不好又该怎么调。这些经验,是你未来做更复杂的图像识别、自然语言处理项目的基础。说白了,搞定这个,你就拿到了打开机器学习大门的钥匙。
2. 数据准备:像大厨备菜一样处理你的数据集
拿到数据就直接扔给模型训练,就像不做任何处理就把食材下锅,结果很可能是一团糟。数据处理是模型成功的一半,这一步做扎实了,后面的训练会顺利很多。
2.1 获取与观察数据
我们用的经典数据集是波士顿房价数据集。虽然现在一些主流的机器学习库(如Scikit-learn)出于伦理考虑移除了它,但我们完全可以用结构类似的替代数据集,或者自己构造数据来学习原理。这里,为了完全复现过程,我们可以假设从一个文本文件(比如 housing.data)中读取数据。这个文件里,每一行代表一套房子,每一列代表一个特征,最后一列是房价(即我们要预测的目标)。
import numpy as np
import pandas as pd
# 定义特征名称,方便我们理解每一列是什么
feature_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']
# MEDV 就是我们要预测的房价中位数
# 从文件读取数据
data_path = 'housing.data'
data = np.fromfile(data_path, sep=' ') # 数据以空格分隔
feature_num = len(feature_names)
# 将读取的一维数组重塑成二维数组(样本数 x 特征数)
data = data.reshape([data.shape[0] // feature_num, feature_num])
# 用Pandas的DataFrame看一下数据长什么样,更直观
df = pd.DataFrame(data, columns=feature_names)
print(df.head()) # 查看前5行
print(df.describe()) # 查看数据的基本统计信息,如均值、标准差、最值
运行这几行代码,你就能看到数据的全貌了。df.describe() 的输出尤其重要,它会告诉你每个特征的平均值、波动范围(最小最大值)。这时你可能会发现,有的特征(比如‘TAX’房产税率)数值在几百,而有的特征(比如‘CHAS’查尔斯河虚拟变量)只有0或1。这种数量级的巨大差异,会严重影响模型的训练,我们下一步就要解决它。
2.2 数据集的划分:训练、验证与测试
我们不能用所有的数据来训练模型,否则就无法客观评价模型面对新房子时的预测能力了。通常,我们会把数据分成三份:
- 训练集:用来给模型“上课学习”,调整模型内部的参数(权重和偏置)。这部分数据量最大,通常占70%-80%。
- 验证集:用来在训练过程中“随堂测验”,检查模型学得怎么样,帮助我们调整一些“学习策略”(即超参数,如学习率)。它不参与参数更新,就像模拟考。
- 测试集:用来最终“期末考试”,在模型完全训练好后,评估其真实的、泛化的性能。这部分数据在训练过程中绝对不能被“偷看”。
一个简单且常用的划分比例是 8:1:1。下面是一个手动实现的划分示例:
# 设定随机种子,确保每次划分结果一致,便于复现
np.random.seed(2023)
# 打乱数据顺序,防止原始数据有顺序性影响
np.random.shuffle(data)
# 计算划分比例
total_num = len(data)
train_ratio, eval_ratio = 0.8, 0.1
train_num = int(total_num * train_ratio)
eval_num = int(total_num * eval_ratio)
# 划分
train_data = data[:train_num]
eval_data = data[train_num: train_num + eval_num]
test_data = data[train_num + eval_num:]
print(f"训练集样本数:{len(train_data)}, 验证集样本数:{len(eval_data)}, 测试集样本数:{len(test_data)}")
2.3 数据归一化:让所有特征站在同一起跑线
这是数据处理中最关键的一步。想象一下,你要根据“距离市中心的公里数”和“房间数量”来预测房价。距离的单位是“公里”,数值可能是10、20;房间数的单位是“个”,数值可能是3、4。模型会认为数值大的特征(距离)更重要,这显然不合理。归一化就是把所有特征都缩放到一个相近的数值区间,消除量纲影响。
方法一:Min-Max归一化(最值归一化) 这种方法把数据线性地映射到[0, 1]区间。公式是:新值 = (原值 - 最小值) / (最大值 - 最小值)。它的好处是计算简单,结果严格在0到1之间。但缺点是如果数据集中有特别大或特别小的异常值,会对结果产生很大影响。
#


1万+

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



