Python机器学习(一):绪论
一、什么是机器学习?
生活中,人们常常会基于生活经验,来判断未知的事物,而类似地
- 机器学习是基于过去,预测未来
- 机器学习是让机器具备寻找一个函数的能力,根据该函数 f(x),输入 x,得到想要的结果 y,并将该函数运用在各种领域
- 如图所示,输入一段音频信号,得到翻译结果;输入一张图片,得到图片内容;输入一种场景,得到最优解…
(图摘自李宏毅机器学习课程)
机器学习的概念建立在人工智能之上,人类传统解决问题的方法就是找到一种函数/流程,根据函数/流程来对问题进行求解,但现实中有许多人类无法解决的问题(有些问题很难建立一种标准的函数/流程),于是,我们通过机器来寻找这种函数
二、机器学习算法分类
1.监督学习(Supervised Learning)
监督学习就是从带标签的训练数据中学习得到模型,并用模型对新样本的标签进行预测,它包含以下模型:
- 分类(Classification)
标签为有限集合,即标签的类别是有限的或离散的 应用:垃圾邮件检测;图像识别;从症状到疾病的医学诊断 - 回归(Regression)
标签为实数值,是连续的数值 应用:预测股票价格;自动导航中的加速度与方向盘角度 - 主要算法:
K-近邻算法(KNN) 贝叶斯分类器 线性回归 逻辑回归 支持向量机(SVM) 决策树和随机森林 神经网络 集成学习
2.无监督学习(Unsupervised Learning)
无监督学习就是对无标签的训练数据进行分析,发现其结构或分布规律,它包含以下模型:
- 聚类(Clustering)
将一批无标签样本划分成多个类,保证同一类之间尽量相似 应用:自然语言处理(NLP)的文本分析 - 数据降维(Dimensionality Deduction)
将n维空间中的向量映射到更低维的m维空间中 应用:数据可视化;图像压缩 - 主要算法:
聚类算法 K-均值算法(K-means) DBSCAN 分层聚类分析(HCA) 异常检测和新颖性检测 单类SVM 孤立森林 可视化和降维 主成分分析(PCA) 核主成分分析 局部线性嵌入(LLE) t-分布随机近邻嵌入(t-SNE) 关联规则学习 Apriori Eclat
3.半监督学习(Semi-Supervised Learning-SSL)
通常为数据打标签是非常耗时和昂贵的,你往往会有很多未标记的数据而很少有已标记的数据,而半监督学习算法可以处理部分已标记的数据
大多数半监督学习算法是无监督学习算法和有监督学习算法的结合,例如:深度信念网络 (DBN)
4.强化学习(Reinforcement Learning)
通过与环境的交互进行奖励学习的一系列行动,让智能体根据当前状态从与环境的交互中学习获得策略,产生行动获得奖励
- 目标:让智能体在特定环境中能采取回报最大化的行为
应用:自动驾驶
5.其他算法
- 模型选择(Model Selection)
参数和模型的比较、验证和选择 算法:网格搜索;交叉验证;度量… 应用:通过参数调优提高精度 - 预处理(Preprocessing)
特征提取和归一化 算法:预处理,特征提取… 应用:转换输入数据,如文本,用于机器学习算法
三、机器学习相关问题
1.建立机器学习模型的一般流程
1.1 Training 训练
- Function with Unknown Parameters 实例化,建立参数未知的模型
y
=
b
+
w
x
1
y = b + wx_1
y=b+wx1?,其中
x
1
x_1
x1? 为已知数据,
w
w
w 为权重,
b
b
b 为偏差 当我们向模型输入已知数据
x
1
x_1
x1? 时,模型就会输出
y
y
y,我们想让模型输出的
y
y
y 尽可能地逼近真实值
y
1
y_1
y1? 同时,我们还想让所有的数据
{
x
0
,
x
1
,
.
.
.
,
x
n
}
\{x_0, x_1, ..., x_n\}
{x0?,x1?,...,xn?} 分别输入到模型中时,相应得到的结果都接近数据的真实值
{
y
0
,
y
1
,
.
.
.
,
y
n
}
\{y_0, y_1, ..., y_n\}
{y0?,y1?,...,yn?},这样就说明建立的模型的性能为优,其中,这些数据称为训练集 但是,如何建立这个模型呢? - Define Loss from Training Data 定义模型的训练数据损失
想要得到这个模型,我们就需要确定
b
,
w
b, w
b,w 的取值,如何确定呢? 定义损失函数
L
o
s
s
=
L
(
b
,
w
)
Loss = L(b, w)
Loss=L(b,w),Loss用来衡量当一个模型采用
(
b
,
w
)
(b, w)
(b,w) 组合来建立时,模型性能的好坏 当Loss越大时,模型的性能越差;当Loss越小时,模型的性能越好 针对不同模型的Loss函数的定义会有所不同 - Optimization 最优解
我们需要找到一组
(
b
,
w
)
(b, w)
(b,w) 来建立的模型,使模型的Loss最小,则找到了最优解——即将模型的性能最优化 方法:Gradient Descent 梯度下降 在选择不同的
(
b
,
w
)
(b, w)
(b,w) 组合时,可以得到不同的Loss值,由
L
o
s
s
=
L
(
b
,
w
)
Loss = L(b, w)
Loss=L(b,w) 可以构成一张三维图,为了找到Loss最小的
(
b
,
w
)
(b, w)
(b,w) 组合,我们利用了梯度的概念:如图,在标量场中,某点的梯度是一个矢量,其大小为具有最大增长率的方向导数,其方向为增长率最大的方向,则梯度的负方向就是Loss在该点上下降最快的方向 我们沿着梯度的负方向来不断修改
(
b
,
w
)
(b, w)
(b,w) 组合,使得Loss逐渐变小,至于每次修改多少取决于该点的梯度大小或自定义大小,称为 learning rate——学习速率,据此,我们很容易找到Loss的极小值点,这种方法我们称为梯度下降法
某
点
的
梯
度
:
▽
u
=
a
b
?
u
?
b
+
a
w
?
u
?
w
某点的梯度:▽u={\bf a_b}\frac{\partial u}{\partial b}+{\bf a_w}\frac{\partial u}{\partial w}
某点的梯度:▽u=ab??b?u?+aw??w?u? 梯度下降法可能会陷入局部最优解,即Loss的局部最小值,而我们需要找到全局最小值,此时的
(
b
,
w
)
(b, w)
(b,w) 组合才能使Loss最小,使模型达到最优性能,不过,局部最优解其实是个假问题,在机器学习中,我们需要面对的难题并非局部最优解
1.2 testing 测试
一般我们会将所拥有的数据分为:
75
%
75\%
75% 的训练集和
25
%
25\%
25% 的测试集,前者用于训练,而后者则用于测试模型的性能
如果模型对数据的预测性能不足,则称为欠拟合;如果模型在训练集上表现很好,而在测试集中表现不佳,则称为过拟合
泛化性: 模型对任意集合的预测效果都很好,则称为泛化性强
2.机器学习的主要挑战
- 训练数据的数量不足
- 训练数据不具代表性,如:数据冗余、数据噪声
- 低质量数据
- 无关特征
- 欠拟合训练数据
模型无法抓住数据的全部特征和规律 - 过拟合训练数据
模型对现有信息量来说过于复杂,导致模型在训练集上表现很好,而在实际测试时表现很差(泛化精度低) - 等…
四、软件环境
1.软件平台
我们将使用 Anaconda 进行包管理,在 Jupyter Lab 上进行代码编写
2.所需的Python库
import pandas as pd
import numpy as np
import sklearn
import matplotlib as mlp
import scipy
import graphviz
其中,前五个库是 Anaconda 自带的,而 graphviz 需要安装,这个库可以帮助我们绘制决策树
在这之前,为了加快下载的速度,我们需要为 Anaconda 换源,更换为国内的镜像源
在 cmd 窗口中输入以下指令即可换源成功,这里更换为清华大学镜像源
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes
接着,还要修改一下生成的.condarc文件,防止更新再次使用默认的国外源,输入以下指令:
conda config --show-sources
出来的第一行就是配置文件的位置 使用记事本打开该配置文件,将 - defaults 删掉即可 为了使 Anaconda 保持较新的版本,我们需要更新一下 Anaconda,打开 Anaconda Prompt 终端 依次执行下面命令(这里是对 base 虚拟环境进行更新):
conda update conda
conda update anaconda
使用 conda 安装 graphviz 库
conda install graphviz
conda install python-graphviz
安装好后,输入以下命令查看 graphviz 的版本
dot -version
显示以下信息即下载成功 此时, Jupyter Lab 还不能导入 graphviz,还需要用 pip 安装 graphviz:
pip install graphviz
最后,尝试在 Jupyter Lab 上导入 graphviz,并查看版本
五、熟悉sklearn库
1.sklearn自带的数据集
import sklearn.datasets
在 JupyterLab 中导入 sklearn.datasets 包,并对 load 使用 Tab 键,发现sklearn自带了大量可供使用的数据集 我们可以进入sklearn的中文社区,查看这些数据集的详细信息:scikit-learn中文社区:查找关键词【sklearn.datasets.load…】
这里就sklearn中文社区列出了一些数据集的解释,方便调用:
方法 | 功能 |
---|
sklearn.datasets.load_boston | 加载并返回波士顿房价数据集(回归) | sklearn.datasets.load_breast_cancer | 加载并返回乳腺癌数据集(分类) | sklearn.datasets.load_diabetes | 加载并返回糖尿病数据集(回归) | sklearn.datasets.load_digits | 加载并返回数字数据集,每个数据点都是一个8x8的数字图像(分类) | sklearn.datasets.load_files | 加载带有类别作为子文件夹名称的文本文件 | sklearn.datasets.load_iris | 加载并返回鸢尾花数据集(多分类) | sklearn.datasets.load_linnerud | 加载并返回linnerud物理锻炼数据集(多输出回归任务) | sklearn.datasets.load_wine | 加载并返回葡萄酒数据集(分类) |
例如: 我们以导入 load_wine 葡萄酒数据集为例
这里只能截取一部分
可以看到其包含了大量的数据,其中标签为
{
0
、
1
、
2
}
\{0、1、2\}
{0、1、2},显然这是一个三分类数据集 其中数据 data 为
178
×
13
178\times13
178×13 的数组 我们查看一下葡萄酒数据集的属性/特征名:
翻译过来就是:
feature_name = ['酒精', '苹果酸', '灰', '灰的碱性', '镁',
'总酚', '类黄酮', '非黄烷类酚类', '花青素',
'颜色强度', '色调', 'od280/od315稀释葡萄酒', '脯氨酸']
查看分类标签的名字,指定了很简单的三个名字 实际上,它们分别是:
target_names = ["琴酒", "雪莉", "贝尔摩德"]
2.划分数据集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(X, y,**options)
随机将数据集按指定比例划分为训练集和测试集 X, y 分别位数据集 (data) 和标签 (target) ,允许输入 列表、numpy数组、稀疏矩阵、DataFrame test_size 、train_size 如果为 [0.0, 1.0] 之间的 float 类型,则表示 测试集或训练集 占原数据集的百分比 如果为 int 类型,则表示数据集中要划分为 测试集或训练集 的数量 如果其一为 None,则分别表示为对方的补集;若两个都为 None,则按 0.75 和 0.25 分配训练集和测试集 random_state 随机数种子,int 类型 X_train, X_test, y_train, y_test 返回值:训练集数据,测试集数据,训练集标签,测试集标签
例如: 导入 load_wine 葡萄酒数据集,并划分
import pandas as pd
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
wine = load_wine()
X_train, X_test, y_train, y_test = train_test_split(wine.data, wine.target, test_size=0.3)
print("wine.data.shape:{}, X_train.shape:{}, X_test.shape{}".format(wine.data.shape, X_train.shape, X_test.shape))
输出结果:
|