K-近邻算法(K-Nearest Neighboor)
特征预处理
数据预处理的过程。数据存在不同的量纲、数据中存在离群值,需要稳定的转换数据,处理好的数据才能更好的去训练模型,减少误差的出现。
标准化
数据集的标准化对scikit-learn中实现的大多数机器学习算法来说是常见的要求,很多案例都需要标准化。如果个别特征或多或少看起来不是很像标准正态分布(具有零均值和单位方差,均值为0,单位方差为1),那么它们的表现力可能会较差。将数据处理成标准化,或者接近于正态分布的数据。
在实际情况中,我们经常忽略特征的分布形状,通过以下公式去实现:
X
′
=
x
−
m
e
a
n
σ
X'= \frac{x-mean}{\sigma}
X′=σx−mean
去均值进行中心化,样本减去均值除以向量的标准差,进行缩放。缺点:特征比较多的时候,某一个特征的方差特别大,特别大的方差在学习算法的时候占有较大的地位,导致机器学习与我们的期望产生误差。
sklearn.preprocessing.MinMaxScaler(feature_range=(0,1)...)
MinMaxScaler.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
数据预处理都在preprocessing下进行的,MinMaxScaler为标准化(归一化)的类。
- 例题:
sklearn.perprocessing.StandardScaler()
StandardScaler.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
StandardScaler也是用来标准化的,默认的参数,with_mean = True,with_std=True,默认去中心化,去标准差。
鸢尾花案例–分类
实现步骤:
- 获取数据
- 数据基本处理
- 特征工程
- 机器学习(模型训练)
- 模型评估
得到的准确率为:0.767,寻找更好的n_neighbors来得出准确率高一点的模型,n_neighbors的取值可以是{1,3,5,7…},如果在模型训练的时候循环取值,就会创建很多个分类器,可以使用交叉验证自动的传入。
交叉验证
交叉验证,也叫循环估计,将数据集切割成10份,在建模的时候,拿出大部分的去训练模型,小部分的保留进行测试,不停的进行切割,直到每一个子样的集都作为测试集之后,把得出来的每一个的结果求平均,得到返回的结果。
得到的是平均的结果,比单次的结果更加可靠,比如考试十次得到的平均结果,比偶然考试得到的结果更加稳定。
目的:为了得到可靠稳定的模型
网格搜索
网格搜索,简单的说就是手动的给出一个模型中你想要改动的所用的参数,程序自动的帮你使用穷举法来将所有的参数都运行一遍。
交叉验证、网格搜索api
sklearn.model_selection.GridSearchCV(estimator,param_grid=None,cv=None)对估计器的指定参数值进行详尽搜索
estimator:估计器对象
param_grid:估计器参数(dict){"n_neighbors":[1,3,5]}
cv: 指定几折交叉验证
fit: 输入训练数据
score: 准确率
选参数的方式:
- 交叉验证网格搜索,只适合数据量较小的,这种方法的计算量大
- 随机搜索
- 贝叶斯调参
K近邻算法-回归
KNN算法不仅能做分类的问题,还能解决回归的问题。最常用的是均方误差。预测值减去真实值平方求和,除以个数。 M S E = ∑ i = 1 m ( f ( x i ) − y i ) 2 m MSE= \frac{\displaystyle{\sum_{i=1}^{m}(f(x_i)-y_i)^2}}{m} MSE=mi=1∑m(f(xi)−yi)2
分析房子出租的情况,如果有个1室的房子,可以租多少钱。
得到的值比模型评估的均方误差值还要大,多了个特征并不是能更精确。
有房子的特征数据和房价,训练完房子的特征,传到模型里去,得出预测的房价。预测的房价与真实值之间存在误差,目标是找到最好的拟合线。
线性回归
高尔顿发现父母的身高比较高,子女也会高;父母矮,子女也会矮,如果父母双方都异常高或者异常矮,那么子女的身高会趋向于人的平均身高。皮尔逊收集了近千名成员的身高记录发现,父亲高的群体,儿辈的平均身高低于父辈的身高;父亲矮的群体,儿辈是平均身高高于父辈的身高,这样高的和矮的的儿辈一同“回归”到所有男子的平均身高,回归到中等。回归算法中最基础的就是线性回归。
线性回归定义
利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。
根据给定的楼盘价格,预测房价
上图中的点大致会回归为一条直线
y
=
k
x
+
b
y=kx+b
y=kx+b,k为斜率,b为截距,如想买100平的房子,就可以大致预测出价格大致为430000左右,房子的尺寸是特征,价格是目标(标签),线性回归算法是有监督学习的算法。
每一行都是一个样本数据,共有m个样本数据,size为特征,price为标签。
线性回归的流程如上图,用训练集训练算法,然后用算法去建模得到模型,有新的数据传进来去预测目标数据。
θ
0
θ_0
θ0为截距,
θ
1
θ_1
θ1为斜率,图中的直线为简单的一元线性回归模型,只有1个变量预测出来的,也称为单变量线性回归模型。
代价函数(cost function)
目标:找到一条最好的拟合线,使得误差最小,也就是代价函数最小。
针对给出的点有真实的y值,在预测线上有个相对于线的y值,真实值
y
i
y^i
yi与预测值
h
(
x
i
)
h(x^i)
h(xi)之间存在误差,结果
h
(
x
i
)
−
y
i
h(x^i)-y^i
h(xi)−yi有正有负,取绝对值进行求和为总误差,除以样本点的个数为均方误差。加上二分之一是为了后续计算方便,公式如下。
参数
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1是未知的,目标是找到
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,使得
j
(
θ
0
,
θ
1
)
j(θ_0,θ_1)
j(θ0,θ1)最小,简化使得截距最小,使
θ
0
=
0
θ_0=0
θ0=0,目标也变为了只求
θ
1
θ_1
θ1,使得
j
(
θ
1
)
j(θ_1)
j(θ1)最小。
理解代价函数与
j
(
θ
1
)
j(θ_1)
j(θ1)之间的关系。
下图右3个样本点,此时
θ
0
=
0
,
θ
1
=
1
θ_0=0,θ_1=1
θ0=0,θ1=1,代入到公式中,
h
(
x
)
=
x
h(x)=x
h(x)=x,得到
j
(
θ
1
)
=
0
j(θ_1)=0
j(θ1)=0,代价函数为0。
如果
θ
0
=
0
,
θ
1
=
0.5
θ_0=0,θ_1=0.5
θ0=0,θ1=0.5,
h
(
x
)
=
x
2
h(x)= \frac{x}2
h(x)=2x,代入公式中,代价函数的结果
j
(
θ
1
)
=
0.58
j(θ_1)=0.58
j(θ1)=0.58。
如果
θ
0
=
0
,
θ
1
=
0
θ_0=0,θ_1=0
θ0=0,θ1=0,
h
(
x
)
=
0
h(x)= 0
h(x)=0,画出的线与x轴完全重合,从点到线作垂线,误差是很大。
一个
θ
1
θ_1
θ1对应一个
h
(
x
)
h(x)
h(x)函数,
θ
1
=
1
θ_1=1
θ1=1时对应的是三个点连接的重合的线,
θ
1
=
0.5
θ_1=0.5
θ1=0.5时对应的一条偏离三个点向下的线,
θ
1
=
0
θ_1=0
θ1=0时对应的是与x轴重合的线。
加上
θ
0
θ_0
θ0后的图形为三维的图形,代价函数的值为曲面是深度,在同一条等高线上,
j
(
θ
0
,
θ
1
)
j(θ_0,θ_1)
j(θ0,θ1)的值是相等的。
下图中右侧每一条线都是一条等高线,每一条线上的
j
(
θ
0
,
θ
1
)
j(θ_0,θ_1)
j(θ0,θ1)是相等的,最小的圆是图形的底。图上随意取一点,对应的
θ
0
θ_0
θ0大概为800左右,对应的
θ
1
θ_1
θ1大概为-1.2左右,形成左侧的图形是个向下的蓝色线,与散点的关系不大,说明理合效果不好,意味着代价函数不是最小的,最小的在中心的位置。
下图中的
θ
0
θ_0
θ0大概为380左右,对应的
θ
1
θ_1
θ1为0,截距为380左右,斜率为0,平行于x轴,理合效果不好,代价函数也不是最小的。
假设点在底心,
θ
0
θ_0
θ0大概为220左右,对应的
θ
1
θ_1
θ1为0.12左右,截距220左右,斜率为0.12,理合出一条向上的直线,说明代价函数无限接近于最低点,局部最小值。
同一条等高线上的
j
(
θ
0
,
θ
1
)
j(θ_0,θ_1)
j(θ0,θ1)是相等的,找到
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,使得误差最小,理合效果最好。如果一个点一个点试的话,会耗费大量的时间,当特征变多的时候,维度也会变高,很难可视化图形辅助得到最终的结果。目标是通过程序来自动的寻找代价函数最小值对应的
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,可以使用梯度下降法。
梯度下降法
梯度下降法就是可以使代价函数最小化的算法,应用到代价函数中求得最优解,是个非常常用的算法,被广泛的应用到各个领域,各个算法中。
目标:找到
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,使得
j
(
θ
0
,
θ
1
)
j(θ_0,θ_1)
j(θ0,θ1)最小。
实现方式:刚开始并不知道要把
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1定义为什么样的值,要先初始化
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,然后不停的去改变
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,使得
j
(
θ
0
,
θ
1
)
j(θ_0,θ_1)
j(θ0,θ1)最小,直到找到
j
(
θ
0
,
θ
1
)
j(θ_0,θ_1)
j(θ0,θ1)的最小值或局部最小值,才停止迭代。本质上相当于循环,不停的改变
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,直到找到最优的。
上图中,图形曲线像一座山,
j
(
θ
0
,
θ
1
)
j(θ_0,θ_1)
j(θ0,θ1)相当于山的高度,要找到最小的代价函数,就是要找到山底。从最高点到最低点的时候,需要找到一个方向,相当于每走一段就要切换一次方向,重新判定应该走哪个方向,直到找到局部最低点。不同的方向得到的局部最低点是不一样的。
梯度下降法的数学应用
通过改变
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,来不停的调整方向,直到找到最优点。学习率也为梯度下降值,也就是说要移动的范围(走多大的步),
α
α
α值很大的时候,意味着走很长一段路才调整方向,梯度下降的速度就比较快;
α
α
α值比较小的时候,向下移动的速度比较慢(走路的步伐就比较小),梯度下降就比较慢。后面的内容相当于对
θ
j
θ_j
θj进行求导。
求导
在进行计算的时候,
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1要同时更新,如果说一个不变,另一个改变的话,就相当于一个方向已经稳定了,调整另外一个方向就不适合找到一个最优的解,两个同时更新的话,相当于就是360度在不停的寻找,达到最优的过程。
x轴为
θ
1
θ_1
θ1,曲线为
j
(
θ
1
)
j(θ_1)
j(θ1),此时
θ
0
θ_0
θ0为0,求导为求该点在曲线上的斜率,图上点出的斜率为正值,相减后
θ
1
θ_1
θ1就会减小,往x轴的左边移动,从曲线往下走,迭代到最优的位置,
j
(
θ
1
)
j(θ_1)
j(θ1)的最小值,曲线的最低点。
上图中,点处的斜率是为负值,
θ
1
θ_1
θ1减去负值,意味着
θ
1
θ_1
θ1逐渐增大,往x轴的右边移动,经过不停的迭代,直到x轴的最优点。
学习率
当
α
α
α比较小的时候,系数比较小,移动的速度比较慢,好比小碎步的形式去下山,要走很多步才能到达最低点,学习率小的时候,梯度下降会很慢。
当
α
α
α比较大的时候,系数比较大,对斜率的影响也比较大,
θ
1
θ_1
θ1的值变化的也比较大,如下图中,本身点已经很接近最优值了,
α
α
α比较大的时候,可能一下子就跨过最低点,到达另一个距离最低点较远的区域,使得代价函数的值跨度大,来回震荡,很难找到最优的点。
在第一个点,斜率为正,点往x轴的左侧移动,到达第二个点的时候,斜率还是为正,但是斜率变小了,整体的值也变小了,后面移动的幅度就没有那么快了,到达第三个点,斜率仍然在减小,移动的幅度就更下了。
没有必要去特意减小
α
α
α,当学习率与求导进行乘积的过程中,会有个自动调节的过程,无论
α
α
α取多少,都会有个区域最优点的过程,只是移动快慢的问题。
通过调整斜率和学习率来调整
θ
j
θ_j
θj,控制
θ
j
θ_j
θj来找到一个最低点,这是一个重复的过程,将梯度下降法应用到代价函数中。
将
h
(
x
)
h(x)
h(x)代入式子中得到:对代价函数求导,可以分别对
θ
0
θ_0
θ0,
θ
1
θ_1
θ1求偏导
对
θ
0
θ_0
θ0求偏导,得到:
对
θ
1
θ_1
θ1求偏导,得到:
根据这两个导数来优化
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1,方便对
θ
0
,
θ
1
θ_0,θ_1
θ0,θ1进行迭代,m为样本的个数,计算的是m个样本的总和。
非凸函数与凸函数
局部最优,可以得到几个最优解的都是非凸函数。没有局部最优,只有一个全局最优解的是凸函数,使用线性回归,就会收敛到全局最优,因为没有其他的全局最优。
使用numpy实现一元线性回归的梯度下降法
刚开始第0次迭代时截距b=0,斜率k=0,损失值= 2782.55,等50次迭代结束后,得到目前最优的拟合线,b=0.0305,斜率k=1.478,损失值= 56.3248。迭代次数过多,会影响到运算的效率,可以减少迭代的次数。
sklearn实现一元线性回归
直接拟合出最优的结果