写在开头
虽然作为网安专业学生之一,但是面对着 AI 兴起的时代大势,不学点相关知识未免显得自己闭门造车了。由于之前已经学习过了机器学习和人工智能 的相关理论知识(详情可以见我的其他帖子),所以这篇文章主要是跟着 Kaggle 上的课程把相关的理论知识落地成为代码,可能也有一些我个人学习时解决的问题和思考。好的,闲话到此结束,接下来我们开始吧🥰。
Intro to Machine Learning
这个部分的课程是对机器学习的初步探索,前置知识也很简单,了解 python 的基本语法就行。这里我们做的是回归任务,我们希望通过对已有的墨尔本房屋价格及其相关特征训练出一个模型,进而使得这个模型在面对新的房屋特征时,也能较好的预测出价格。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import pandas as pdfrom sklearn.tree import DecisionTreeRegressor file_path = "./melb_data.csv" data = pd.read_csv(file_path) data = data.dropna(axis=0 ) y = data.Price data_features = ['Rooms' , 'Bathroom' , 'Landsize' , 'BuildingArea' , 'YearBuilt' , 'Lattitude' , 'Longtitude' ] x = data[data_features] model = DecisionTreeRegressor(random_state=1 ) model.fit(x, y)print ("Making predictions for the following 5 houses:" )print (x.head())print ("The predictions are" )print (model.predict(x.head()))
pandas 是用来处理表格数据的库,我们从文件中提取价格数据将其作为我们的预测目标,也就是 $y$ ,我们选取一部分指标作为特征向量作为 $x$ 。因为 sklearn 库中的模型训练大部分只支持数值输入,所以我们需要对字符串的数据做编码处理。因此,我们现在的特征尽可能选取数值型的特征。确定了特征和预测目标后,我们就可以开始训练了,训练中的 random_state 是训练的内部状态,状态一致可以确保训练出来的模型一致,从而确保我得到的结果是可以稳定复现的。
训练之后,我们可以打印前五行数据,并对其做一个简单预测。然后你会发现,准确率特别高,几乎是一致的。那这毕竟只是前五个数据,所以我们需要一个指标评估模型在整体上的预测效果。
1 2 3 4 5 predicted_home_prices = model.predict(x)from sklearn.metrics import mean_absolute_errorprint (mean_absolute_error(y, predicted_home_prices))
因此,我们选择了平均绝对误差(MAE)来评估模型好坏,其定义如下:
$$
MAE = \frac{1}{n}\sum_{i=1}^n\left|y_i-\hat{y}_i\right|
$$
其中, $n$ 为样本总数,$y_i$ 是对应样本的真实值,$\hat y_i$ 是对应样本的预测值,为了让误差能够累积,我们采用绝对值。运行后,我们发现我们的模型效果很好啊,只有 400 左右,意味着 百万左右的房子,我们的预测偏差只有 400 左右 。
但是,实际上我们的模型效果真的有这么好吗?🤔🤔🤔
如果我们还记得机器学习的相关理论就会知道:这个时候模型往往是陷入了过拟合,即模型直接开始死记硬背训练集的数据特征,那我们的预测效果就会很好了。为了解决这个问题,我们需要将数据集划分为训练集和验证集 ,在训练集上训练模型,在验证集上验证模型的泛化能力。
1 2 3 4 5 6 7 8 9 10 11 from sklearn.model_selection import train_test_split train_x, test_x, train_y, test_y = train_test_split(x, y, random_state=0 ) model = DecisionTreeRegressor(random_state=0 ) model.fit(train_x, train_y) predicted_home_prices = model.predict(test_x)from sklearn.metrics import mean_absolute_errorprint (mean_absolute_error(test_y, predicted_home_prices))
现在,让我们再次运行代码,看一看我们的模型效果究竟如何?结果看起来并不好,误差到了 260000 左右。为了让模型的效果更好,我们调整决策树回归模型 的叶子节点参数,找出过拟合和欠拟合的平衡点 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from tqdm import trangedef find_best (leaf_nodes, train_x, train_y, test_x, test_y ): model = DecisionTreeRegressor(max_leaf_nodes=leaf_nodes, random_state=0 ) model.fit(train_x, train_y) predicted_home_prices = model.predict(test_x) return mean_absolute_error(test_y, predicted_home_prices) best_mae = 10000000 best_leaf_nodes = 0 for nodes in trange(5 , 1000 ): mae = find_best(nodes, train_x, train_y, test_x, test_y) if mae < best_mae : best_mae = mae best_leaf_nodes = nodesprint ("Best leaf nodes:" , best_leaf_nodes)print ("Best Mean Absolute Error:" , best_mae)
这下我们的误差降到了 240000 左右,emm,看得出来,使用决策树模型的学习结果并不好。所以我们考虑使用随机森林 进行机器学习,进而获得更好的预测结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import pandas as pdfrom sklearn.ensemble import RandomForestRegressorfrom sklearn.metrics import mean_absolute_errorfrom sklearn.model_selection import train_test_split file_path = "./melb_data.csv" data = pd.read_csv(file_path) data = data.dropna(axis=0 ) y = data.Price data_features = ['Rooms' , 'Bathroom' , 'Landsize' , 'BuildingArea' , 'YearBuilt' , 'Lattitude' , 'Longtitude' ] x = data[data_features] train_x, test_x, train_y, test_y = train_test_split(x, y, random_state=0 ) new_model = RandomForestRegressor(random_state=0 ) new_model.fit(train_x, train_y) new_predicted_home_prices = new_model.predict(test_x)print (mean_absolute_error(test_y, new_predicted_home_prices))
运行之后,效果还不错,误差优化到 190000 左右,针对随机森林我们也可以尝试参数优化,让模型的效果更好。
Kaggle 的 Intro to Machine Learning 部分介绍到此就结束了,看起来,入门机器学习也并非困难,我们拥有了一个良好的开头。
文章中涉及到的代码和数据文件均可在我的 Github 仓库中找到,感谢你的阅读。🥰🥰🥰