线性回归** (属于回归算法,解决回归问题,即目标值为连续性的数据)
应用场景:房价预测,销售额度预测,贷款额度预测
定义:线性回归(Linear regression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。
线性关系:
通用公式(线性模型): h(w) = w1x1 + w2x2 + w3x3 + … + b —自变量一次
x1,x2,x3代表特征值,h(w)为目标值(或者用y来表示),w1,w2,w3为权重值(也叫回归系数),b为偏置。
即可以这样表示 h(w) = w^Tx + b(w的转置乘x加b)
线性表示:y = wx +b 线性表示:y = w1x1 + w2x2 + b
注:单特征与目标值的关系是直线关系,两个特征与目标值呈平面关系。
非线性关系:
公式(线性模型):y = w1x1 + w2x1^2 + w3x1^3 + w4x1^3 + … + b —参数一次
线性回归的原理:假定特征值和目标值满足线性回归公式(即上面的函数关系),然后通过一些方法找到最合适的一组权重和偏置,使得预测结果(目标值)更加的准确。
特点:只有一个自变量的情况称为 单变量回归 ,多于一个自变量的情况叫做 多元回归 。
损失函数(也叫最小二乘法,最小:想要使得损失最小,二乘法:平方):
hw(x1)即把x1特征代入一个假定形成的具有权重和偏置的函数中求出的预测目标值,y1,y2…ym为真实目标值,然后相减、平方(两值相减可能为负,为了不让距离相互之间抵消,所以平方)
损失函数的原理:即假设已经有个预测函数,和一个真实函数,求出预测函数到真实函数的总距离(总损失)
如何使得损失更小(算出一个最佳的线性模型,即求出最佳参数w,b)?
优化损失(即缩小损失的过程):缩小预测函数到真实函数的总距离即为优化损失
优化算法:
如何去求模型当中的W,使得损失最小?(目的是找到最小损失对应的W值)
算法一:正规方程(用的较少):天才——直接求解w
理解:X为特征值矩阵
y为目标值矩阵
: 把m×n矩阵X的行换成同序数的列得到一个n×m矩阵,此矩阵叫做X的转置矩阵
:矩阵 的逆矩阵, 比如 一个数a乘以一个数b,让他的结果为1,即 a * b = 1,那么 b = 1 / a = a ^ -1,同理,一个矩阵A乘以一个矩阵B,让他的结果为单位矩阵E (主对角线上的元素都为1,其余元素全为0的n阶矩阵称为n阶单位矩阵,比如 ),即A * B = E,那么B = A ^ -1,其实就是A的逆
缺点:当特征过多过复杂时,求解速度太慢并且得不到结果
应用场景:适合用于数据量比较小的场景
算法二:梯度下降(用于线性回归、逻辑回归、深度学习):勤奋努力的普通人——一开始随便给出权重和偏置,然后不断尝试(试错、改进)求出最佳权重和偏置
公式:
理解: α为学习速率,也可以称为步长,需要手动指定, 为方向,沿着这个函数下降的方向找,最后就能找到最低点,然后更新W值
沿着切线向下的方向,一步步的计算出权重使得损失值最小。
如何在sklearn中使用线性回归算法?
API:sklearn.linear_model.LinearRegression(fit_intercept=True)
优化方法:正规方程
fit_intercept:是否计算偏置
LinearRegression.coef_:查看回归系数(即权重w)
LinearRegression.intercept_:查看偏置(即偏置b)
API:sklearn.linear_model . SGDRegress or(loss=“squared_loss”, fit_intercept=True, learning_rate=“invscaling”, eta0=0.01)
优化方法:梯度下降
fit_intercept:是否计算偏置
SGDRegression.coef_:查看回归系数(即权重w)
SGDRegression.intercept_:查看偏置(即偏置b)
loss:损失类型,默认为sqaured_loss,即最小二乘法
learning_rate:string,optional,学习速率,即步长,学习率默认为invscaling算法(invscaling算法公式:eta=eta0/pow(t, power_t) eta0需要自己指定初始学习率,power_t默认为0.25),还有optimal算法(optimal算法公式:eta=1.0/(alpha * (t+t0))[default]),constant算法(constant算法公式:eta=eta0,如果想要学习率保持在一个水平,可以使用此算法,即设置learning_rate=“constant”)
eta0:指定学习率,默认为0.01
示例:波士顿房价预测
数据集:
流程:
1)获取数据
2)数据集划分
3)特征工程: 无量纲化——>标准化
4)预估器流程:fit() —>模型
5)模型评估
如何去评估模型的效果?(即回归性能评估)
方法:均方误差(Mean Sqaured Error,即MSE)评价机制
理解:每一个样本的预测值减去真实值,然后求出平方和的平均, 为预测值, 为真实值。
只需要求一下模型的均方误差,哪一个模型的均方误差比较小,就说明哪个模型效果更好一些。
如何在sklearn中使用均方误差?
API:sklearn.metrics.mean_squared_error(y_true, y_pred)
metrics:(数学中)测量的意思
mean_squared_error:平均的平方误差
y_ture:真实的目标值
y_pred:预测的目标值
返回值:均方误差的结果,结果越大,损失越大
代码:
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import mean_squared_error
def linear1():
'''
正规方程的优化方法对波士顿房价进行预测
:return:
'''
# 1、获取数据
boston = load_boston()
print("特征名称:", boston.feature_names)
print("样本和特征的数量:", boston.data.shape)
# 2、数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3、特征工程:标准化
transfer = StandardScaler()
x_train_new = transfer.fit_transform(x_train)
x_test_new = transfer.transform(x_test)
# 4、预估器流程
estimator = LinearRegression()
estimator.fit(x_train_new, y_train)
# 5、得出模型
print("正规方程-权重系数为:", estimator.coef_)
print("正规方程-偏置为:", estimator.intercept_)
# 6、模型评估
y_predict = estimator.predict(x_test_new)
error = mean_squared_error(y_test, y_predict)
print("预测房价:\n", y_predict)
print("正规方程-均方误差为:", error)
return None
def linear2():
'''
梯度下降的优化方法对波士顿房价进行预测
:return:
'''
# 1、获取数据
boston = load_boston()
# 2、数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3、特征工程:标准化
transfer = StandardScaler()
x_train_new = transfer.fit_transform(x_train)
x_test_new = transfer.transform(x_test)
# 4、预估器流程
estimator = SGDRegressor(learning_rate='constant')
estimator.fit(x_train_new, y_train)
# 5、得出模型
print("梯度下降-权重系数为:", estimator.coef_)
print("梯度下降-偏置为:", estimator.intercept_)
# 6、模型评估
y_predict = estimator.predict(x_test_new)
error = mean_squared_error(y_test, y_predict)
print("预测房价:\n", y_predict)
print("梯度下降-均方误差为:", error)
if __name__ == '__main__':
# 代码1:正规方程的优化方法对波士顿房价进行预测
linear1()
# 代码2:梯度下降的优化方法对波士顿房价进行预测
linear2()
结果(部分截图):可以看出在小数据集上,正规方程比梯度下降的均方误差要小一些,损失就小一些,当然也可以对梯度下降进行调参使得损失减小(即尝试改变预估器SGDRegressor()里的参数值,比如eta0-学习率,max_iter-最大迭代次数,learning_rate-学习算法…)。
进行调参,替换掉上面实例化梯度下降算法预估器代码:
estimator = SGDRegressor(learning_rate='constant', max_iter=10000)
结果:通过对梯度下降算法预估器进行调参,均方误差明显减小了,即损失减少。
总结:
梯度下降 | 正规方程 |
---|---|
需要选择学习率(即设置参数eta0和learning_rate) | 不需要 |
需要迭代求解(即需要不断的试错,改进) | 一次运算得出结果 |
特征数量较大也可以使用 | 需要计算方程、时间复杂度高(需要计算转置、求逆,遇到特征数量较多的情况就不太适合) |
如果数据集样本数量小于10万个,不建议用梯度下降(SGDRegressor),要么用Lasso ElasticNet—样本数量少的情况下适合特征数量少的,要么用岭回归(RidgeRegression)—样本数量少的情况下适合特征数量多的。
(sklearn官网给出的图,图中没有提LinearRegression—正规方程算法)
LinearRegression虽然适合小规模数据,但是不能够解决 拟合问题 ,所以不常用,常用岭回归
SGDRegressor适合大规模数据
拓展:梯度下降优化器
优化方法:GD、SGD、SAG(基于梯度下降对优化器的改进)
GD(Gradient—梯度 Descent—下降):最普通最原始的梯度下降,需要计算每一个样本的值进行一个个的迭代,每一次迭代权重和偏置时都要把所有样本的值算一遍,然后再进行一次迭代,导致计算量非常大效率低,所以后面才有一系列的改进。
改进:SGD,SAG
SGD(Stochastic gradient descend):称为随机梯度下降,是一个优化方法。它在一次迭代时只考虑一个训练样本。而不是像传统的最原始的GD,算所有样本才更新一次权重和偏置。
优点:高效、容易实现
缺点:SGD需要许多超参数,比如正则项参数、迭代数
SGD对于特征标准化是敏感的
效果没有GD好
SAG(Stochastic Average Gradient):称为随机平均梯度法,由于传统的GD收敛的速度太慢,SGD也有一些缺点,于是有人提出SAG等基于梯度下降的算法。
岭回归和逻辑回归等当中都会有SAG优化
欠拟合和过拟合
问题:训练数据训练的很好,误差也不大,为什么在测试集上面有问题呢?
当算法在某个数据集中出现这种情况,可能就出现了 过拟合现象
欠拟合:学习到的特征太少了
图片理解:机器学习天鹅的特征,由于学到的特征比较少,所以第一个,第二个根据有翅膀、嘴巴长预测的结果为天鹅(错误),最后一个正确。
过拟合:学习到的特征太多了
图片理解 : 这次让机器学习较多特征,第一个根据脖子短(不符合),体型小(不符合)预测的结果不是天鹅(正确),第二个由于机器学习到的特征中有”白色的“,所以判断第二个不是天鹅(错误)
过拟合:
定义:一个假设在训练数据上能够获得比其他假设更好的拟合,但是在测试数据上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象。(模型过于复杂)
原因:原始特征过多,存在一些嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点。
图1 如果用一条直线去拟合各个数据点,属于欠拟合,图3 由于有很多高次项去拟合数据,在训练集上非常吻合,但是这个模型泛化能力比较差,如果新的数据拿来测试很可能不准,图2 为 理想模型。
如何解决过拟合问题?
正则化方法:
类别:L1正则化,L2正则化
L2正则化(常用):
作用:使得模型当中的权重系数W尽可能地接近于0,从而削弱某些特征的影响。
加入L2正则化后的损失函数:
理解: 为损失函数,预测值减去真实值,求一个平方和,不过前面变为1/2m,这样更容易求导。 为λ * 惩罚项,λ为惩罚系数(惩罚的步长,超参数,可以调节),每一个权重的平方乘以λ然后再加和。这个方法在尽可能的让损失函数值变小的同时,后面还加上惩罚项,可以使得权重系数尽可能的减小(不仅能够让模型更加的准确,还消除了一些高次项的影响)
加入L2正则化后的损失函数称为 Ridge — 岭回归
L1正则化:
同L2正则化,也是在损失函数 后面加上λ * 惩罚项,不过惩罚项为权重w的绝对值和(L2正则化为权重w的平方和)
作用:可以使得其中一些w的值直接为0,删除这个特征的影响
加入L1正则化后的损失函数称为 LASSO
欠拟合:
定义:一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)
原因:学习到数据的特征过少
解决方法:增加数据的特征数量
过拟合和欠拟合的理解:
岭回归 :(属于回归算法)即带L2正则化的线性回归,是线性回归的一个改进(也是一种线性回归,加入L2正则化的限制,从而能够解决过拟合问题)
API:sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True, solver=“auto”, normalize=False)
alpha:正则化力度(即惩罚项系数),也叫λ,取值在 0-1 1-10
fit_intercept:是否添加偏执,默认添加,使得模型更加准确
solver:默认为"auto",会根据数据自动选择优化方法,如果数据集、特征都比较大,选择随机平均梯度法优化,将自动选择参数"sag"(Stochastic Average Gradient)。
normalize:默认为False,如果选True,可以在预估器流程fit()之前调用preprocessing.StandardScaler,相当于省去了在特征工程中进行标准化的步骤,直接在实例化预估器流程中选择参数normalize=True即可实现特征工程标准化。
因生成的模型也是线性模型,如果想看权重和偏置,也可以调用相关属性,如下
Ridge.coef_:回归权重
Ridge.intercept_:回归偏执
理解:Ridge方法相当于SGDRegressor(penalty=“l2”, loss=“squared_loss”),penalty=“l2”:给线性回归加上了L2惩罚项,实现了L2正则化,loss=“squared_loss”:最小二乘法,只不过SGDRegressor实现了一个普通的随机梯度下降学习,推荐使用Ridge(实现了SAG,即随机平均梯度法)
其他API:sklearn.linear_model.RidgeCV(_BaseRidgeCV, RegressorMixin)
理解:具有L2正则化的线性回归,可以进行交叉验证,即加上了交叉验证的岭回归。
coef_:回归系数
正则化力度(即惩罚项系数)对结果(权重系数)有什么影响?
横坐标:正则化力度(alpha);纵坐标:权重系数(weights)
观察上图,可以得出,正则化力度越大,权重系数越接近于0(越小),正则化力度越小,则权重系数越大,把图和公式联系起来,加入L2正则化后的损失函数公式(即岭回归公式):
损失函数值 要求 越小越好,根据公式也可以看除出,当正则化力度比较大,相对而言,惩罚项会比较小一点,即权重系数会小一点,当正则化力度小的话,权重系数就会大一些。
示例:波士顿房价预测
代码:
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Ridge
def linear3():
'''
岭回归对波士顿房价进行预测
:return:
'''
# 1、获取数据
boston = load_boston()
# 2、数据集划分
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3、特征工程:标准化
transfer = StandardScaler()
x_train_new = transfer.fit_transform(x_train)
x_test_new = transfer.transform(x_test)
# 4、预估器流程
estimator = Ridge(alpha=0.5, max_iter=10000)
estimator.fit(x_train_new, y_train)
# 5、得出模型
print("岭回归-权重系数为:", estimator.coef_)
print("岭回归-偏置为:", estimator.intercept_)
# 6、模型评估
y_predict = estimator.predict(x_test_new)
error = mean_squared_error(y_test, y_predict)
print("预测房价:\n", y_predict)
print("岭回归-均方误差为:", error)
if __name__ == '__main__':
linear3()
逻辑回归 :(属于分类算法)用来解决二分类问题
逻辑回归(Logistic Regression)不属于回归算法,但确实和线性回归有一定的联系
应用场景:广告点击率(是否会被点击)、是否为垃圾邮件、是否患病、金融诈骗(是否为金融诈骗)、虚假账号(是否为虚假账号),上面场景全是二分类问题,即要么是,要么否。
原理:
1 输入
理解:线性回归的输出(结果)作为逻辑回归的输入
2 激活函数
sigmoid函数
将逻辑回归的输入(线性回归的输出结果)代入到sigmoid函数中
理解:sigmo函数其实是1 / 1 + e^(-x),然后将线性回归的输出代入到x的部分就成了 这个结果,只不过公式写的是另一种线性模型的表示方法(即用矩阵的形式来表示)
输出结果:将线性回归的结果代入sigmoid函数得到的值是[0, 1]区间中的一个概率值,默认0.5为阈值,如果输出结果大于0.5,就认为属于某个类别,如果小于0.5.就认为不属于某个类别,这样就可以解决分类问题
假设有了一个线性模型,将线性模型的函数 h(w) = w1x1 + w2x2 + w3x3 … + b 代入 simoid函数(即 1 / 1 + e^(-x) )的x部分,可得:
1 / 1 + e^(-(w1x1 + w2x2 + w3x3 … + b)) —— 逻辑回归生成的模型函数其实就是这个
如何得出一组权重和偏执使得模型可以准确进行分类预测?
思路:构建一个损失函数,然后优化损失
线性回归构建的损失函数为最小二乘法或均方误差,即 y_predict - y_true 然后求出平方和或 y_predict - y_true 然后求出平方和除以总数求平均。
逻辑回归损失函数如何构建?
线性回归的真实值:具体的一个数,容易构建损失函数
逻辑回归的真实值:分类,(即是否属于某个类别)
逻辑回归的预测值:概率,然后加一个阈值,大于这个阈值为一个类别,小于这个阈值不为这个类别(即是否属于某个类别)
对数似然损失(逻辑回归的损失计算函数)
理解:如果 真实值 y=1(即属于这个类别),损失就是 ,如果真实值 y=0(即不属于这个类别),损失就是
当 y = 1 时:(真实值属于这个类别)
理解:线性回归的输出结果映射到sigmoid函数上, 得到区间在[0, 1]的预测的概率值 (即在这里代表横坐标 ,如果 越接近于1,纵坐标损失值越接近于0,说明预测的越准确,如果 为越接近于0的概率值,损失值就越大,说明预测的不准确 )
当 y = 0时:(真实值不属于这个类别)
理解:线性回归的输出结果映射到sigmoid函数上,得到区间在[0, 1]的预测的概率值,如果预测值接近于0的话,损失也接近于0,说明预测的比较准,如果预测的概率值接近于1的话,真实值是不属于这个类别,而预测的值代表属于这个类别,说明预测的不准,意味着损失比较大。
综合完整损失函数公式:
理解:如果某一个样本的 真实值为1 (属于一个类别),则后面部分 的yi = 1,抵消了,然后根据 计算这个样本的损失值。如果某一个样本的 真实值为0 ,则前面部分 的yi = 0,抵消了, 然后根据 计算这个样本的损失值。最后把所有样本的损失值进行加和,求出总的损失。
关于对数函数log:
当 a > 1 时,函数单调递增,-log a §,P值越大,结果(即单个样本损失值)越小
知道了逻辑回归损失的计算方法,如何去优化损失?
即逻辑回归预测的结果更加准确,更加接近于真实结果
方法:梯度下降
如何在sklearn中使用逻辑回归?
API:sklearn.Linear_model.LogisticRegression(solver=“liblinear”, penalty=“l2”, C=1.0)
solver:优化求解方式,默认为开源的"liblinear"库实现,内部使用了坐标轴下降法来迭代优化损失函数,如果设为"sag",则为随机平均梯度下降
pernalty:正则化的种类,这里加入L2正则化,防止过拟合。(逻辑回归虽然是用来分类的,但是其内部还是有线性回归)
C:正则化力度
LogisticRegression.coef_:查看回归(权重)系数
LogisticRegression.intercept_:查看偏置
LogisticRegression方法相当于SGDClassfier(loss=“log”, penalty=""),SGDClassfier实现了一个普通的随机梯度下降学习,也支持平均随机梯度下降法(SAG),可以通过设置average=True。而使用LogisticRegression(实现了SAG)。
示例: 逻辑回归对癌症分类预测 — 良 / 恶性乳腺癌肿瘤预测
数据集:(来自UCI)
下载地址: https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/
下载页面:
.data为数据集,.names为数据描述
直接下载附件:
breast-cancer-wisconsin.data
breast-cancer-wisconsin.data内容:(部分)
共有699个样本,每个样本10个特征值和1个目标值
breast-cancer-wisconsin.names内容:(部分)
10个特征对应的名称,最后一个为类别(目标),2代表良性,4代表恶性
存在16个 用"?"表示的 缺失值,意味着要进行缺失值处理
流程:
1)获取数据
读取的时候加上names
2)数据处理
处理缺失值
3)数据集划分
4)特征工程
无量纲化处理:标准化
5)逻辑回归预估器流程
6)模型评估
jupyter notebook代码:
import pandas as pd
# 1、获取数据
# 注意,源文件没有列索引
# 方法一:要么在源文件第一行加上特征名
# 方法二:要么设置一个数组存放特征名,然后通过pd.read_csv的names参数传进去
column_name = ['Sample code number','Clump Thickness','Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion','Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class']
data = pd.read_csv('.\\breast-cancer-wisconsin.data', names=column_name)
# 2、数据处理,缺失值处理,总共16个用"?"表示的缺失值
import numpy as np
# 1)将带有"?"的缺失值替换为 np.nan,
# to_replace —> 想要替换的缺失值,value —> 把缺失值替换为 np.nan即(NaN)
data = data.replace(to_replace="?", value=np.nan)
# 2)删除缺失样本
# dropna()默认按行删除所有含有NaN数值的样本
# inplace=True:不创建新的对象,直接对原始对象进行修改;inplace=False:对数据进行修改,创建并返回新的对象承载其修改结果。
data.dropna(inplace=True)
# 检验是否删除含有缺失值的样本
data.isnull() # False代表不为空数据
data.isnull().any() # 每一列都不存在空数据,即已删除含有缺失值的样本
# 3、数据集划分
from sklearn.model_selection import train_test_split
# 筛选特征值和目标值
x = data.iloc[:, 1:-1] # 选择所有行,选择第二列(不包括id列的第二列)到倒数第二列
y = data['Class']
x_train, x_test, y_train, y_test = train_test_split(x, y)
# 4、特征工程:标准化
from sklearn.preprocessing import StandardScaler
transfer = StandardScaler()
x_train_new = transfer.fit_transform(x_train)
x_test_new = transfer.transform(x_test)
# 5、逻辑回归预估器流程
from sklearn.linear_model import LogisticRegression
estimator = LogisticRegression()
estimator.fit(x_train_new, y_train)
# 查看逻辑回归模型的参数
# coef_ —> 回归(权重)系数
estimator.coef_ # 有几个特征就有几个回归(权重)系数,即有9个特征(回归系数)
# intercept_ —> 偏置
estimator.intercept_
# 6、模型评估
# 方法一:直接比对预测值和真实值
y_predict = estimator.predict(x_test_new)
print("直接比对预测值和真实值:\n", y_predict == y_test)
# 方法二:计算准确率
score = estimator.score(x_test_new, y_test)
print("准确率为:\n", score)
总结:比对真实值和以这种方式来计算准确率显然不够专业,不能够很好的分析出,在预测的结果中,患有恶(良)性肿瘤中真正患有恶(良)性肿瘤的人,以及,在真实的结果中,所有患有恶(良)性肿瘤的人中被查出来了多少人,为了更好的进行模型评估,引入以下概念。
精确率和召回率:
混淆矩阵
定义:在分类任务下,预测结果(predict Condition)于正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适用于多分类)
TP:True Possitive FN:False Negative
精确率:在预测结果为正例样本中证实为正例的比例,如下图表示
即 TP / TP + FP
召回率:真实为正例的样本中预测结果为正例的比例(即反应查的全不全)
即 TP / TP + FN
比如说,恶性肿瘤的为正例,良性肿瘤为假例,预测的患有恶性肿瘤的患者中真正为恶性肿瘤患者的人即为 准确率 ,在所有真正患有恶性肿瘤的患者中预测患有恶性肿瘤的比例即为 召回率 。
除了准确率和召回率来对模型预测的结果进行评估之外,还有 F1-score ,反应模型的稳健型。
理解:精确率 加 准确率 分之 2倍的 精确率 乘 召回率,F1-score值越大,精确率、召回率就越高,稳健性就更强。
如何在sklearn中使用精确率、召回率、F1-score进行模型评估?
API:sklearn.metrics.classification_report(y_true, y_pred, lables=[], target_names=None)
metrics — 测量
classification_report — 分类结果报告
y_true:真实目标值
y_pred:估计器预测的目标值
labels:指定类别对应的数字
target_names:目标类别名称
return:每个类别精确率与召回率,返回值为字符串类型
示例:对上述癌症预测进行模型评估
jupyter notebook代码:
# 6、模型评估
from sklearn.metrics import classification_report
# 查看精确率、召回率、F1-score
report = classification_report(y_true=y_test, y_pred=y_predict, labels=[2, 4], target_names=['良性', '恶性'])
print(report) # support为样本量
假设总共100个人,99个患有癌症,1个无癌症 —— 样本不均衡(正例太多,反例太少)
不管怎样, 全部 预测为癌症
准确率:99%
召回率:100%
精确率:99%
F1-score:2 & 99% * 100% / 199% = 99.497%
可以看出,这样得出的结果都很高(即不管怎么样,全部预测为癌症,是一个很不负责任的模型,这就是样本不均衡下的评估问题)
如何衡量样本不均衡下的评估?(即从样本均不均衡的角度去评估生成模型的预测结果)
ROC曲线与AUC指标:
蓝线为ROC曲线, 曲线和X轴、Y轴包成的区域的面积为AOC指标(衡量分类器的好坏就看这个指标,如果AOC指标也接近于1,说明分类器越好,越接近于0.5,说明分类器越不好),横坐标为FPR,纵坐标为TPR
ROC曲线:
TPR = TP / (TP + FN) —— 召回率
理解:在所有真实类别为1的样本中,预测类别为1的比例
FPR = FP / (FP + TN)
理解:在所有真实类别为0的样本中,预测类别为1的比例
有了TPR和FPR就可以确定ROC曲线了。
如果TPR = FPR,意味着全部预测为1(意味着不管正例还是反例,统统预测为正例,就是在瞎猜乱蒙,对应着上图中的红色虚线(random guess)),此时面积为0.5(即AUC=0.5)
如果TPR > FPR,极限为TPR接近于1, FPR接近于0,即上图左上角perfect classification,此时面积就为1(AUC=1),完美分类器
如果TPR < FPR,即在红色虚线之下的部分,这部分的AUC < 0.5,即很糟糕,那么反过来预测,即 用 1 减去糟糕小于0.5的AUC值,可得到不错的AUC值
AUC指标:
AUC的最小值为0.5,最大值为1,取值越高越好
如何在sklearn中使用AUC计算?
API:sklearn.metrics.roc_auc_score(y_true, y_score)
计算ROC曲线面积,即AUC值
y_true:每个样本的真实类别, 必须为0(反例),1(正例)标记
y_score:预测值(y_predict),可以是正类的估计概率,置信值或者分类器方法的返回值(classification)
示例:对上述 癌症分类预测 进行AUC评估
jupyter notebook代码:
# 6、从样本不均衡的角度去衡量模型的好坏
from sklearn.metrics import roc_auc_score
# 样本中4代表恶性,即正例,转换为1标记,2代表良性,即反例,转换为0标记
y_true = np.where(y_test > 3, 1, 0)
![image](https://upload-images.jianshu.io/upload_images/23178900-
d7f5338d487fd1af.png!thumbnail?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
# y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
roc_auc_score(y_true,y_predict)
AUC指标的结果接近于1,从样本不均衡的角度看,说明这个模型还可以。
总结:AUC只能用来评价二分类,非常适合用来评价当样本出现不均衡的情况下,分类器的性能。比如前面的这种不均衡的情况,正例为患有癌症
求AUC
TPR = 100%(在 所有真实类别为1(正例)的样本中,预测类别为1的比例 )
FPR = 100%(在 所有真实类别为0的样本中,预测类别为1的比例)
因为 TPR = FPR 所以AUC=0.5 即最差的模型
所以通过AUC指标就可以知道样本不均衡的情况下模型到底好不好。
模型的保存和加载
API:from sklearn.externals import joblib
保存:joblib.dump(value, ‘test.pkl’)
value:传入预估器 ’ ':路径,会在指定的本地路径生成后缀名为.pkl模型文件
加载:estimator = joblib.load(‘test.pkl’)
K-means算法 :(属于一个无监督学习的聚类算法)
图一为原始的无聚类数据,经过K-means聚类算法得到聚类数据。
K-means聚类步骤:(K为超参数)
1、随机设置K个特征空间内的点作为初始的聚类中心
2、对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类中心点作为标记类别
3、接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点(平均值)
4、如果计算机得出的新中心点与原中心点一致,那么结束,否则重新进行第二步过程。
如何在sklearn中使用K-means算法?
API:sklearn.cluster.KMeans(n_clusters=B, init=‘k-means++’)
n_clusters:开始的聚类中心数量(即K值)
init:初始化方法,默认为’k-means++’(其实是对K-means的一种优化方法)
labels_:默认标记的类型,可以和真实值比较(labels为属性,即调用之后可以查看标记的类型)
示例:k-means对 Instacart Market用户聚类(对用户进行划分,从而针对不同类别的人推荐不同的商品)
如果k=3,即把用户分为3类
流程:
降维后的数据
1)预估器流程
2)看结果
3)模型评估
jupyter notebook代码:
import pandas as pd
# 1.获取数据
order_products_prior = pd.read_csv("instacart/order_products__prior.csv")
products = pd.read_csv("instacart/products.csv")
orders = pd.read_csv("instacart/orders.csv")
aisles = pd.read_csv("instacart/aisles.csv")
# 2.合并表
# 合并aisles和products,aisle和product_id就关联了
tab1 = pd.merge(aisles, products, on=["aisle_id", "aisle_id"])
# 合并tab1和order_products_prior,aisle和order_id就关联了
tab2 = pd.merge(tab1, order_products_prior, on=["product_id", "product_id"])
# 合并tab2和orders,aisle和user_id就关联了
tab3 = pd.merge(tab2, orders, on=["order_id", "order_id"])
# 3.找到user_id和aisle之间的关系
table = pd.crosstab(tab3["user_id"], tab3["aisle"])
data = table[:10000]
# 4.PCA降维
from sklearn.decomposition import PCA
# 1)实例化一个转换器类
transfer = PCA(n_components=0.95)
# 2)调用fit_transorm
data_new = transfer.fit_transform(data)
# 5、预估器流程
from sklearn.cluster import KMeans
estimator = KMeans(n_clusters=3)
estimator.fit(data_new)
# 看结果
y_predict = estimator.predict(data_n
可以看到用户被分成了3个类别(0,1,2),但是并不知道生成的模型的好坏。
如何对K-means算法生成的模型进行评估?
轮廓系数
公式理解:
bi — 每一个样本到其他族群所有样本的距离的最小值(外部距离)
ai — 每一个样本到本族群中所有距离的平均值(内部距离)
轮廓系数数值分析:
如何根据轮廓系数判断聚类的好坏?
如果 >> ,即外部距离很大,内部距离很小,聚类效果最好,则轮廓系数 ≈ / = 1
如果 << ,即外部距离很小,内部距离很大,聚类效果最差,则轮廓系数 ≈ - / = -1
如何在sklearn中使用轮廓系数?
API:sklearn.metrics.silhoutte_score(X, labels)
计算所有样本的平均轮廓系数
X:特征值
labels:被聚类标记的目标值
返回值:轮廓系数
jupyter notebook代码:(接上面的代码)
# 6、模型评估 — 轮廓系数
from sklearn.metrics import silhouette_score
silhouette_score(data_new, y_predict)
轮廓系数:(仅对10000个样本训练得到的模型,这个结果还可以)
K-means总结:
优点:采用迭代式算法
即
缺点:容易收敛到局部最优解
最开始在取初始K个聚类中心点的时候是随机选取的,如果选取的K个点恰好挨得比较近,那么容易导致结果陷入到局部最优,怎么避免?多次聚类(多次随机取聚类中心)
应用场景:如果一开始没有目标值,根据聚类生成类别,有了类别,后期就可以进行分类。
学习大纲: