1.K-近邻算法
1.1K-近邻算法概念
定义:
如果⼀个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的⼤多数属于某⼀个类别,则该样本也属于这个类别。
简单来说就是通过你的"邻居"来判断你属于哪个类别
距离公式:
1.2 KNN算法流程总结
1)计算已知类别数据集中的点与当前点之间的距离
2)按距离递增次序排序
3)选取与当前点距离最⼩的k个点
4)统计前k个点所在的类别出现的频率
5)返回前k个点出现频率最⾼的类别作为当前点的预测分类
1.3 K-近邻算法API
- sklearn.neighbors.KNeighborsClassifier(n_neighbors=5)
- n_neighbors:int,可选(默认= 5),k_neighbors查询默认使⽤的邻居数
from sklearn.neighbors import KNeighborsClassifier
# 1.构造数据
x = [[0],[2],[3],[64]] # 4个样本 (二维) (特征值
y = [0 , 0 , 1 , 1 ] # 每个样本分别对应哪个类 (目标值
# 2.训练模型
# 2.1 实例化一个估计器模型
mestimator = KNeighborsClassifier(n_neighbors=1) #(k=1
# 2.2 调用fit方法进行训练
mestimator.fit(x,y)
# 3.数据预测
res = mestimator.predict([[23]]) # 要用二维的 预测特征值23 的目标值
print(res)
23 属于 1 类
1.4 距离度量
1.4.1 常⻅的距离公式
1.4.1.1.1 欧式距离(Euclidean Distance):
就是我们目前所熟知的距离公式
1.4.1.1.2曼哈顿距离(Manhattan Distance):
在曼哈顿街区要从⼀个⼗字路⼝开⻋到另⼀个⼗字路⼝,驾驶距离显然不是两点间的直线距离。这个实际驾驶距离就是
“曼哈顿距离”。曼哈顿距离也称为“城市街区距离”(City Block distance)。
1.4.1.1.3切⽐雪夫距离 (Chebyshev Distance):
国际象棋中,国王可以直⾏、横⾏、斜⾏,所以国王⾛⼀步可以移动到相邻8个⽅格中的任意⼀个。国王从格⼦(x1,y1)
⾛到格⼦(x2,y2)最少需要多少步?这个距离就叫切⽐雪夫距离。
1.4.1.1.4 闵可夫斯基距离(Minkowski Distance):
闵⽒距离不是⼀种距离,⽽是⼀组距离的定义,是对多个距离度量公式的概括性的表述。
两个n维变量a(x11,x12,…,x1n)与b(x21,x22,…,x2n)间的闵可夫斯基距离定义为:
当p->无穷时,我们可以用极限的思想来理解,|x1-x2|^P + |x3-x4|^P +… 我们假设|x1-x2|^p超级大, |x3-x4|^p 是一个很小的数,那么|x3-x4|^p我们可以忽略不记 ,那么最后的结果就是 max(|x1i-x2I|),也就是切比雪夫距离了
1.4.2连续属性”和“离散属性”的距离计算
我们常将属性划分为"连续属性" (continuous attribute)和"离散属性" (categorical attribute),前者在定义域上有⽆穷多个
可能的取值,后者在定义域上是有限个取值.
- 若属性值之间存在序关系,则可以将其转化为连续值,例如:身⾼属性“⾼”“中等”“矮”,可转化为{1, 0.5, 0}。
- 闵可夫斯基距离可以⽤于有序属性。
- 若属性值之间不存在序关系,则通常将其转化为向量的形式,例如:性别属性“男”“⼥”,可转化为{(1,0),
(0,1)}。
1.5 k值的选择
K值过⼩:
容易受到异常点的影响
k值过⼤:
受到样本均衡的问题
K=N(N为训练样本个数),则完全不⾜取,
因为此时⽆论输⼊实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单,忽略了训练
实例中⼤量有⽤信息。
在实际应⽤中,K值⼀般取⼀个⽐较⼩的数值
- 近似误差:
- 对现有训练集的训练误差,关注训练集,
- 如果近似误差过⼩可能会出现过拟合的现象,对现有的训练集能有很好的预测,但是对未知的测试样本将会出
现较⼤偏差的预测。 - 模型本身不是最接近最佳模型。
- 估计误差:
- 可以理解为对测试集的测试误差,关注测试集,
- 估计误差⼩说明对未知数据的预测能⼒好,
- 模型本身最接近最佳模型。
1.6 KD树
1.6.1KD树的建立
1.构造根节点
2.通过递归的⽅法,不断地对k维空间进⾏切分,⽣成⼦节点
3.重复第⼆步骤,直到⼦区域中没有示例时终⽌。
这里通过一个栗子来解释一下
给定⼀个⼆维空间数据集:T={(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},构造⼀个平衡kd树。
(1)思路引导:
根结点对应包含数据集T的矩形,选择x(1)轴,6个数据点的x(1)坐标中位数是6,这⾥选最接近的(7,2)点,以平⾯x(1)=7
将空间分为左、右两个⼦矩形(⼦结点);接着左矩形以x(2)=4分为两个⼦矩形(左矩形中{(2,3),(5,4),(4,7)}点的x(2)坐
标中位数正好为4),右矩形以x(2)=6分为两个⼦矩形,如此递归,最后得到如下图所示的特征空间划分和kd树。
1.6.2 最近领域的搜索
假设标记为星星的点是 test point, 绿⾊的点是找到的近似点,在回溯过程中,需要⽤到⼀个队列,存储需要回溯的
点,在判断其他⼦节点空间中是否有可能有距离查询点更近的数据点时,做法是以查询点为圆⼼,以当前的最近距离为
半径画圆,这个圆称为候选超球(candidate hypersphere),如果圆与回溯点的轴相交,则需要将轴另⼀边的节点都放
到回溯队列⾥⾯来。
还是举一个栗子
样本集{(2,3),(5,4), (9,6), (4,7), (8,1), (7,2)}
在(7,2)处测试到达(5,4),在(5,4)处测试到达(4,7)【优先选择在本域搜索】,然后search_path中的结点为<(7,2),(5,4),
(4,7)>,从search_path中取出(4,7)作为当前最佳结点nearest, dist为3.202;
然后回溯⾄(5,4),以(2,4.5)为圆⼼,以dist=3.202为半径画⼀个圆与超平⾯y=4相交,所以需要跳到(5,4)的左⼦空间去
搜索。所以要将(2,3)加⼊到search_path中,现在search_path中的结点为<(7,2),(2, 3)>;另外,(5,4)与(2,4.5)的距离为
3.04 < dist = 3.202,所以将(5,4)赋给nearest,并且dist=3.04。
回溯⾄(2,3),(2,3)是叶⼦节点,直接平判断(2,3)是否离(2,4.5)更近,计算得到距离为1.5,所以nearest更新为(2,3),
dist更新为(1.5)
回溯⾄(7,2),同理,以(2,4.5)为圆⼼,以dist=1.5为半径画⼀个圆并不和超平⾯x=7相交, 所以不⽤跳到结点(7,2)的右⼦
空间去搜索。
⾄此,search_path为空,结束整个搜索,返回nearest(2,3)作为(2,4.5)的最近邻点,最近距离为1.5。
1.7 scikit-learn中数据集介绍
1.7.1 scikit-learn数据集API介绍
- sklearn.datasets
- 加载获取流⾏数据集
- datasets.load_*()
- 获取⼩规模数据集,数据包含在datasets⾥
- datasets.fetch_*(data_home=None)
- 获取⼤规模数据集,需要从⽹络上下载,函数的第⼀个参数是data_home,表示数据集下载的⽬录,默认
是 ~/scikit_learn_data/
- 获取⼤规模数据集,需要从⽹络上下载,函数的第⼀个参数是data_home,表示数据集下载的⽬录,默认
1.7.1.1 sklearn⼩数据集
- sklearn.datasets.load_iris()
加载并返回鸢尾花数据集
1.7.1.2 sklearn⼤数据集
- sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)
- subset:‘train’或者’test’,‘all’,可选,选择要加载的数据集。
- 训练集的“训练”,测试集的“测试”,两者的“全部”
1.7.2 sklearn数据集返回值介绍
- load和fetch返回的数据类型datasets.base.Bunch(字典格式)
- data:特征数据数组,是 [n_samples * n_features] 的⼆维 numpy.ndarray 数组
- target:标签数组,是 n_samples 的⼀维 numpy.ndarray 数组
- DESCR:数据描述
- feature_names:特征名,新闻数据,⼿写数字、回归数据集没有
- target_names:标签名
from sklearn.datasets import load_iris ,fetch_20newsgroups
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
# 1.数据集获取
# 1.1小数据集获取
iris = load_iris()
print(iris)
# 1.2大数据集获取
news = fetch_20newsgroups()
print(news) # urllib.error.HTTPError: HTTP Error 403: Forbidden !!!!!
#
# 2.数据集属性描述
# 可以用 '.' 也可以用【】
print('数据集特征值是:\n',iris.data)
print('1)数据集目标值是:\n',iris.target)
print("2)数据集的目标值是:\n",iris["target"])
1.7.3 查看数据分布
- seaborn.lmplot() 是⼀个⾮常有⽤的⽅法,它会在绘制⼆维散点图时,⾃动完成回归拟
- sns.lmplot() ⾥的 x, y 分别代表横纵坐标的列名,
- data= 是关联到数据集,
- hue=*代表按照 species即花的类别分类显示,
- fit_reg=是否进⾏线性拟合。
from sklearn.datasets import load_iris ,fetch_20newsgroups
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
iris = load_iris()
iris_d = pd.DataFrame(data= iris['data'],columns=['Sepal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width'])
iris_d["target"]=iris.target
print(iris)
def plt_iris(clo1,clo2,iris):
sns.lmplot(x=clo1,y=clo2,data=iris,hue='target',fit_reg=False) #hue 代表不同的系列
plt.xlabel(clo1)
plt.ylabel(clo2)
plt.title('鸢尾花种类分布图')
plt.show()
plt_iris( 'Sepal_Width', 'Petal_Length',iris_d)
1.7.4 数据集的划分
-
机器学习⼀般的数据集会划分为两个部分:
- 训练数据:⽤于训练,构建模型
- 测试数据:在模型检验时使⽤,⽤于评估模型是否有效
-
划分⽐例:
- 训练集:70% 80% 75%
- 测试集:30% 20% 25%
数据集划分api
-
sklearn.model_selection.train_test_split(arrays, *options)
- 参数:
- x 数据集的特征值
- y 数据集的标签值
- test_size 测试集的⼤⼩,⼀般为float
- random_state 随机数种⼦,不同的种⼦会造成不同的随机采样结果。相同的种⼦采样结果相同。
- return
- x_train, x_test, y_train, y_tes
- 参数:
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=2)
print("训练集的特征值是:",x_train)
print("训练集的目标值是:",y_train)
print("测试集的特征值是: ",x_test)
print("测试集的目标值是: ",y_test)
print("训练集的特征值的形状是:",x_train.shape)
print("测试集的特征值的形状是:",x_test.shape)
#不同的种子得到的结果也不同 相同的种子得到的结果也相同
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)
x_train1,x_test1,y_train1,y_test1=train_test_split(iris.data,iris.target,test_size=0.2,random_state=2)
x_train2,x_test2,y_train2,y_test2=train_test_split(iris.data,iris.target,test_size=0.2,random_state=2)
print("测试集的目标值是: ",y_test)
print("测试集的目标值是: ",y_test1)
print("测试集的目标值是: ",y_test2)
1.8 特征⼯程-特征预处理
1.8.1 什么是特征预处理
1.8.1.1 特征预处理定义
通过⼀些转换函数将特征数据转换成更加适合算法模型的特征数据过程
1.8.2 归⼀化
1.8.2.1 定义
通过对原始数据进⾏变换把数据映射到(默认为[0,1])之间
1.8.2.2 公式
作⽤于每⼀列,max为⼀列的最⼤值,min为⼀列的最⼩值,那么X’’为最终结果,mx,mi分别为指定区间值默认
mx为1,mi为0
1.8.2.3 API
- sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)… )
- MinMaxScalar.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后的形状相同的array
- MinMaxScalar.fit_transform(X)
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
s =[[40920,8.326976,0.953952],[14488,7.153469,1.673904],[26052,1.441871,0.805124],[75136,13.147394,0.428964],[38344,1.669788,0.134296]]
cls = ['milage','milage','milage']
data =pd.DataFrame(data=s,columns=cls)
print(data)
def minmax_demo():
"""
归一化演示
:return: None
"""
#1.实例化一个转换器类
transfer = MinMaxScaler(feature_range=(0,1)) #将原数据映射到(0,1)范围内
#2.调用fit_transform,进行转换
res = transfer.fit_transform(data)
print("归一化的结果:",res)
minmax_demo()
1.8.2.4 归一化总结
归一化很容易受到异常值的影响,稳定性很差
1.8.3 标准化
1.8.3.1 定义
通过对原始数据进⾏变换把数据变换到均值为0,标准差为1范围内
1.8.3.2 公式
作⽤于每⼀列,mean为平均值,σ为标准差
对于标准化来说:如果出现异常点,由于具有⼀定数据量,少量的异常点对于平均值的影响并不⼤,从⽽⽅差改变
较⼩。
1.8.3.3 API
- sklearn.preprocessing.StandardScaler( )
- 处理之后每列来说所有数据都聚集在均值0附近标准差差为1
- StandardScaler.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features
- 返回值:转换后的形状相同的array
import pandas as pd
from sklearn.preprocessing import StandardScaler
s =[[40920,8.326976,0.953952],[14488,7.153469,1.673904],[26052,1.441871,0.805124],[75136,13.147394,0.428964],[38344,1.669788,0.134296]]
cls = ['milage','milage','milage']
data =pd.DataFrame(data=s,columns=cls)
print(data)
def Standard_demo():
"""
归一化演示
:return: None
"""
#1.实例化一个转换器类
transfer = StandardScaler() #把数据变换到均值为0,标准差为1范围内
#2.调用fit_transform,进行转换
res = transfer.fit_transform(data)
print('标准化的结果:',res)
Standard_demo()
1.9 案例:鸢尾花种类预测—流程实现
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
#1.获取数据
iris = load_iris()
#2.数据基本处理
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)
#3.特征工程 - 特征预处理
#3.1实例化一个转换器类
transfer = StandardScaler()
x_train=transfer.fit_transform(x_train)
x_test=transfer.fit_transform(x_test)
#4.机器学习-KNN
#4.1实例化一个估计器
estimator = KNeighborsClassifier(n_neighbors=5)
#4.2模型训练
estimator.fit(x_train,y_train)
#5.模型评估
#5.1预测值结果输出
y_pre = estimator.predict(x_test)
print("预测值是:",y_pre)
print("预测值与真实值的对比是:",y_pre==y_test)
#5.2准确率计算
score = estimator.score(x_test,y_test)
print(score)
1.10 交叉验证,⽹格搜索
1.10.1 什么是交叉验证(cross validation
交叉验证:将拿到的训练数据,分为训练和验证集。以下图为例:将数据分成4份,其中⼀份作为验证集。然后经过4次
(组)的测试,每次都更换不同的验证集。即得到4组模型的结果,取平均值作为最终结果。⼜称4折交叉验证。
交叉验证⽬的:为了让被评估的模型更加准确可信
1.10.2 什么是⽹格搜索(Grid Search)
通常情况下,有很多参数是需要⼿动指定的(如k-近邻算法中的K值),这种叫超参数。但是⼿动过程繁杂,所以需要
对模型预设⼏种超参数组合。每组超参数都采⽤交叉验证来进⾏评估。最后选出最优参数组合建⽴模型
1.10.3 交叉验证,⽹格搜索(模型选择与调优)API:
- sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
- 对估计器的指定参数值进⾏详尽搜索
- estimator:估计器对象
- param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}cv:指定⼏折交叉验证
- fit:输⼊训练数据
- score:准确率
- 结果分析:
- bestscore__:在交叉验证中验证的最好结果
- bestestimator:最好的参数模型
- cvresults:每次交叉验证后的验证集准确率结果和训练集准确率结
1.10.4鸢尾花案例增加K值调优
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
#1.获取数据
iris = load_iris()
#2.数据基本处理
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)
#3.特征工程 - 特征预处理
#3.1实例化一个转换器类
transfer = StandardScaler()
x_train=transfer.fit_transform(x_train)
x_test=transfer.fit_transform(x_test)
#4.机器学习-KNN
#4.1实例化一个估计器
estimator = KNeighborsClassifier(n_neighbors=5)
#4.2模型调优--交叉验证、网格搜索
param_grid={'n_neighbors':[1,3,5,7]}
estimator = GridSearchCV(estimator,param_grid=param_grid,cv=4)
#4.3模型训练
estimator.fit(x_train,y_train)
#5.模型评估
#5.1预测值结果输出
y_pre = estimator.predict(x_test)
print("预测值是:",y_pre)
print("预测值与真实值的对比是:",y_pre==y_test)
#5.2准确率计算
score = estimator.score(x_test,y_test)
print(score)
#5.3 查看交叉验证、网格搜索的一些属性
print('在交叉验证中得到的最好结果是:',estimator.best_score_)
print('在交叉验证中得到的最好参数模型是:',estimator.best_estimator_)
print('每次交叉验证后的验证集准确率结果和训练集准确率结果是:',estimator.cv_results_)
2.线性回归
2.1定义与公式
线性回归(Linear regression)是利⽤回归⽅程(函数)对⼀个或多个⾃变量(特征值)和因变量(⽬标值)之间关系进⾏建模的⼀种分析⽅式。
- 特点:只有⼀个⾃变量的情况称为单变量回归,多于⼀个⾃变量情况的叫做多元回归
学生的最终成绩=a平时成绩+b期末成绩
2.2 线性回归的特征与⽬标的关系分析
线性回归当中主要有两种模型,⼀种是线性关系,另⼀种是⾮线性关系
- 单变量线性关系
- 多变量线性关系
- 非线性关系
2.3线性回归Api
- sklearn.linear_model.LinearRegression()
- LinearRegression.coef_:回归系数
from sklearn.linear_model import LinearRegression
#1.获取数据
x = [[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]]
y = [84.2, 80.6, 80.1, 90, 83.2, 87.6, 79.4, 93.4]
#2.模型训练
#2.1实例化一个估计器模型
estimator = LinearRegression()
#2.2 使用fit方法进行训练
estimator.fit(x,y)
#打印对应系数
print("线性回归的系数:",estimator.coef_)
#打印预测结果
print("输出预测结果:",estimator.predict([[100,80]]))
2.4矩阵求导(简单了解)
2.5 线性回归的损失和优化
2.5.1 损失函数
2.5.2 优化算法
2.5.2.1 正规方程
损失函数的图像:
缺点:当特征值过多时,计算的时间复杂度很大,求解速度太慢。
2.5.2.2 梯度下降
下面这个博主讲的挺好的,通俗易懂
https://www.bilibili.com/video/BV18P4y1j7uH/?spm_id_from=333.999.0.0
- 步⻓(Learning rate):
- 步⻓决定了在梯度下降迭代的过程中,每⼀步沿梯度负⽅向前进的⻓度。⽤前⾯下⼭的例⼦,步⻓就是在当前
这⼀步所在位置沿着最陡峭最易下⼭的位置⾛的那⼀步的⻓度。
- 步⻓决定了在梯度下降迭代的过程中,每⼀步沿梯度负⽅向前进的⻓度。⽤前⾯下⼭的例⼦,步⻓就是在当前
- 特征(feature):
- 指的是样本中输⼊部分,⽐如2个单特征的样本(x
(0), y(0)),(x(1), y(1)),则第⼀个样本特征为x(0),第⼀个样本输出为y(0)
- 指的是样本中输⼊部分,⽐如2个单特征的样本(x
- 假设函数(hypothesis function):
- 在监督学习中,为了拟合输⼊样本,⽽使⽤的假设函数,记为hθ(x)。⽐如对于单个特征的m个样本(x(i), y(i))(i = 1, 2, …m),可以采⽤拟合函数如下: hθ(x) = θ0 + θ1x。
- 损失函数(loss function):
- 为了评估模型拟合的好坏,通常⽤损失函数来度量拟合的程度。损失函数极⼩化,意味着拟合程度最好,对应
的模型参数即为最优参数。 - 在线性回归中,损失函数通常为样本输出和假设函数的差取平⽅。⽐如对于m个样本(xi, yi)(i = 1, 2, …m),采
⽤线性回归,损失函数为:
- 为了评估模型拟合的好坏,通常⽤损失函数来度量拟合的程度。损失函数极⼩化,意味着拟合程度最好,对应
在线性回归算法中,通常是先随机假设一个函数,然后得出误差函数也叫做代价函数,误差函数是一个开口向上的抛物线,误差越小我们得到的线性函数就越准确,训练的模型也就越准确,寻找误差函数最低点就是梯度下降要干的活。
2.5.2.3 梯度下降(Gradient Descent)公式
α是学习率也就是步长
2.6 梯度下降法大家族
- 全梯度下降算法(Full gradient descent),
- 随机梯度下降算法(Stochastic gradient descent),
- ⼩批量梯度下降算法(Mini-batch gradient descent),
- 随机平均梯度下降算法(Stochastic average gradient descent)
2.6.1 全梯度下降算法(FG)
具体做法也就是在更新参数时使⽤所有的样本来进⾏更新。
这个算法的准确率最高但是时间耗费也是最大的
2.6.2 随机梯度下降算法(SG)
在更新参数时随机选取一个样本来进行更新,这个算法容易陷入局部最优解
与FG算法相比时间更快了但是准确率下降了
2.6.3 ⼩批量梯度下降算法(mini-batch)
每次从训练样本集上随机抽取⼀个⼩样本集,在抽出来的⼩样本集上采⽤FG迭代更新权重。
2.6.4 随机平均梯度下降算法(SAG)
随机平均梯度算法克服了这个问题,在内存中为每⼀个样本都维护⼀个旧的梯度,随机选择第i个样本来更新此样本的
梯度,其他样本的梯度保持不变,然后求得所有梯度的平均值,进⽽更新了参数。
2.7 线性回归api
- sklearn.linear_model.LinearRegression(fit_intercept=True)
- 通过正规⽅程优化
- 参数
- fit_intercept:是否计算偏置
- 属性
- LinearRegression.coef_:回归系数
- LinearRegression.intercept_:偏置 (b)
梯度下降法:
- sklearn.linear_model.SGDRegressor(loss=“squared_loss”, fit_intercept=True, learning_rate =‘invscaling’,
eta0=0.01)- SGDRegressor类实现了随机梯度下降学习,它⽀持不同的loss函数和正则化惩罚项来拟合线性回归模型。
- 参数:
- loss:损失类型
- loss=”squared_loss”: 普通最⼩⼆乘法
- fit_intercept:是否计算偏置
- learning_rate : string, optional
- 学习率填充
- ‘constant’: eta = eta0
- ‘optimal’: eta = 1.0 / (alpha * (t + t0)) [default]
- ‘invscaling’: eta = eta0 / pow(t, power_t)
- power_t=0.25:存在⽗类当中
- 对于⼀个常数值的学习率来说,可以使⽤learning_rate=’constant’ ,并使⽤eta0来指定学习率。
- loss:损失类型
- 属性:
- SGDRegressor.coef_:回归系数
- SGDRegressor.intercept_:偏置
2.7.1 案例:波⼠顿房价预测
2.7.1.1正规方程优化:
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
"""
# 1.获取数据
# 2.数据基本处理
# 2.1 分割数据
# 3.特征工程-标准化
# 4.机器学习-线性回归
# 5.模型评估
"""
def linear_mode1():
# 1.获取数据
boston = load_boston()
print(boston)
# 2.数据基本处理
# 2.1 分割数据
x_train,x_test,y_train,y_test = train_test_split(boston.data,boston.target,test_size=0.2)
# 3.特征工程-标准化
transfer = StandardScaler()
x_train=transfer.fit(x_train)
x_test = transfer.fit(x_test)
# 4.机器学习-线性回归
estimator = LinearRegression()
estimator.fit(x_train,y_train)
print("这个模型的偏置(b)是:",estimator.intercept_)
print("这个模型的系数是:",estimator.coef_)
# 5.模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print('预测值是:',y_pre)
# 5.2 均方误差
res = mean_squared_error(y_test,y_pre)
print('误差为:',res)
2.7.1.2 梯度下降法优化:
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 linear_mode2():
# 1.获取数据
boston = load_boston()
print(boston)
# 2.数据基本处理
# 2.1 分割数据
x_train,x_test,y_train,y_test = train_test_split(boston.data,boston.target,test_size=0.2)
# 3.特征工程-标准化
transfer = StandardScaler()
x_train=transfer.fit(x_train)
x_test = transfer.fit(x_test)
# 4.机器学习-线性回归
estimator = SGDRegressor()
estimator.fit(x_train,y_train)
print("这个模型的偏置(b)是:",estimator.intercept_)
print("这个模型的系数是:",estimator.coef_)
# 5.模型评估
# 5.1 预测值
y_pre = estimator.predict(x_test)
print('预测值是:',y_pre)
# 5.2 均方误差
res = mean_squared_error(y_test,y_pre)
print('误差为:',res)
用均方误差来评估回归性能:
2.8 欠拟合、过拟合
- 过拟合:⼀个假设在训练数据上能够获得⽐其他假设更好的拟合, 但是在测试数据集上却不能很好地拟合数据,
此时认为这个假设出现了过拟合的现象。(模型过于复杂) - ⽋拟合:⼀个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据,此时认为这个
假设出现了⽋拟合的现象。(模型过于简单)
2.8.1 原因以及解决办法
- ⽋拟合原因以及解决办法
- 原因:学习到数据的特征过少
- 解决办法
- 1)添加其他特征项,
- 2)添加多项式特征
- 过拟合原因以及解决办法
- 原因:原始特征过多,存在⼀些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾各个测试数据点
- 解决办法:
- 重新清洗数据,导致过拟合的⼀个原因也有可能是数据不纯导致的,如果出现了过拟合就需要我们重
新清洗数据。 - 增⼤数据的训练量,还有⼀个原因就是我们⽤于训练的数据量太⼩导致的,训练数据占总数据的⽐例
过⼩。 - 正则化
- 减少特征维度,防⽌维灾难
- 重新清洗数据,导致过拟合的⼀个原因也有可能是数据不纯导致的,如果出现了过拟合就需要我们重
2.9 正则化
在学习的时候,数据提供的特征有些影响模型复杂度或者这个特征的数据点异常较多,所以算法在学习的时候尽量减少
这个特征的影响(甚⾄删除某个特征的影响),这就是正则化
正则化类别:
- L2正则化
- 作⽤:可以使得其中⼀些W的都很⼩,都接近于0,削弱某个特征的影响
- 优点:越⼩的参数说明模型越简单,越简单的模型则越不容易产⽣过拟合现象
- Ridge回归
- L1正则化
- 作⽤:可以使得其中⼀些W的值直接为0,删除这个特征的影响
- LASSO回归
2.9.1 正则化线性模型
-
Ridge Regression (岭回归,⼜名 Tikhonov regularization)
岭回归是线性回归的正则化版本,即在原来的线性回归的 cost function 中添加正则项(regularization term):
以达到在拟合数据的同时,使模型权重尽可能⼩的⽬的 -
Lasso Regression(Lasso 回归)
倾向于完全消除不重要的权重。
-
Elastic Net (弹性⽹络)
弹性⽹络在岭回归和Lasso回归中进⾏了折中,通过 混合⽐(mix ratio) r 进⾏控制:
- r=0:弹性⽹络变为岭回归
- r=1:弹性⽹络便为Lasso回归
岭回归api:
sklearn.linear_model.Ridge(alpha=1.0,fit_intercept=True,solver=“auto”, normalize=False)
- 具有l2正则化的线性回归
- alpha:正则化⼒度,也叫 λ
- λ取值:0~1 1~10
- solver:会根据数据⾃动选择优化⽅法
- sag:如果数据集、特征都⽐较⼤,选择该随机梯度下降优化
2.9.2 小结
常⽤:岭回归
假设只有少部分特征是有⽤的:
- 弹性⽹络
- Lasso
- ⼀般来说,弹性⽹络的使⽤更为⼴泛。因为在特征维度⾼于训练样本数,或者特征是强相关的情况下,Lasso
回归的表现不太稳定。
2.10 模型的加载和保存
from sklearn.externals import joblib
- 保存:joblib.dump(estimator, ‘test.pkl’)
- 加载:estimator = joblib.load(‘test.pkl’)
保存文件的后缀为 ‘.pkl’