机器学习入门:基础知识与快速开始
之前系统学习了黄佳老师的《AI应用实战课》,对机器学习有了一个大概的认知,意犹未尽感觉还想再了解了解,于是又学习了黄佳老师的《零基础实战机器学习》,基础知识看这一篇就够了。
机器学习到底是什么?
机器学习是利用计算机的运算能力,从大量的数据中发现一个“函数”或“模型”,并通过它来模拟现实世界事物之间的关系,从而实现预测、判断等目的。
这个过程的关键之处就在于:建立一个合适的模型,并能主动地根据这个模型进行“推理”,而这个建模的过程就是机器的“学习”过程。

机器学习和传统程序有何差别?
传统程序是程序员将已知的规则定义好之后输入给机器的。
机器学习则是从已知数据中,通过不断试错、自我优化、自身总结,归纳出来规则来。
从上图可以看到,机器学习的本质特征是:从数据中发现规则。
我们也可以这样说:传统程序是程序员定义好函数,而在机器学习中是机器训练出函数。我们学过中学数学应该都知道,既然是函数,那就有自变量(x)和因变量(y)。在机器学习中,自变量叫做特征(feature),因变量叫做标签(label),而一批历史特征和一批历史标签的集合,就是机器学习的数据集(dataset)。
数据集中,最初用来训练的数据集,叫做训练集(training dataset)。而当机器训练出了一个函数,用来验证和评估的数据集呢,就叫做验证数据集(validation dataset)或 测试数据集(test dataset)。

做机器学习项目,其实就是选定一个算法,然后用数据训练机器,从而找到一组函数中最适合的那一个,形成模型。
机器学习的三种类型
根据机器学习是否有标签,可以分为三种类型:

(1)监督学习(Supervised Learning):训练数据集全部有标签
(2)无监督学习(Unsupervised Learning):训练数据集没有标签
(3)半监督学习(Semi-Supervised Learning):训练数据集有的有标签,有的没有标签监督学习目前,监督学习是应用最广泛的机器学习算法。
据标签的特点,监督学习可以分为两大类:回归 和 分类。

(1)回归问题回归问题的标签是连续的数值,比如预测房价、股市、天气情况等等。
(2)分类问题分类问题的标签是离散的数值,比如客户风险识别、病人患病诊断、人脸识别等等。
无监督学习和半监督学习
无监督学习,是为没有标签的数据而建的模型,目前它大多应用在聚类和降维等有限的场景中,往往是作为数据预处理的一个子步骤而显显身手。
半监督学习,是使用大量无标签数据和一部分有标签的数据进行建模,一般情况下是因为这类场景下获取数据标签的难度或成本很高。目前,半监督学习的落地应用还比较有限。
强化学习和深度学习
强化学习研究的目标是:智能体(Agent)如何基于环境而做出行动反映,以取得最大化的累计奖励。
NOTE:这里的智能体,我们暂且将其理解为一种机器学习模型即可。
强化学习和监督学习的差异在于:监督学习是从数据中学习,而强化学习则是从环境中给它的奖励中学习。通过反复试错、不断调整,每个训练周期后,它都变得比以前强一点,最终亿万次训练之后就非常强大了。
深度学习是一种使用深层神经网络算法的机器学习模型,它也是一种算法。它既可以应用在监督学习、无监督学习和半监督学习中,也可以应用在强化学习中。
深度学习最厉害的地方在于:它可以对非结构化的数据集进行复杂特征的自动提取,完全不需要人为干预。那么,像图形图像、自然语言处理、语音识别和视觉处理等问题,就是深度学习的常用场景。
机器学习的实战5步
一个机器学习项目的实战大概有5个步骤:

- 定义问题
- 收集数据和预处理
- 选择算法和确定模型
- 训练拟合模型
- 评估和优化模型性能
第一个机器学习项目
假设我们在一个企业的新媒体运营部,需要对公众号推广文案的运营效率进行分析,我们收集了大量的软文数据,包括点赞数、转发数和浏览量等等,如下图所示:

但是,当一个公众号文章的阅读量超过了10万之后,就不会显示它的具体阅读量了。所以针对这个问题,我们的目标是:建立一个机器学习模型,能够根据点赞数和转发数等指标,估计一篇文章的大概阅读量。
这里,我们使用Python + scikit-learn框架来实现这个案例。
(1)定义问题
因为要预估阅读量,在数据集中的四个字段都是特征,而标签就是阅读量。因此,可以看出,这是一个监督学习类型的回归问题,因为它的标签阅读量是一个连续的数值。
(2)收集数据和预处理
在这个步骤中包含了一些子步骤:数据可视化、数据清洗、特征工程、构建特征集和标签集、拆分训练集/验证集和测试集。
给收集好的数据(基于csv文件的数据集)做一下可视化:
import pandas as pd # 导入Pandas数据处理工具包 df_ads = pd.read_csv('wechat-articles-data.csv') # 读入数据 df_ads.head() # 显示前几行数据 #导入数据可视化所需要的库 import matplotlib.pyplot as plt # Matplotlib – Python画图工具库 import seaborn as sns # Seaborn – 统计学数据可视化工具库 plt.plot(df_ads['点赞数'],df_ads['浏览量'],'r.', label='Training data') # 用matplotlib.pyplot的plot方法显示散点图 plt.xlabel('点赞数') # x轴Label plt.ylabel('浏览量') # y轴Label plt.legend() # 显示图例 plt.show() # 显示绘图结果!
绘图结果如下:

可以看出,这些历史数据基本上集中在一条线附近,它的标签(阅读量)和特征值(这里是点赞数)之间,貌似存在着一种线性关系。
用一个线性函数来表示这个问题的话,它应该是:y=w1x1+w2x2+w3x3+w4x4+b
其中,y是标签值即阅读量,w1,w2,w3,w4是4个特征值如点赞数、转发量等,b是一个偏置(截距),这里我们暂且不对其深究。
与此同时,我们还可以做一些数据清洗的工作,因为数据越干净,模型的效果也就越好。例如,我们可以处理一些缺失的数据、过滤掉重复的数据、过滤掉错误的数据(如商品的销售金额如果出现负值,百分比数据出现大于1的值等等)。
下面的代码展示了批量将出现了NaN(Not a Number)的值删除掉:
df_ads = df_ads.dropna() # 把出现了NaN的数据行删掉
随后,我们还可以做特征工程,它可以有效降低特征数据集的维度,从而使得机器学习模型训练的效率越高。
例如,我们可以使用BMI指数这一个特征来替代原来的两个特征-体重和身高,进而降低特征维度。这里的这个案例相对简单,无需做特征工程。
随后,我们可以构建特征集和标签集,例如通过下面的代码来构建:
X = df_ads.drop(['浏览量'],axis=1) # 特征集,Drop掉标签相关字段 y = df_ads.浏览量 # 标签集
最后,我们还需要拆分训练集、验证集和测试集,例如我们通过80/20的比例来拆分,借助Scikit-Learn框架来实现:
#将数据集进行80%(训练集)和20%(验证集)的分割 from sklearn.model_selection import train_test_split #导入train_test_split工具 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
至此,数据预处理工作结束。
(3)选择算法和确定模型
这个案例是典型的回归问题分析,因为这里我们就选择线性回归算法来进行建模。当然,还是借助scikit-learn框架预置的线性回归算法通过下面简单的两行代码就可以创建线性模型:
from sklearn.linear_model import LinearRegression # 导入线性回归算法模型 linereg_model = LinearRegression() # 使用线性回归算法创建模型
(4)训练模型
所谓训练模型就是使用训练集中的特征变量和已知标签,通过逐渐拟合函数,确定最优的参数,最后完成模型。
在scikit-learn框架中,只需要一个简单的fit方法即可实现:
linereg_model.fit(X_train, y_train) # 用训练集数据,训练机器,拟合函数,确定内部参数
在这个过程里,fit方法的核心就是减少损失,使函数对特征到标签的模拟越来越贴切。

线性回归中所谓的拟合,其关键环节是通过梯度下降,逐步优化模型参数,使训练集误差值达到最小。

(5)模型评估和优化
完成模型的训练之后,需要对其进行评估,可能还需要对其进行优化。在常用的机器学习库如scikit-learn中都会提供常用的工具指标,比如R平方分数 或者 MSE 均方误差指标,就可以用于评估回归分析模型的优劣。
对于这个案例,我们首先需要将在训练集中训练好的模型在测试集中跑一下,看看预测结果差距有多少:
y_pred = linereg_model.predict(X_test) #预测测试集的Y值 df_ads_pred = X_test.copy() # 测试集特征数据 df_ads_pred['浏览量真值'] = y_test # 测试集标签真值 df_ads_pred['浏览量预测值'] = y_pred # 测试集标签预测值 df_ads_pred #显示数据
输出结果:

可以看出,阅读量的预测值有些还是蛮接近的。
光靠眼睛看还是太累了,直接通过scikit-learn的工具方法给出一个指标分数来评估吧:
print('当前模型的4个特征的权重分别是: ', linereg_model.coef_) print('当前模型的截距(偏置)是: ', linereg_model.intercept_) print("线性回归预测评分:", linereg_model.score(X_test, y_test)) # 评估模型
输出结果:
当前模型的4个特征的权重分别是: [ 48.08395224 34.73062229 29730.13312489 2949.62196343] 当前模型的截距(偏置)是: -127493.90606857178 线性回归预测评分: 0.7085754407718876
那么,结合之前的线性函数,我们就似乎得到了它:
y=48.08x1(点赞)+34.73x2(转发)+29730.13x3(热度)+2949.62x4(评级)−127493.91
最后,通过得到的R平方分数值0.708(0到1之间),也意味着它能达到一个还可以的预测准确度。
不过,如果模型的预测评估不太理想,那我们则需要回到第3步,要么重新选择机器学习算法,要么调整已选择模型的外部参数重新训练模型,这一些列步骤都是机器学习工程师的家常便饭。
那么,如果经过一系列迭代之后,对于训练的模型觉得很不错了,那么接下来你就可以把它部署上线,而这个上线使用的步骤则是MLOps/AIOps工程师的主要职责。例如,我们可以做一个Web网站系统,提供一个UI界面供用户输入对应的特征值即可调用训练好的模型进行预测值的预测,如下图所示:


其背后的协作流程大致如下图所示:

需要注意的是:当我们训练好一个模型后,可以将其序列化为一个标准的字节流文件,以便于我们的Web系统可以方便的调用它。这里我们可以将之前训练好的模型导出为一个model.pkl格式的字节流文件,然后将其放到Web系统的部署目录下以便其进行反序列化加载使用。
下面是一个具体的调用模型进行预测的代码示例:
import numpy as np #导入NumPy from flask import Flask, request, render_template #导入Flask相关包 import pickle #导入模块序列化包 app = Flask(__name__) model = pickle.load(open('model.pkl', 'rb')) #反序列化模型 @app.route('/') def home(): # 默认启动页面 return render_template('index.html') # 启动index.html @app.route('/predict',methods=['POST']) def predict(): # 启动预测页面 features = [int(x) for x in request.form.values()] # 输入特征 label = [np.array(features)] # 标签 prediction = model.predict(label) # 预测结果 output = round(prediction[0], 2) #输出预测结果 return render_template('index.html', #预测浏览量 prediction_text='浏览量 $ {}'.format(output) if __name__ == "__main__": # 启动程序 app.run(debug=True)
怎么样,上线系统使用机器学习模型是不是很简单!
总结
本文介绍了机器学习的基本概念,通过一个预测公众号文章阅读量的案例介绍了如何进行一个机器学习的实战步骤,最后介绍了将训练好的机器学习模型与线上系统集成起来上线使用。
相信通过这些快速开始的内容,你一定能对机器学习的项目有个初步的了解!
最后,推荐大家学习黄佳老师的课程《零基础实战机器学习》,你一定能学到更多!
参考内容
黄佳 《零基础实战机器学习》



本文介绍了机器学习的基本概念,通过一个预测公众号文章阅读量的案例介绍了如何进行一个机器学习的实战步骤,最后介绍了将训练好的机器学习模型与线上系统集成起来上线使用。相信通过这些快速开始的内容,你一定能对机器学习的项目有个初步的了解!

浙公网安备 33010602011771号