机器学习-day03
一、概述
1.什么是机器学习
机器学习是一门能够让编程计算机从数据中学习的计算机科学。
一个计算机程序在完成任务T之后,获得经验E,其表现效果为P,如果任务T的性能表现,也就是用以衡量的P,随着E增加而增加,那么这样计算机程序就被称为机器学习系统。
自我完善,自我增进,自我适应。
2.为什么需要机器学习
1)自动化的升级和维护
2)解决那些算法过于复杂甚至跟本就没有已知算法的问题
3)在机器学习的过程中协助人类获得对事物的洞见
3.机器学习的形式
1)建模问题
所谓机器学习,在形式上可近似等同于,在数据对象中通过统计或推理的方法,寻找一个接受特定输入X,并给出预期输出Y的功能函数f,即Y=f(X)。
2)评估问题
针对已知的输入,函数给出的输出(预测值)与实际输出(目标值)之间存在一定的误差,因此需要构建一个评估体系,根据误差的大小判定函数的优劣。
3)优化问题
学习的核心在于改善性能,通过数据对算法的反复锤炼,不断提升函数预测的准确性,直至获得能够满足实际需求的最优解,这个过程就是机器学习。
4.机器学习的种类
1)有监督学习、无监督学习、半监督学习、强化学习
有监督学习:用已知输出评估模型的性能。
无监督学习:在没有已知输出的情况下,仅仅根据输入信息的相关性,进行类别的划分。
半监督学习:先通过无监督学习划分类别,再根据人工标记通过有监督学习预测输出。
强化学习:通过对不同决策结果的奖励和惩罚,使机器学习系统在经过足够长时间的训练以后,越来越倾向于给出接近期望结果的输出。
2)批量学习和增量学习
批量学习:将学习的过程和应用的过程截然分开,用全部的训练数据训练模型,然后再在应用场景中实现预测,当预测结果不够理想时,重新回到学习过程,如此循环。
增量学习:将学习的过程和应用的过程统一起来,在应用的同时以增量的方式,不断学习新的内容,边训练边预测。
3)基于实例的学习和基于模型的学习
基于实例的学习:根据以往的经验,寻找与待预测输入最接近的样本,以其输出作为预测结果。
年龄 学历 经验 性别 -> 月薪
20 本科 3 男 8000
25 硕士 2 女 10000
…
20 本科 3 男 ?
基于模型的学习:根据以往的经验,建立用于联系输出和输入的某种数学模型,讲待预测输入代入该模型,预测其结果。
输入 -> 输出
1 2
2 4
3 6 Y = 2 * X
4 8
…
9 ? -> 18
5.机器学习的一般过程
1)数据收集 \ 数据处理
2)数据清洗 / 数据检索、数据挖掘、爬虫 …
3)选择模型(算法)
4)训练模型 | 机器学习
5)评估模型 | 工具、框架、算法知识
6)测试模型 /
7)应用模型 \ 业务运维
8)维护模型 /
6.机器学习的典型应用
股价预测、推荐引擎、自然语言识别、语音识别、
语音合成、图像识别、人脸识别
7.机器学习的基本问题
1)回归问题:根据已知的输入和输出寻找某种性能最佳的模型,将未知输出的输入代入模型,得到连续的输出。
2)分类问题:根据已知的输入和输出寻找某种性能最佳的模型,将未知输出的输入代入模型,得到离散的输出。
3)聚类问题:根据已知输入的相似程度,将其划分为不同的群落。
4)降维问题:在性能损失尽可能小的前提下,降低数据的复杂度。
二、数据预处理
sklearn
scikit-learn
解决机器学习问题的科学计算工具包
输入数据->模型->输出数据
样本矩阵
年龄 学历 经验 性别 -> 月薪
20 本科 3 男 8000
1.均值移除(标准化)
让样本矩阵中的每一列的平均值为0,标准差为1。
a b c
m=(a+b+c)/3
a’ = a-m
b’ = b-m
c’ = c-m
(a’+b’+c’)/3 = ((a+b+c)-3m)/3 = 0
s = sqrt(((a-m)2+(b-m)2+(c-m)^2)/3)
a" = a’/s
b" = b’/s
c" = c’/s
s" = sqrt(((a’/s)2+(b’/s)2+(c’/s)^2)/3)
= sqrt((a’2+b’2+c’2)/(3*s2))
= 1
import sklearn.preprocessing as sp
sp.scale(原始样本矩阵)->均值移除预处理后的样本矩阵
代码:std.py
2.范围缩放
将样本矩阵中的每一列的最小值和最大值设定为相同的区间,统一各列特征值的范围。
[0, 1]
a b c -> min = b
a’ b’ c’ -> min’=0
a’ = a-b
b’ = b-b
c’ = c-b
max = c’
a" = a’/c’
b" = b’/c’
c" = c’/c’
max = 1
[MIN, MAX]
kx+b=y
kmin+b=MIN
kmax+b=MAX
mms = sp.MinMaxScaler(feature_range=(0, 1))
mms.fit_transform(原始样本矩阵)
->范围缩放预处理后的样本矩阵
代码:mms.py
3.归一化
Python Java PHP
2017 10 20 5
2018 8 5 0
用每个样本的每个特征值除以该样本各个特征值绝对值的总和。变换后的样本矩阵,每个样本的特征值绝对值之和为1。
sp.normalize(原始样本矩阵, norm=‘l1’)
->归一化预处理后的样本矩阵
l1 - l1范数,向量中个元素绝对值之和
l2 - l2范数,向量中个元素平方之和
代码:nor.py
4.二值化
根据一个事先给定的阈值,用0和1表示特征值不高于或高于阈值。
bin = sp.Binarizer(threshold=阈值)
bin.transform(原始样本矩阵)
->二值化预处理后的样本矩阵
代码:bin.py
5.独热编码
根据一个特征中值的个数建立一个由一个1和若干个0组成的序列,用该序列对所有的特征值进行编码。
1 3 2
7 5 4
1 8 6
7 3 9
1-10 3-100 2-1000
7-01 5-010 4-0100
8-001 6-0010
9-0001
101001000
010100100
100010010
011000001
ohe = sp.OneHotEncoder(
sparse=是否采用紧缩格式, dtype=数据类型)
ohe.fit_transform(原始样本矩阵)
->独热编码处理后的样本矩阵
代码:ohe.py
6.标签编码
根据字符串形式的特征值在特征序列中的位置,为其指定一个数字标签,用于提供给基于数值算法的学习模型。
lbe = sp.LabelEncoder()
lbe.fit_transform(原始样本矩阵)
->标签编码处理后的样本矩阵
代码:lab.py
high medium low
4 3 2
三、线性回归
y = f(x)
输出 输入
输入->输出
0.5 5.0
0.6 5.5
0.8 6.0
1.1 6.8
1.4 7.0
预测函数:y = w0+w1x
x: 输入
y: 输出
w0和w1: 模型参数
所谓模型训练,就是根据已知的x和y,找到最佳的模型参数w0和w1,尽可能精确地描述出输入和输出的关系。
5.0 = w0 + w1x0.5
5.5 = w0 + w1x0.6
单样本误差:w0 + w1x -> 1/2(y’ - y)^2
总样本误差:1/2SIGMA((y’ - y)^2)
损失函数:loss = 1/2SIGMA(((w0 + w1x) - y)^2)
损失函数就是总样本误差关于模型参数的函数。
w0/w1? -> loss->min
w0 = w0 + dw0
w1 = w1 + dw1
dw0 = -nDloss/Dw0
dw1 = -nDloss/Dw1
loss = 1/2*SIGMA((y - y’)^2), y’=w0+w1x
Dloss/Dw0 = SIGMA((y - y’)(-1))=-SIGMA(y - y’)
Dloss/Dw1 = SIGMA((y - y’)(-x))=-SIGMA((y - y’)x)
w0 \ y’=w0+w1x / Dloss/Dw0 -> dw0 -> w0
w1 / -------------->y’ \ Dloss/Dw1 -> dw1 -> w1
^ |
|_________________________|
批量梯度下降
代码:bgd.py
import sklearn.linear_model as lm # 线性模型
model = lm.LinearRegression() # 线性回归器
model.fit(训练输入, 训练输出) # 训练模型
model.predict(待预测输入)->预测输出
代码:line.py
模型的保存和加载
import pickle
pickle.dump(模型对象, 文件对象) # 保存
|^
模型对象 = pickle.load(文件对象) # 加载
^|
代码:dump.py、load.py
四、岭回归
1.线性回归的主要问题是对异常样本过于敏感。在实际项目的数据收集过程中,经常会遇到错误的度量的结果。线性回归使用普通的损失函数优化策略,其目标是最小化损失值,因此错误样本对回归模型的影响与正确样本的影响几乎相等,从而降低了回归模型对大多数正确样本的拟合精度。
2.岭回归试图为不同的样本分配不同的权重。占多数席位的正确样本会被分配较高的权重,对模型参数的影响较大,而只占少数席位的错误样本被分配的权重较低,对模型参数的影响较小。这样一来,回归的结果更大概率会倾向于多数的正确样本,受少数错误的样本的影响被削弱。
model = lm.Ridge(正则强度(惩罚力度)) # 岭回归器
…
正则强度(惩罚力度)越大少数异常样本对模型的影响就越小。
代码:rdg.py
五、多项式回归
一元线性回归:
y = w0 + w1x
一元二次多项式回归:
y = w0 + w1x + w2x^2
一元三次多项式回归:
y = w0 + w1x + w2x^2 + w3x^3
一元n次多项式回归:
y = w0 + w1x + w2x^2 + … + wnx^n
同样可以利用梯度下降对损失值最小化的方法,寻找最优的模型参数w0, w1, w2, …, wn。
一元n次多项式回归->n元线性(一次多项式)回归
x->x1
x^2->x2
x^3->x3
…
x^n->xn
y = w0 + w1x1 + w2x2 + … + wnxn
x x1,x2,…,xn w0,w1,…,wn
->多项式特征扩展器------------>线性回归器--------------->y
_/
管线(pipeline)
代码:poly.py
过于简单的模型,无论对于训练数据还是测试数据都无法给出足够高的预测精度,这种现象叫做欠拟合。
过于复杂的模型,对于训练数据可以得到较高的预测精度,但对于测试数据通常精度较低,这种现象叫做过拟合。
一个性能可以接受的学习模型应该对训练数据和测试数据都有接近的预测精度,而且精度不能太低。
训练集R2 测试集R2
0.3 0.4 欠拟合:过于简单,无法反映数据的规则
0.9 0.2 过拟合:过于复杂,太特殊,缺乏一般性
0.7 0.6 可接受:复杂度适中,既反映数据的规则
同时又不失一般性
六、决策树
思想:相似的输入必然产生相似的输出——同因同果。
年龄:1-青年,2-中年,3-老年
学历:1-本科,2-硕士,3-博士
经验:1-小白,2-欠缺,3-丰富,4-资深
性别:1-男性,2-女性
年龄 学历 经验 性别 -> 薪资
1 1 2 1 6000 低
2 1 3 1 8000 中
1 3 2 2 10000 高
…
2 1 3 1 -> ?
基于决策树的归回:在已知数据中寻找与待预测输入匹配或近似匹配的样本,将它们输出的平均值作为预测输出。
基于决策树的分类:在已知数据中寻找与待预测输入匹配或近似匹配的样本,将它们输出中占大多数的类别作为预测输出。
找相同或相似,用均值回归,用投票分类。
决策树的构建是为了提高寻找相同或相似输入的效率。依次针对训练集中的每一个特征,划分成若干个子表,每一次划分所得到的子表中都会有一个特征是相同的,这样被划分到叶级子表中的样本必然所有的特征都是相同的。当需要查找某个待预测输入时,就可以根据其每个特征值直接定位到相应的子表中,以此提高搜索性能。
优化:不必使每一个特征都参与子表的划分,而只是选择其中较为重要的部分特征作为划分子表的依据。特征重要性的评价指标就是根据该特征划分子表后所带来的信息熵减小量,熵减越大的特征就越重要,也就越优先参与子表划分。
集成算法:利用多棵由不同方法得到的决策树,共同参与预测,将它们的预测结果根据平均(回归)或投票(分类)的处理作为最终的预测结果。
1)自助聚合:利用随机抽取的部分样本构建多棵决策树。
2)随机森林:利用随机抽取的部分样本结合随机选择的部分特征构建多棵决策树。
3)正向激励:首先为训练集中的样本随机分配初始权重,构建第一棵决策树,用该树对训练集做预测,增加预测错误的样本的权重,构建第二棵决策树,以此类推,构建出多棵具有不同权重的决策树。
代码:house.py
特征重要性:任何一种基于决策树的评估模型,都会在选择特征时根据信息熵减少量计算每个特征的重要程度,该项指标往往也可以对业务分析提供指导。
代码:fi.py
针对一组样本的特征重要性排列不仅与模型算法有关,还和数据本身有关,不同的数据采集方式和粒度有可能会导致特征重要性排序出现较大的差别。
代码:bike.py
七、简单分类
输入 输出
3 1 0
2 5 1
1 8 1
6 4 0
5 2 0
3 5 1
4 7 1
4 -1 0
x1 x2 y
/ x1 < x2, y = 1
\ x1 > x2, y = 0
5 9 1
7 2 0
代码:simple.py
八、逻辑分类
y = f(x1,x2)
y = w0+w1x1+w2x2
逻辑函数
1
y = ----------
1 + e^-t
1
y= ------------------------------
1 + e^-(w0+w1x1+w2x2)
0.5 -> 1
<0.5 -> 0
将逻辑函数的值是为x1x2样本隶属于1类别的概率。
model = lm.LogisticRegression(
solver=‘liblinear’, C=正则强度)
model.fit(训练输入集, 训练输出集)
model.predict(待预测输入集)->预测输出集
代码:log.py
通过多个二元分类器解决多元分类问题
x1 x2 x3 -> A 1 0 0
x1 x2 x3 -> B 0 1 0
x1 x2 x3 -> C 0 0 1
… 模型1 模型2 模型3
x1 x2 x3 -> 0.9 0.98 0.95
A B C
^
代码:mlog.py
loss = f(w0, w1,…, wn) - 正则项(训练数据)x正则强度
九、朴素贝叶斯分类
输入 输出
1 6 9 -> 0
3 2 7 -> 0
8 5 3 -> 0
…
1 2 3 -> ?
对于一个带预测样本x被判定为类别C的概率
x 0 0.8
1 0.7
2 0.9 *
在x样本出现的条件下,该样本属于C类别的概率:P(C|x)
P(0|x)
P(1|x)
P(2|x) max -> x属于2类别
将一个分类问题转换为一个条件概率问题。
贝叶斯定理:P(A|B)=P(B|A)P(A)/P(B)
P(C|x)
=P(x|C)P©/P(x)
P(x|C)P©
=P(x,C)
=P(x1,x2,x3,C)
=P(x1|x2,x3,C)P(x2,x3,C)
=P(x1|x2,x3,C)P(x2|x3,C)P(x3,C)
=P(x1|x2,x3,C)P(x2|x3,C)P(x3|C)P©
朴素:条件独立,构成一个样本的各个特征彼此无关,不行成约束。
=P(x1|C)P(x2|C)P(x3|C)P©
C: 你在街上遇到美女的概率=0.01
x: 美女爱上你的概率=0.01
P(x|C)P©=P(x,C)=0.01 x 0.01
代码:nb.py
对于分类问题训练集和测试集的划分不应该用整个样本空间的特定百分比作为训练数据,而应该在其每一个类别的样本中抽取特定百分比作为训练数据。
import sklearn.model_selection as ms
ms.train_test_split(输入集, 输出集, test_size=测试集占比,
random_state=随机种子)
->训练输入, 测试输入, 训练输出, 测试输出
代码:split.py
评估分类器的性能指标:
查准率:对/(对+多),[0, 1],找的对不对
召回率:对/(对+少),[0, 1],找的全不全
F1得分:2x查准率x召回率/(查准率+召回率),[0, 1]
针对每一个类别分别统计其查准率、召回率和F1得分,再对所有类的查准率、召回率和F1得分分别求算数平均数,将其作为分类器的性能指标。
交叉验证:将训练集划分成若干个折叠,每次用其中的一个折叠用于测试,其它折叠用于训练,将所有折叠都测试完成,得到一个性能指标序列。通过该指标序列的平均值和标准差评估模型的性能。
ms.cross_val_score(模型, 输入集, 输出集, cv=验证数,
scoring=指标)
precision_weighted - 查准率
recall_weighted - 召回率
f1_weighted - F1得分
代码:cv.py
混淆矩阵
每一行表示一个真是类别的样本,每一列表示一个预测类别的样本。
sm.confusion_matrix(真实输出,预测输出)->混淆矩阵
代码:cm.py
分类报告
sm.classification_report(真实输出,预测输出)->分类报告
代码:cr.py
十、决策树分类
通过相似样本的投票确定划分类别。
代码:car.py
se.RandomForestClassifier(
max_depth=最大高度,n_estimators=评估器数,
random_state=随机种子)