吴恩达机器学习笔记

文章目录

简介

x i x^i xi代表x的i次方

x ( i ) x^{(i)} x(i)代表数据点x

x [ i ] x^{[i]} x[i]代表i层神经元层的量x

x i x_i xi代表向量x的第i个分量

有监督学习

关键特征:对训练集给出输入x和正确的输出y标签, 训练模型后给出全新的输入要求输出预计的y

回归

从无限的选项中根据模型选择其中的可能的选项,预测结果

分类

从有限的选项中选择其中最有可能的那一个,预测种类

无监督学习

无标签,不是为了找出“正确答案”,而是尝试在数据中找到可能存在的有用的结构或模式。

聚类算法

将未标记的数据放置在不同的集群中,不知道这些数据代表什么但是知道他们相似。eg:新闻与相关新闻的聚类,自动放置在同一个主题下。

异常检测

尝试找到异常的数据点

降维

压缩数据

有监督学习

回归

线性模型

模型:使用 f w , b ( x ) = w x + b f_{w,b}(x)=wx+b fw,b(x)=wx+b(也可以写成 f θ ( x ) = θ 0 + θ 1 x f_{\theta}(x)=\theta_{0}+\theta_{1}x fθ(x)=θ0+θ1x)来拟合回归的曲线,关键在于构建一个最小的成本函数。

参数:w,b或者使用参数向量来表示: θ ⃗ \vec{\theta} θ

成本函数

整个训练集的损失函数的平均。 n t r n_{tr} ntr表示训练集的大小
J ( θ ⃗ ) = 1 n t r ∑ i = 1 n t r L ( f θ ⃗ ( x ( i ) , y ( i ) ) J(\vec \theta)=\frac{1}{n_{tr}}\sum_{i=1}^{n_{tr}}L(f_{\vec \theta}(x^{(i)},y^{(i)}) J(θ )=ntr1i=1ntrL(fθ (x(i),y(i))

损失函数

单个数据与实际值的偏离程度。

L ( f θ ⃗ ( x ( i ) , y ( i ) ) = 1 2 ( y ^ ( i ) − y ( i ) ) 2 = 1 2 ( f θ ⃗ ( x ( i ) ) − y ( i ) ) 2 L(f_{\vec \theta}(x^{(i)},y^{(i)})=\frac{1}{2}(\hat{y}^{(i)}-{y}^{(i)})^2=\frac{1}{2}(f_{\vec \theta}(x^{(i)})-y^{(i)})^2 L(fθ (x(i),y(i))=21(y^(i)y(i))2=21(fθ (x(i))y(i))2

目标

尽可能的使得所有预测值 y ^ ( i ) \hat{y}^{(i)} y^(i)与实际值 y ( i ) y^{(i)} y(i)相贴近,即最小化 J ( θ ⃗ ) J(\vec \theta) J(θ )

梯度下降

更新参数以达到更加乃至最佳的参数向量。

最速下降

θ i = θ i − α ∂ J ( θ ⃗ ) ∂ θ i = θ i − α ∗ 1 n t r ∑ k = 1 n t r ( f θ ⃗ ( x ( k ) ) − y ( k ) ) x ( k ) i \theta_{i}=\theta_{i}-\alpha\frac{\partial J(\vec{\theta})}{\partial\theta_{i}}=\theta_{i}-\alpha*\frac{1}{n_{tr}}\sum_{k=1}^{n_{tr}}(f_{\vec\theta}(x^{(k)})-y^{(k)}){x^{(k)}}^i θi=θiαθiJ(θ )=θiαntr1k=1ntr(fθ (x(k))y(k))x(k)i

θ i \theta_{i} θi代表 f θ ⃗ ( x ) f_{\vec \theta}(x) fθ (x) x i x^i xi前的参数

对于 θ \theta θ向量的每一个分量而言都用上述含偏微 分的表达式进行更新其中 α \alpha α是常数,也被称为学习率,他将直接决定更新的步长,过小则迭代过慢,过大则可能不准确甚至不收敛。

同时最速下降容易得到极值点,陷入局部最优解的困局,未必是全局最优的。仅当我们使用平方误差成本函数时,他是一个凸函数,因此可以得到最优解。

随机梯度下降

在最速下降法中我们选取了所有的样本点作为更新的依据,在随机梯度下降法中我们仅仅选择其中的一个或者几个点作为依据。

表达式更新为:
θ i = θ i − α ( f θ ⃗ ( x ( k ) ) − y ( k ) ) x ( k ) i \theta_{i}=\theta_{i}-\alpha(f_{\vec \theta}(x^{(k)})-y^{(k)}){x^{(k)}}^i θi=θiα(fθ (x(k))y(k))x(k)i
其中的k是随机选取的。

或者选取其中的几个点如下:
θ i = θ i − α ∑ k ϵ K ( f θ ⃗ ( x ( k ) ) − y ( k ) ) x ( k ) i \theta_{i}=\theta_{i}-\alpha\sum_{k\epsilon K}(f_{\vec \theta}(x^{(k)})-y^{(k)}){x^{(k)}}^i θi=θiαkϵK(fθ (x(k))y(k))x(k)i

其中的K是选取的样本的集合。

多元变量的高次曲线拟合

我们使用 n x n_x nx维向量 X ⃗ = [   x 1   x 2     . . .   x n x ] \vec X=\begin{bmatrix}\ x_{1}\ \\x_{2}\ \\\ ...\ \\x_{n_{x}}\end{bmatrix} X =  x1 x2  ... xnx 来代替之前的变量x并使用下角标 x i x_i xi表示这是向量 X ⃗ \vec X X 的第i个元素,即第i个不同的特征。此时我们的参数个数应当同时取决于拟合的最高次数 n p n_{p} np和维度 n x n_x nx,应当是 n p ∗ n x n_{p}*n_{x} npnx在加上常数项。

此时我们的拟合函数由 f θ ⃗ ( x ) f_{\vec \theta}(x) fθ (x) 变成了 f θ ⃗ ( X ⃗ ) = θ ( 0 , 0 ) + θ ( 1 , 1 ) x 1 + θ ( 1 , 2 ) x 1 2 . . . + θ ( 3 , 5 ) x 3 5 . . . + θ ( i , j ) x i j f_{\vec \theta}(\vec X )=\theta_{(0,0)}+\theta_{(1,1)}x_1+\theta_{(1,2)}x_1^2...+\theta_{(3,5)}x_3^5...+\theta_{(i,j)}x_i^j fθ (X )=θ(0,0)+θ(1,1)x1+θ(1,2)x12...+θ(3,5)x35...+θ(i,j)xij

成本函数变成了
J ( θ ⃗ ) = 1 2 n t r ∑ i = 1 n t r ( y ^ ( i ) − y ( i ) ) 2 = 1 2 n t r ∑ i = 1 n t r ( f θ ⃗ ( X ⃗ ( i ) ) − y ( i ) ) 2 J(\vec \theta)=\frac{1}{2n_{tr}}\sum_{i=1}^{n_{tr}}(\hat{y}^{(i)}-{y}^{(i)})^2=\frac{1}{2n_{tr}}\sum_{i=1}^{n_{tr}}(f_{\vec \theta}(\vec X^{(i)})-y^{(i)})^2 J(θ )=2ntr1i=1ntr(y^(i)y(i))2=2ntr1i=1ntr(fθ (X (i))y(i))2
θ ( i , j ) \theta^{(i,j)} θ(i,j)代表 x i j x_i^j xij前的参数参数更新变成了:
θ ( i , j ) = θ ( i , j ) − α ∂ J ( θ ⃗ ) ∂ θ ( i , j ) = θ ( i , j ) − α ∗ 1 n t r ∑ k = 1 n t r ( f θ ⃗ ( X ⃗ ( k ) ) − y ( k ) ) x i ( k ) j \theta_{(i,j)}=\theta_{(i,j)}-\alpha\frac{\partial J(\vec \theta)}{\partial\theta_{(i,j)}}=\theta_{(i,j)}-\alpha*\frac{1}{n_{tr}}\sum_{k=1}^{n_{tr}}(f_{\vec \theta}(\vec X^{(k)})-y^{(k)}){x_i^{(k)}}^j θ(i,j)=θ(i,j)αθ(i,j)J(θ )=θ(i,j)αntr1k=1ntr(fθ (X (k))y(k))xi(k)j

如果只有多元没有高次的话,便称为多元线性模型,可以用矢量化来表达为

f θ ⃗ ( X ) = θ ⃗ ⋅ X ⃗ f_{\vec \theta}(X)=\vec \theta\cdot \vec X fθ (X)=θ X

向量化可以极高的提升代码的运行效率,其原理主要是numpy在调用dot函数的时候是并行处理乘法而后加起来的。

欠缺拟合与过拟合

欠拟合(高偏差 high bias)意味着当前的模型不能很好的贴合当前的训练集,需要增加维度或者多项式次数,过拟合(高方差high variance)意味着用过于复杂的模型尝试贴合过多的点反而不能很好的预测非训练集的点。

一个好的模型应当在尽可能的贴合训练集的基础上,尽可能的做到可以很好的预测非训练集的结果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1fU197Qf-1689044625570)(C:\Users\backordinary\AppData\Roaming\Typora\typora-user-images\image-20230629140211817.png)]

特征缩放

变量的变化范围不同,变化幅度不同,不同的变量对结果的影响大小也不同,这将直接造成对参数的选取而言部分变量有较小的变化但是对结果的影响却很大的结果。进一步造成在进行梯度下降时路径的选取可能较为粗糙。

普通缩放

为了使得得到尽可能的好的效果可以通过将变量除以可能的最大值将范围压缩到【0,1】当中e,g:若 300 ≤ x 1 ≤ 2000 300\le x_1\le 2000 300x12000可以使得 x 1 = x 1 2000 x_1=\frac{x_1}{2000} x1=2000x1

均值归一化

也可以使用均值归一化使得样本以0为中心:先求出平均值 μ 1 \mu_1 μ1

将参数重新赋值 x 1 = x 1 − μ 1 2000 − 300 x_1=\frac{x_1-\mu_1}{2000-300} x1=2000300x1μ1

Z-score 归一化

先求出平均值 μ 1 \mu_1 μ1和标准差 σ 1 \sigma_1 σ1

x 1 = x 1 − μ 1 σ 1 x_1=\frac{x_1-\mu_1}{\sigma_1} x1=σ1x1μ1

如何判断梯度下降时是否收敛

1、随着迭代次数的增加, J ( θ ⃗ ) J(\vec \theta) J(θ )的减少趋向于减少,基本不变时收敛。若反而增大,则需考虑是不是学习率过大,或者算法出问题了。

2、使用自动收敛测试:设置一个阈值 ε \varepsilon ε若是一次迭代后的减少量少于这个阈值则认为他收敛了。

选择一个好的学习率

1、手动选择一系列的值,查看 J ( θ ⃗ ) J(\vec \theta) J(θ )的图像,只选择其中稳定下降的最快的那一个

特征工程

通过你对问题的理解和直觉选择新的特征加入模型中
比如拍卖房子的原始变量是长和宽,加入面积=长*宽这一特征可以更好的拟合。

多项式回归

选择多个变量的相互组合(乘积,幂次、甚至根号等)作为特征,记得进行特征缩放,这很重要。

分类

逻辑回归

这是一个分类算法。

sigmoid函数(逻辑函数g)

g ( z ) = 1 1 + e − z = f θ ⃗ ( X ⃗ ) = 1 1 + e − θ ⃗ ⋅ X ⃗ g(z)=\frac{1}{1+e^{-z}}=f_{\vec \theta}(\vec X)=\frac{1}{1+e^{-\vec \theta\cdot \vec X}} g(z)=1+ez1=fθ (X )=1+eθ X 1
其中
z = θ ⃗ ⋅ X ⃗ z=\vec \theta\cdot \vec X z=θ X
其中 θ ⃗ \vec \theta θ 是参数向量 X ⃗ \vec X X 是可能带有任意形式如 x 1 ∗ x 2 3 x_1*x_2^3 x1x23的分量的特征的向量

上述函数将算出一个【0,1】的值用于决定当前的是更倾向于哪一种分类,是0,还是1(是1的可能性)。

一种可行的方案是将0.5设置为分割线。

决策边界

分割决策的边界,不属于0也不属于1。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HthLkJxC-1689044625571)(C:\Users\backordinary\AppData\Roaming\Typora\typora-user-images\image-20230627163250123.png)]

损失函数

背景:在由 n t r n_{tr} ntr个样本的 n x n_x nx个特征的模型中

使用线性回归的成本函数将得到非凸的成本函数,会陷入局部最优解。

应使用以下函数:
L ( f θ ⃗ ( X ⃗ ( i ) ) , y ( i ) ) { − l o g ( f θ ⃗ ( X ⃗ ( i ) ) )  if  y ( i ) = 1 − l o g ( 1 − f θ ⃗ ( X ⃗ ( i ) ) )  if  y ( i ) = 0 L(f_{\vec \theta} (\vec X^{(i)}),y^{(i)})\begin{cases} -log(f_{\vec \theta} (\vec X^{(i)})) & \text{ if } y^{(i)}=1 \\ -log(1-f_{\vec \theta} (\vec X^{(i)})) & \text{ if } y^{(i)}=0 \end{cases} L(fθ (X (i)),y(i)){log(fθ (X (i)))log(1fθ (X (i))) if y(i)=1 if y(i)=0
也可以写成下述表达式
L ( f θ ⃗ ( X ⃗ ( i ) ) , y ( i ) ) = − y ( i ) l o g ( f θ ⃗ ( X ⃗ ( i ) ) ) − ( 1 − y ( i ) ) l o g ( 1 − f θ ⃗ ( X ⃗ ( i ) ) ) L(f_{\vec \theta} (\vec X^{(i)}),y^{(i)})=-y^{(i)}log(f_{\vec \theta} (\vec X^{(i)}))-(1-y^{(i)})log(1-f_{\vec \theta} (\vec X^{(i)})) L(fθ (X (i)),y(i))=y(i)log(fθ (X (i)))(1y(i))log(1fθ (X (i)))

根据图像可以显然得出:当预测结果对真实结果的可能性越靠近的时候损失越少。可能性越偏移,其损失将急剧增加。

成本函数

使用上述损失函数,我们将得到一个凸的 成本函数如下:
J ( θ ⃗ ) = − 1 n t r ∑ i = 1 n t r [ y ( i ) l o g ( f θ ⃗ ( X ⃗ ( i ) ) ) + ( 1 − y ( i ) ) l o g ( 1 − f θ ⃗ ( X ⃗ ( i ) ) ) ] J(\vec \theta)=-\frac{1}{n_{tr}}\sum_{i=1}^{n_{tr}}[y^{(i)}log(f_{\vec \theta} (\vec X^{(i)}))+(1-y^{(i)})log(1-f_{\vec \theta} (\vec X^{(i)}))] J(θ )=ntr1i=1ntr[y(i)log(fθ (X (i)))+(1y(i))log(1fθ (X (i)))]

参数更新

θ ( i , j ) = θ ( i , j ) − α ∂ J ( θ ⃗ ) ∂ θ ( i , j ) = θ ( i , j ) − α ∗ 1 n t r ∑ k = 1 n t r ( f θ ⃗ ( X ⃗ ( k ) ) − y ( k ) ) x i ( k ) j \theta_{(i,j)}=\theta_{(i,j)}-\alpha\frac{\partial J(\vec \theta)}{\partial\theta_{(i,j)}}=\theta_{(i,j)}-\alpha*\frac{1}{n_{tr}}\sum_{k=1}^{n_{tr}}(f_{\vec \theta}(\vec X^{(k)})-y^{(k)}){x_i^{(k)}}^j θ(i,j)=θ(i,j)αθ(i,j)J(θ )=θ(i,j)αntr1k=1ntr(fθ (X (k))y(k))xi(k)j

解决过拟合

1、使用更大的数据集,扩展样本。

2、尝试使用更少,但是足够的特征。

3、正则化,保留所有的特征,但是对于高次数的

特征,我们使用尽可能小的参数来避免他对模型产生较大的影响。

正则化解决过拟合

为我们的成本函数加上正则化项用于惩罚参数的大小对模型的影响,注意到的是当参数变大时惩罚性应当急剧变大 ,比如修改线性回归的成本函数为:
J ( θ ⃗ ) = 1 2 n t r ∑ i = 1 n t r ( f θ ⃗ ( X ⃗ ( i ) − y ( i ) ) 2 + λ 2 n t r ∑ j = 1 n x ∗ n p θ ⃗ j 2 J(\vec \theta)=\frac{1}{2n_{tr}}\sum_{i=1}^{n_{tr}}(f_{\vec \theta}(\vec X^{(i)}-{y}^{(i)})^2+\frac{\lambda }{2n_{tr}}\sum_{j=1}^{n_x*n_{p}}\vec \theta_j^2 J(θ )=2ntr1i=1ntr(fθ (X (i)y(i))2+2ntrλj=1nxnpθ j2
前项用于训练你的模型,后向用于保持 θ j \theta_j θj尽可能小,而 λ \lambda λ用于指定相对权衡这两个目标以获得平衡,z值得注意的是用 λ 2 n t r \frac{\lambda}{2n_{tr}} 2ntrλ是为了使得两项以相同的方式放缩,以方便 λ \lambda λ取值。

线性回归模型的正则化

成本函数为:
J ( θ ⃗ ) = 1 2 ∗ n t r ∑ i = 1 n t r ( f θ ⃗ ( X ⃗ ( i ) − y ( i ) ) 2 + λ 2 n t r ∑ j = 1 n x ∗ n p θ ⃗ j 2 J(\vec \theta)=\frac{1}{2*n_{tr}}\sum_{i=1}^{n_{tr}}(f_{\vec \theta}(\vec X^{(i)}-{y}^{(i)})^2+\frac{\lambda }{2n_{tr}}\sum_{j=1}^{n_x*n_{p}}\vec \theta_j^2 J(θ )=2ntr1i=1ntr(fθ (X (i)y(i))2+2ntrλj=1nxnpθ j2
参数更新:
θ ( i , j ) = θ ( i , j ) − α ∂ J ( θ ⃗ ) ∂ θ ( i , j ) = θ ( i , j ) − α ∗ [ 1 n t r ∑ k = 1 n t r ( f θ ⃗ ( X ⃗ ( k ) ) − y ( k ) ) x i ( k ) j + λ n x ∗ n p θ ( i , j ) ] \theta_{(i,j)}=\theta_{(i,j)}-\alpha\frac{\partial J(\vec \theta)}{\partial\theta_{(i,j)}}=\theta_{(i,j)}-\alpha*[\frac{1}{n_{tr}}\sum_{k=1}^{n_{tr}}(f_{\vec \theta}(\vec X^{(k)})-y^{(k)}){x_i^{(k)}}^j+\frac{\lambda}{n_x*n_{p}}\theta_{(i,j)}] θ(i,j)=θ(i,j)αθ(i,j)J(θ )=θ(i,j)α[ntr1k=1ntr(fθ (X (k))y(k))xi(k)j+nxnpλθ(i,j)]
其中 θ ( i , j ) = = θ ( i − 1 ) ∗ n p + j \theta_{(i,j)}==\theta_{(i-1)*n_p+j} θ(i,j)==θ(i1)np+j

也可以写成以下形式:
θ ( i , j ) = θ ( i , j ) ∗ ( 1 − α λ n t r ) − α ∗ 1 n t r ∑ k = 1 n t r ( f θ ⃗ ( X ⃗ ( k ) ) − y ( k ) ) x i ( k ) j \theta_{(i,j)}=\theta_{(i,j)}*(1-\alpha\frac{\lambda}{n_{tr}})-\alpha*\frac{1}{n_{tr}}\sum_{k=1}^{n_{tr}}(f_{\vec \theta}(\vec X^{(k)})-y^{(k)}){x_i^{(k)}}^j θ(i,j)=θ(i,j)(1αntrλ)αntr1k=1ntr(fθ (X (k))y(k))xi(k)j

神经网络(深度学习)

他将自己学习如何设计特征而无需手动设计特征、做特征工程。神经网络应当计算出他在某个隐藏层中使用的特征是什么。

神经元

使用一个核函数构建一个模型(如逻辑回归中的函数和模型),接受输入,并输出对应的结果作为输入传递给下一层的神经元。

神经元层

将处在相同输入性质(传递次数)的多个神经元划分为一个层级,主要的是输入层接收原始输入,输出层输出最后的结果。 中间传递的数据也被称为激活值。

每层输入一个向量并输出另一个数字向量。
使用 x [ i ] x^{[i]} x[i]来表示当前的参数或数据是第i层神经元的参数或数据。
每层输出的激活向量表示为 a ⃗ [ i ] \vec a^{[i]} a [i]则其第j个分量的更新表达式为:
a j [ l ] = g ( θ ⃗ j [ l ] ⋅ a ⃗ [ l − 1 ] ) {a}_j^{[l]}=g(\vec \theta_j^{[l]}\cdot\vec a^{[l-1]}) aj[l]=g(θ j[l]a [l1])
其中 θ ⃗ j [ l ] \vec \theta_j^{[l]} θ j[l]表示第l层的神经元层的第j个神经元的参数向量

前向传播算法

是用于预测的算法,在参数以及固定的情况下将输入依次经过各层隐藏层得到最后的输出。

他的典型的神经网络架构为从输入层到输出层,神经元数量是递减的。

tensorflow的数据存储

tensorflow使用2维的张量(区别于矩阵,是tensorflow的存储类)进行存储比如[[100,132]]是一个1*2的张量,而numpy会比较惯用一维数组来进行输入如[100,132]

tensorflow的神经网络搭建

可以将多层的神经元层搭建在一起形成一个神经网络:

layer_1 = Dense(unit=3, activation="sigmoid")
layer_2 = Dense(unit=1, activation="sigmoid")
model = Senquential([layer_1, layer_2])#顺序串联在一起
...
model.compile(loss=BinaryCrossentropy())#指出损失函数以编译
model.fit(x,y,epochs=100)#训练,指出收敛步数
model.predict(x_new)#预测
dense背后的算法逻辑
#方案1
def dense(A_in,W,B):
	units = W.shape[1]#第1维度(0开始的下标)的大小
	A_out = np.zeros(units)
	for j in range(units)
    	w = W[:,j]#取出同一列的元素组成行向量
        z = np.dot(w,A_in)+B[j]#等价于w*A_in^T或A_in*w^T
        A_out[j] = g(z)
    return A_out
#方案2
def dense(A_in,W,B):
	Z=np.matmul(A_in,W) + B#另一种写法是 Z=A_in @ W + B
    A_out = g(Z)
    return A_out
#模型是3层的神经元,输入两个参数
X=np.array([[200,17]])
#参数的格式为3个列向量组成的矩阵,一个列向量代表一个神经元的参数
W=np.array([[1,-3,5],
           [-2,4,-6]])
B=np.array([-1,1,2])
layer_1 = dense(X,W,B)

此处我们定义的是一个给定参数,输入的函数,对于numpy而言dot()和matmul()的执行效率远高于单纯的使用for循环,因为会有许多底层的并行计算。

神经网络的学习过程
二元交叉熵函数

L ( f θ ⃗ ( X ⃗ ( i ) ) , y ( i ) ) = − y ( i ) l o g ( f θ ⃗ ( X ⃗ ( i ) ) ) − ( 1 − y ( i ) ) l o g ( 1 − f θ ⃗ ( X ⃗ ( i ) ) ) L(f_{\vec \theta} (\vec X^{(i)}),y^{(i)})=-y^{(i)}log(f_{\vec \theta} (\vec X^{(i)}))-(1-y^{(i)})log(1-f_{\vec \theta} (\vec X^{(i)})) L(fθ (X (i)),y(i))=y(i)log(fθ (X (i)))(1y(i))log(1fθ (X (i)))

此时的 f θ ⃗ ( X ⃗ ( i ) ) f_{\vec \theta} (\vec X^{(i)}) fθ (X (i))指的是神经网络的整体输出。

反向传播

用于计算参数更新中的偏导数项。在神经网络中参数的传播是从输出层到输入层的,其遵循的是链式法则
θ ( i , j ) [ l ] = θ ( i , j ) [ l ] − α ∂ J ( θ ⃗ ) ∂ θ ( i , j ) = θ ( i , j ) [ l ] − α ∗ 1 n t r ∑ k = 1 n t r ( f θ ⃗ ( X ⃗ ( k ) ) − y ( k ) ) x i ( k ) j \theta_{(i,j)}^{[l]}=\theta_{(i,j)}^{[l]}-\alpha\frac{\partial J(\vec \theta)}{\partial\theta_{(i,j)}}=\theta_{(i,j)}^{[l]}-\alpha*\frac{1}{n_{tr}}\sum_{k=1}^{n_{tr}}(f_{\vec \theta}(\vec X^{(k)})-y^{(k)}){x_i^{(k)}}^j θ(i,j)[l]=θ(i,j)[l]αθ(i,j)J(θ )=θ(i,j)[l]αntr1k=1ntr(fθ (X (k))y(k))xi(k)j

python自动求导

使用Syspy包

import Symtpy
J,w = sympy.symbols('J,w')
J = W**3
print(J)
dj_dw = sympy.diff(J,w)#求导
print(dj_dw)
dj_dw.subs([(w,2)])#dai'ru
计算图
sigmoid函数的替代激活函数

线性 : g ( z ) = z g(z)=z g(z)=z
ReLU : g ( z ) = m a x ( 0 , z ) g(z)=max(0,z) g(z)=max(0,z)
sigmoid : g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+ez1

softmax : 见后,是sigmoid的推广,用于多分类

如何选择激活函数

可以为神经网络中不同的神经元选择不同的激活函数。

根据y值选择输出层:

​ 二元分类问题:sigmoid较为合适。

​ 回归问题:不同情况。

​ 非负值:ReLU

隐藏层:

​ 最常见:ReLU 原因:sigmoid在两处变得较为平坦,在计算J时多出梯度下降呈现阶梯式下降,较难收敛。

为什么激活函数很重要

若全部使用线性激活函数,整个神经网络将变得和线性回归模型差不多(可以将参数更新的表达式迭代带入求证)。全部使用线性做隐藏,逻辑做输出,等价于逻辑回归模型。因此,隐藏层尽量不使用线性激活函数。

多分类问题

对于多分类问题我们使用的是softmax回归,他是逻辑回归的泛化模型。我们记当前为 n c l a s s n_{class} nclass分类问题 z i = θ ⃗ i ⋅ X ⃗ + b i z_i=\vec \theta_i \cdot \vec X+b_i zi=θ iX +bi则输出项为:
a i = g ( z 1 , z 2 . . . , z n c l a s s ) = e z i ∑ j = 1 n c l a s s e z i = P ( y = i ∣ X ⃗ ) a_i=g(z_1,z_2...,z_{n_{class}})=\frac{e^{z_i}}{\sum_{j=1}^{n_{class}}e^{z_i}}=P(y=i|\vec X) ai=g(z1,z2...,znclass)=j=1nclasseziezi=P(y=iX )
他代表当前为i 的可能性为多少。

损失函数

SparseCategoricalCrossentropy()
L ( a 1 , . . . a n c l a s s , y ( i ) ) { − l o g ( a 1 )  if  y ( i ) = 1 − l o g ( a 2 )  if  y ( i ) = 2 . . . − l o g ( a n c l a s s )  if  y ( i ) = n c l a s s L(a_1,...a_{n_{class}},y^{(i)})\begin{cases} -log(a_1) & \text{ if } y^{(i)}=1 \\ -log(a_2) & \text{ if } y^{(i)}=2 \\ ... \\ -log(a_{n_{class}}) & \text{ if } y^{(i)}=n_{class} \end{cases} L(a1,...anclass,y(i)) log(a1)log(a2)...log(anclass) if y(i)=1 if y(i)=2 if y(i)=nclass

输出层

softmax的输出层的神经元个数不再是一个,而是等同于分类个数。

layer_out = Dense(units=10,actication=‘softmax’)

输出层减少精度误差
layer_out = Dense(units=10,actication='linear')#此时使用线性激活函数
...
model.compile(loss = SparseCrossEntropy(from_logits = True))
model.fit(X,Y,epochs = 100)
logits = model(X)

最后一层将不再输出 a 1 . . . a 10 a_1...a_{10} a1...a10而是输出他的输入 z 1 . . . z 10 z_1...z_{10} z1...z10

因此在做出预测的时候也需要做出相应改变

f_x = tf.nn.softmax(logits)

对于逻辑回归也可以用以上方式来减少中间变量对损失函数的精度误差影响。

多标签分类

同一个输入可能对应着许多众多的标签值。比如图像输入,有可能存在标签值:是否为车、是否为人、是否是建筑等。

一种解决方案是将建立和标签值相同数量的模型,但这不太合理

另一种解决方案是,将输出层的神经元建立为标签数量的神经元 ,对于这一层的这三个神经元我们使用sigmoid激活函数

高级优化

不使用梯度下降算法,使用Adam算法。

Adam (Adaptive Moment Estimation)

不使用相同的全局Alpha值,而是对每个参数采用不同的学习率,同时自动调整学习率的值,达到每次下降的时候尽可能好的快速、准确的下降。

使用时如下:

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True))

主要修改的就是参数optimizer的值。

其他不同类型的网络层

之前我们使用的基本上都是密集层(每个神经元使用前一层的所有激活值),实际上另一种使用的不同类型的层:卷积层(单个神经元仅使用部分前一层的激活)。

优点:计算快速,数据需求更少。

提高性能

评估性能

给出测试集(将数据分为训练集和测试集),其成本函数为其中一个性能指标

也可以进一步划分数据为:1、训练集 2、交叉验证集 3、测试集。
在交叉验证集上评估参数并计算其成本函数,将成本最低的作为合适的模型。而测试集将作为这个模型最终性能表现的评估指标。

精准率与召回率

对于一些数据如果样本比例不是近似1:1,只评估正确分类的性能可能出现较大的误差,比如某稀有的遗传疾病在人群中仅占0.5%我们不能只评估是否正确分类,不然全部输出0的情况准确率高达99.5%。看起来很高,但显然不是优秀的模型。
我们将样本结果分为四种:TP(true positive)、FP(false positive)、FN(false negative)、TN(true negative)分别代表正确预测为P、不是P但是错分类为P、不是N但错分为N、正确预测为N的情况。
精准率(精确度Precision):预测为P时多大可能确实是P的
P = T P T P + F P = T P 所有预测为 P P=\frac{TP}{TP+FP}=\frac{TP}{所有预测为P} P=TP+FPTP=所有预测为PTP
召回率(Recall):所有事实上的P有多少被预测为P的比例
R = T P T P + F N = T P 所有真的为 P R=\frac{TP}{TP+FN}=\frac{TP}{所有真的为P} R=TP+FNTP=所有真的为PTP

精准率与召回率的权衡

对于逻辑回归模型,处理结果的阈值可能会影响最终的精准率和召回率,比如我们不采用0.5而是采用0.9 那么划分为1的情况将下降精准率上升但召回率下降。通过改变阈值绘制精准率-召回率曲线可以在两者间权衡,选择一个较为合理的阈值。

也可以使用F1 score来权衡二者:
F 1 s c o r e = 1 1 2 ( 1 P + 1 R ) F_1 score = \frac{1}{\frac{1}{2}(\frac{1}{P}+\frac{1}{R})} F1score=21(P1+R1)1
上式其实也就是精准率和召回率的调和平均数。

方差与偏差

高偏差:训练集的成本高且交叉测试集的成本也高,这意味着欠拟合

高方差:交叉测试集的成本远高于训练集,这意味着过拟合

部分数据很好的拟合而部分不好的情况下甚至可能同时出现高偏差和高方差。

评判标准

建立基准水平。比如对于语音识别,将准确率与正常人的语音识别准确性作为比较,相差大则出现高偏差。

比较训练集的准确性和交叉测试集的准确性偏差是否巨大(比较【训练集与基准水平的差值】与【训练集的和交叉测试集的差值】两者之间的差距或是由基准水平得出的标准),相差大则出现高方差。

参数与模型选择

根据交叉验证的结果通过修改正则化的系数 λ \lambda λ、选择不同拟合的次数,选择最优化的系数和次数

值得注意的是在欠拟合的情况下,添加数据量可能不能很好的解决问题。而对于过拟合的情况反而可以解决交叉测试集的成本过高问题。

错误分析

寻找到算法错分的部分,尝试将它们分组成为相同的主题(属性或特征)。比如你会发现邮件分类错把垃圾邮件分类为正常邮件的一类是那些故意将部分单词拼写错误的(w4tches、med1cine)、故意漏字母的等

数据添加
数据增强

可以通过改变原始数据但是不改变标签的方式来扩大数据集。比如对文字识别的原始图像进行PS的扭曲、模糊、旋转等操作后的数据加入训练集;对声音识别的加入背景音、噪声、部分的失真等

数据合成

通过文字的变体、颜色的改变、改变字体等不妨碍最终标签值的方式来生成大量数据

迁移学习

神经网络使用其他学习模型的参数,但是将最后一层输出层转化为你的输出层,并重新训练该层的参数。

机器学习项目全周期

1、确定项目范围;eg:

2、收集数据

3、训练模型、 错误分析、迭代改进、乃至回到步骤2

4、部署项目

决策树

学习

选择根节点的决策特征,根据特征划分子集。若子集以及纯净,则无需再划分,是混杂的则需继续划分。

停止划分条件:1、此节点完全纯净。 2、若划分到最深的深度还没有纯净,也不再划分。 3、纯净值低于一个阈值(继续划分的收益过小) 4、某节点的样本数过少

纯度

定义样本的混乱程度:熵
H ( p 1 ) = − p 1 l o g 2 ( p 1 ) − p 0 l o g 2 ( p 0 ) = − p 1 l o g 2 ( p 1 ) − ( 1 − p 1 ) l o g 2 ( 1 − p 1 ) H(p_1)=-p_1log_2(p_1)-p_0log_2(p_0)=-p_1log_2(p_1)-(1-p_1)log_2(1-p_1) H(p1)=p1log2(p1)p0log2(p0)=p1log2(p1)(1p1)log2(1p1)
目标是尽可能减少熵

选择一种拆分方式

计算每一种方式熵的加权平均,选择其中最小的一种方式。权重是各子集的样本数量占比。比如拆分后的左集有5个样本其中有4个猫,右集有10个样本其中猫有1个则加权平均值= 5 15 H ( 0.8 ) + 10 15 H ( 0.1 ) \frac{5}{15}H(0.8)+\frac{10}{15}H(0.1) 155H(0.8)+1510H(0.1)

信息增益

所谓信息增益为 当前节点的熵 − 拆分后熵的加权平均 当前节点的熵-拆分后熵的加权平均 当前节点的熵拆分后熵的加权平均比如上式中当前节点猫的占比为 5 15 \frac{5}{15} 155那么该方案的信息增益为 H ( 1 3 ) − ( 5 15 H ( 0.8 ) + 10 15 H ( 0.1 ) ) H(\frac{1}{3})-(\frac{5}{15}H(0.8)+\frac{10}{15}H(0.1)) H(31)(155H(0.8)+1510H(0.1))

如果信息增益过小,也选择不拆分。

也可以形式化的写成以下形式:
= H ( p 1 r o o t ) − ( w l e f t H ( p 1 l e f t + w r i g h t H ( p 1 r i g h t ) =H(p_1^{root})-(w^{left}H(p_1^{left}+w^{right}H(p_1^{right}) =H(p1root)(wleftH(p1left+wrightH(p1right)

学习全过程

1、从根节点开始

2、计算每种特征的信息增益,选择其中最大的一个进行拆分

3、使用上一步选择的特征拆分当前节点创建左右子树

4、重复上述步骤直至下述条件之一满足:

​ 1)节点完全纯净

​ 2)超过最大深度

​ 3)信息增益过小

​ 4)节点的样本数量过小

独热码

将一个拥有多个选择的特征转化为多个仅有两种选择的特征,比如耳朵特征有方耳、圆耳、竖耳三种选择,转化为是否有方耳、是否有圆耳、是否有竖耳三种特征。

处理连续数据

选择一个阈值,以这个阈值划分0/1。 阈值的选择应当是可以获得最佳的信息增益的。一种通常的做法是排序后选择中间的一些值进行尝试

作为回归的决策树

正常使用特征作为分割的依据,但是构建回归树的时候目的是减少样本内部的方差而非熵,对于最终的叶子节点我们根据其中的标签值作为预测依据,通常可以使用其平均值作为预测。

决策树集合

不使用单个决策树的原因:对于样本的很微小的改变可能使得决策树的决策发生巨大的变化,从而造成树的形状也有很大的变化。

使用多个决策树进行预测,根据他们的结果进行投票,票多的认为是预测结果。

带放回取样

为了得到不同的决策树集合,我们对原始数据集采用带放回的取样方式来得到每一个决策树实际采用的随机训练数据集

随机森林

对于给出的m大小的训练集

for b=1 to B:
	带放回的取样得到大小为m的训练集
    在新的训练集上训练决策树

对于上述的B常用的大小为100、64等。过大可能收益递减。

对于每个节点我们可能并不采用全部的特征比较信息增益,而是随机选取k个特征进行比较。

对于k的取值我们常常使用 n \sqrt{n} n 其中n是特征的总数。

XGBoost 增强决策树模型

boosting的核心思想在于我们将更多的注意力集中到之前错分的把部分数据当中,并根据这部分表现不良的数据子集上获得新的决策树。

for b=1 to B:
	带放回的取样得到大小为m的训练集
		但是对于之前错分的数据要比其他数据有更大的概率作为取得的样本
    在新的训练集上训练决策树

其中较好的一个实现就是XGBoost

以下是他的两种使用实例:

from xgboost import XGBClassifier

model = XGBClassifier()

model.fit(X_train, y_train)
y_pred = model.predict(X_test)
from xgboost import XGBRegressor

model = XGBRegressor()

model.fit(X_train, y_train)
y_pred = model.predict(X_test)

决策树与神经网络对比

对于表格型的数据可能决策时表现较高。对于非结构化的数据比如图像、声音而言神经网络较为优异。

决策树的训练速度很快。

较小的决策树对人类而言较为容易理解,可解释性较强。

神经网络可以进行迁移学习,从而对数据进行预训练。

对于由多个机器学习模型协同工作的系统而言神经网络串在一起可能比多个决策树容易。神经网络可以串联在一起训练,但是决策树一次只能训练一颗树。

无监督学习

聚类

查看大量数据并自动找到彼此相关、相似的数据点。没有标签值。

K-Means

算法内容

直观理解:先尝试随机猜测集群的中心点(簇质心)。再尝试去移动这个质心 。

具体的做法是遍历后将每个点标记成对应的簇中心的同类,然后将簇质心移动到所有同类的平均值然后重复以上步骤。

1、随机初始化K个簇质心(包含所有特征的多维向量)

μ 1 \mu_1 μ1, μ 2 \mu_2 μ2, . . . ... ..., μ K \mu_K μK

2、 将所有点分配给不同的质心,可以根据L2范式作为距离的衡量指标。

for i =1 to m
	c[i] = 所有 簇中心 中最靠近的那一个的索引

3、移动簇中心的位置

for k =1 to K
	U[k] = 同一个簇的平均值

如果某个簇中心没有得到样本,可以选择重新roll一下簇中心的位置,或者可以选择将簇中心的数量减少1。

成本函数

看起来上述算法没有一个明确的成本函数,实际上他的成本函数如下:
J ( c ( 1 ) , . . . , c ( m ) , μ 1 . . . , μ K ) = 1 m ∑ i = 1 m ∣ ∣ x ( i ) − μ c ( i ) ∣ ∣ 2 J(c^{(1)},...,c^{(m)},\mu_{1}...,\mu_{K})=\frac{1}{m}\sum_{i=1}^{m}||x^{(i)}-\mu_{c^{(i)}}||^2 J(c(1),...,c(m),μ1...,μK)=m1i=1m∣∣x(i)μc(i)2
直观的讲,他在尝试将系统中 簇中的点到其所属的簇中心的距离最小化。

他也被称为失真函数。

通过上述的成本函数我们再来看上述的算法会发现他的两个步骤都在保证算法的每一步都在尝试减少成本函数,最终会保证他是收敛的,但是可能会陷入局部最优解但是并非全局最优。

初始化K-means

选择一个k<m,随机选择K个训练样本作为簇中心。

减少局部最优解

对于以上的算法重复做50-1000次。给出不同的随机初始条件运行k-means然后计算最终结果的成本函数,选择其中成本最小的那几个。

选择簇中心数量

簇中心的数量并非是一定的,哪怕是不同的人来选择说出看到的簇中心的数量也未必一致。

一种尝试的方法被称为肘法,尝试多种k并绘制成本关于K的函数图像。随着K变大成本逐渐降低我们可以选择一个由成本快速下降转变为缓慢下降的点。

异常检测算法

算法作用

查看未标记的正常数据集,学会检测异常或异常事件发出危险信号。

密度估计

找出每个特征有较高的概率是什么样的取值,较低的概率是那些取值。

选择一个阈值,对于测试样本而言如果可能性小于这个值那么就标记为异常。

高斯分布(正态分布)

p ( x ) = 1 2 π σ e − ( x − μ ) 2 2 σ 2 p(x)=\frac{1}{\sqrt{2\pi}\sigma}e^{\frac{-(x-\mu)^2}{2\sigma^2}} p(x)=2π σ1e2σ2(xμ)2

对于最大似然估计的时候我们选择的 μ \mu μ取值为 μ = 1 m ∑ i = 1 m x ( i ) \mu=\frac{1}{m}\sum_{i=1}^{m}{x^{(i)}} μ=m1i=1mx(i), σ 2 = 1 m ∑ i = 1 m ( x ( i ) − μ ) 2 \sigma^2=\frac{1}{m}\sum_{i=1}^{m}{(x^{(i)}-\mu)^2} σ2=m1i=1m(x(i)μ)2也有选择将上式中的 1 m \frac{1}{m} m1换成 1 m − 1 \frac{1}{m-1} m11

异常检测算法

对于训练集X有M个训练样本,每个样本有n个特征。
X = { x ⃗ ( 1 ) , . . . , x ⃗ ( m ) } X=\{ \vec{x}^{(1)},...,\vec{x}^{(m)} \} X={x (1),...,x (m)}

x ⃗ ( 1 ) = { x 1 , x 2 , . . . , x n } ( 1 ) \vec{x}^{(1)}=\{x_1,x_2,...,x_n\}^{(1)} x (1)={x1,x2,...,xn}(1)

对于一个样本我们定义他的可能性如下(忽略了特征间的物理独立性)
P ( x ⃗ ) = ∏ i = 1 n P ( x i ; μ i , σ i 2 ) P(\vec{x})=\prod_{i=1}^n{P(x_i;\mu_i,\sigma_i^2)} P(x )=i=1nP(xi;μi,σi2)
1、选择n个特征 x i x_i xi

2、对于每个特征计算 μ j = 1 m ∑ i = 1 m x j ( i ) {\mu_j}=\frac{1}{m}\sum_{i=1}^{m}{{x_j^{(i)}}} μj=m1i=1mxj(i)以及 σ j 2 = 1 m ∑ i = 1 m ( x j ( i ) − μ j ) 2 \sigma_j^2=\frac{1}{m}\sum_{i=1}^m{(x_j^{(i)}-\mu_j)^2} σj2=m1i=1m(xj(i)μj)2

其中部分也可写成如此 μ ⃗ = 1 m ∑ i = 1 m x ⃗ ( i ) \vec{\mu}=\frac{1}{m}\sum_{i=1}^{m}{\vec{x}^{(i)}} μ =m1i=1mx (i)

3、根据上一步训练的参数对给出的样本 x ⃗ \vec{x} x 计算 P ( x ⃗ ) P(\vec{x}) P(x )比较这个概率是大还是小。对于小于阈值的标记为异常。

值得注意的是只要有一个特征特别大或者特别小上式得到的概率都将会特别小

评估学习算法的方法 (实数评估)

需要少量的带有标记的数据集建立交叉验证集与测试集,利用交叉验证集的结果来调整阈值的大小。

异常检测与监督学习对比

异常监督用于极少量的p样本,大量的n样本。而监督学习适用于有大量的p样本和n样本。

异常监督用于意料之外的结果,即,无法从有限的p样本中推断出n样本究竟是什么样的情况,即,出错的方式千奇百怪。
而监督学习用于有足够量的p样本用于算法得到p样本的情况到底如何,将来预测的样本将和训练集比较相似。

异常检测的特征选取技巧

将选择的特征尝试将他进行变化使得他的形状更加贴合高斯分布。比如使得 x 2 = l o g ( x 2 + C ) x_2=log(x_2+C) x2=log(x2+C)或者 x 2 = x 2 0.5 x_2=x_2^{0.5} x2=x20.5

值得注意的是无论你对训练数据进行了什么样的变化,将来应用或测试时的数据一定也要进行相应的数据处理,比如说交叉验证集和测试集的数据。

错误分析

对于那些错分为正常的我们分析为什么我们认为他是异常的,尽管他的这些特征看起来和正常的区别不大,或许我们可以通过这个错误找出帮助我们分辨异常的新的特征。

推荐系统

背景

例如对于影院推荐,我们对每个电影取特征,比如这个电影有多少动作片的成分、多少爱情…我们对每一个用户j的观影打分可以预测为 w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) \vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)} w (j)x (i)+b(j)代表用户j拟合的参数向量与特征的点积加上常数向量。

我们定义含义如下:

r ( i , j ) = 1 r(i,j)=1 r(i,j)=1表示:j用户给i电影评分了
y ( i , j ) y^{(i,j)} y(i,j)表示:j用户给i电影打的分
w ⃗ ( j ) , b ( j ) \vec{w}^{(j)},b^{(j)} w (j),b(j)表示:是j用户的参数
x ⃗ ( i ) \vec{x}^{(i)} x (i)表示:i电影的特征向量
w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) \vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)} w (j)x (i)+b(j)表示:预测公式
m ( j ) m^{(j)} m(j)表示:j用户预测的电影总数

那么该用户曾经用于给其他电影打的分数将会成为该用户的训练样本。

那么我们可以得到学习预测打分的成本函数如下:
1 2 m ( j ) ∑ i : r ( i , j ) = 1 ( w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) ) 2 + λ 2 m ( j ) ∑ k = 1 n ( w k ( j ) ) 2 \frac{1}{2m^{(j)}}\sum_{i:r(i,j)=1}{(\vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)})^2}+\frac{\lambda}{2m^{(j)}}\sum_{k=1}^n{(w_k^{(j)})^2} 2m(j)1i:r(i,j)=1(w (j)x (i)+b(j))2+2m(j)λk=1n(wk(j))2
忽略掉分母相同的部分将同时将目光放到所有的顾客当中,那么我们的成本函数为
∑ j = 1 n u ∑ i : r ( i , j ) = 1 ( w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) − y ( i , j ) ) 2 + λ ∑ j = 1 n u ∑ k = 1 n ( w k ( j ) ) 2 \sum_{j=1}^{n_u} \sum_{i:r(i,j)=1}{(\vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)}-y^{(i,j)})^2}+\lambda \sum_{j=1}^{n_u} \sum_{k=1}^n{(w_k^{(j)})^2} j=1nui:r(i,j)=1(w (j)x (i)+b(j)y(i,j))2+λj=1nuk=1n(wk(j))2

协同过滤算法

对于上述的过程我们是已知已经提取出了每个电影的特征 x ⃗ ( i ) \vec{x}^{(i)} x (i)但是特征是如何提取的呢。为了引出协同过滤算法,我们假设我们如今已经通过某种方式知道了部分用户的参数 w ( j ) w_{(j)} w(j)为了得到特征 x ⃗ ( i ) \vec{x}^{(i)} x (i)我们应该训练他使得 w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) \vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)} w (j)x (i)+b(j)贴近实际值。

那么每一个用户对于这个电影的打分都是他的训练样本。

忽略相同的常数项的影响那么我们可以得到学习如何提取特征的成本函数如下:
∑ j : r ( i , j ) = 1 ( w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) − y ( i , j ) ) 2 + λ ∑ k = 1 n ( x k ( i ) ) 2 \sum_{j:r(i,j)=1}{(\vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)}-y^{(i,j)})^2}+\lambda\sum_{k=1}^n{(x_k^{(i)})^2} j:r(i,j)=1(w (j)x (i)+b(j)y(i,j))2+λk=1n(xk(i))2

若我们要学习所有电影的特征提取我们的成本函数如下:
∑ i = 1 n m ∑ j : r ( i , j ) = 1 ( w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) − y ( i , j ) ) 2 + λ ∑ i = 1 n m ∑ k = 1 n ( x k ( i ) ) 2 \sum_{i=1}^{n_m} \sum_{j:r(i,j)=1}{(\vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)}-y^{(i,j)})^2}+\lambda \sum_{i=1}^{n_m} \sum_{k=1}^n{(x_k^{(i)})^2} i=1nmj:r(i,j)=1(w (j)x (i)+b(j)y(i,j))2+λi=1nmk=1n(xk(i))2

将预测的算法和训练样本的算法结合到一起我们可以得到协同过滤算法的成本函数如下:
∑ ( i , j ) : r ( i , j ) = 1 ( w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) − y ( i , j ) ) 2 + λ 1 ∑ j = 1 n u ∑ k = 1 n ( w k ( j ) ) 2 + λ 2 ∑ i = 1 n m ∑ k = 1 n ( x k ( i ) ) 2 \sum_{(i,j):r(i,j)=1}{(\vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)}-y^{(i,j)})^2}+\lambda_1 \sum_{j=1}^{n_u} \sum_{k=1}^n{(w_k^{(j)})^2+\lambda_2 \sum_{i=1}^{n_m} \sum_{k=1}^n{(x_k^{(i)})^2}} (i,j):r(i,j)=1(w (j)x (i)+b(j)y(i,j))2+λ1j=1nuk=1n(wk(j))2+λ2i=1nmk=1n(xk(i))2

参数更新

有了上述的协同过滤的成本函数,我们可以来使用梯度下降来计算他对应的参数跟新方程了。
w i ( j ) = w i ( j ) − α ∂ J ( w , b , x ) ∂ w i ( j ) {w}_i^{(j)}=w_i^{(j)}-\alpha\frac{\partial J(w,b,x)}{\partial w_i^{(j)}} wi(j)=wi(j)αwi(j)J(w,b,x)
b ( j ) = b ( j ) − α ∂ J ( w , b , x ) ∂ b ( j ) {b}^{(j)}=b^{(j)}-\alpha\frac{\partial J(w,b,x)}{\partial b^{(j)}} b(j)=b(j)αb(j)J(w,b,x)
x k ( i ) = x k ( i ) − α ∂ J ( w , b , x ) ∂ x k ( i ) {x}_k^{(i)}=x_k^{(i)}-\alpha\frac{\partial J(w,b,x)}{\partial x_k^{(i)}} xk(i)=xk(i)αxk(i)J(w,b,x)

二进制标签

对于标签值只有0,1,?的情况

之前我们预测 y ( i , j ) y^{(i,j)} y(i,j)的值为 w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) \vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)} w (j)x (i)+b(j)

对于二进制标签我们通过 g ( w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) ) g(\vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)}) g(w (j)x (i)+b(j))预测 y ( i , j ) y^{(i,j)} y(i,j)其中 g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+ez1

同时损失函数也更新为:

L ( f w , b , x ( x ) , y ( i , j ) ) = − y ( i , j ) l o g ( f w , b , x ( x ) ) − ( 1 − y ( i , j ) ) l o g ( 1 − f w , b , x ( x ) ) L(f_{w,b,x}(x),y^{(i,j)})=-y^{(i,j)}log(f_{w,b,x}(x))-(1-y^{(i,j)})log(1-f_{w,b,x}(x)) L(fw,b,x(x),y(i,j))=y(i,j)log(fw,b,x(x))(1y(i,j))log(1fw,b,x(x))其中 f w , b , x ( x ) = g ( w ⃗ ( j ) ⋅ x ⃗ ( i ) + b ( j ) ) f_{w,b,x}(x)=g(\vec{w}^{(j)}\cdot \vec{x}^{(i)}+b^{(j)}) fw,b,x(x)=g(w (j)x (i)+b(j))

相应的成本函数为: j ( w ⃗ , b , x ⃗ ) = ∑ ( i , j ) : r ( i , j ) = 1 L ( f w , b , x ( x ) , y ( i , j ) ) j(\vec{w},b,\vec{x})=\sum_{(i,j):r(i,j)=1}{L(f_{w,b,x}(x),y^{(i,j)})} j(w ,b,x )=(i,j):r(i,j)=1L(fw,b,x(x),y(i,j))

均值归一化

将所有的用户对电影的评分转化为二维矩阵,均值归一化对电影的评分。具体的做法为将电影的平均值归一化为相同。 将所有该电影的值减去该电影的平均值。

这样对于新用户预测值将会是该电影的平均值,同时运算速度也会更快一点。

同时也可以按用户的评分将用户的评分归一化为0,但是这样以来方便的是预测一部没有初始数据的电影,这似乎不太合理。

寻找相关项

找到i项目关于特征 x ⃗ ( i ) \vec{x}^{(i)} x (i)的项的方式是计算 ∑ l = 1 n ( x l ( k ) − x l ( i ) ) 2 \sum_{l=1}^{n}{(x_l^{(k)}-x_l^{(i)})^2} l=1n(xl(k)xl(i))2找到这个平方距离最小的几项。

协同过滤算法的限制

冷启动问题:对于初始数据很少的用户和电影不能很好的预测。

使用一些其他信息:比如使用的电影类型、参演人员、工作室;年龄、性别、偏好设置

基于内容的过滤算法

基本内容

基于内容的推荐算法将会根据用户与物品的特征来找到好的匹配来推荐。

目标是预测用户j和电影i能不能很好的适配。

相关向量的维度一定要相同才能进行点积,从各自的特征向量中计算各自的 V ⃗ u \vec{V}_u V u以及 V ⃗ m \vec{V}_m V m来适配彼此的相关特征,比如说电影有多少动作成分在里面,用户有多少喜欢动作片。

通常的一个常用的方法来计算 V u V_u Vu是深度学习的方式,比如使用128-62-32 的神经网络。

最终我们预测这个用户对这个电影的适配度为 V ⃗ u ⋅ V ⃗ m \vec{V}_u \cdot \vec{V}_m V uV m若是使用二进制标签也可以使用sigmoid函数。

对于上述的神经网络我们如何训练:

构建成本函数 J = ∑ ( i , j ) : r ( i , j ) = 1 ( V ⃗ u ( j ) ⋅ V ⃗ m ( i ) − y ( i , j ) ) 2 J=\sum_{(i,j):r(i,j)=1}{(\vec{V}_u^{(j)} \cdot \vec{V}_m^{(i)}-y^{(i,j)})^2} J=(i,j):r(i,j)=1(V u(j)V m(i)y(i,j))2

对于寻找相似的电影我们可以通过计算 ∣ ∣ V ⃗ m ( k ) − V ⃗ m ( i ) ∣ ∣ 2 ||\vec{V}_m^{(k)}-\vec{V}_m^{(i)}||^2 ∣∣V m(k)V m(i)2即两个向量间的距离来确定彼此的相似程度。

从大型目录中推荐

主要分为两步:检索、排名

在检索步骤中可能生成大量的候选项,在排名步骤中将微调并选择最好的项目推荐给客户。

比如说先寻找到10个与用户最后观看的电影相似的电影、对于观看最多的3种风格找到品类中的最好的10项、该地区认为最好的20个电影…之后进行去重、去除已经看过的等数据操作。

之后通过机器学习算法对我们已经取得的项目进行排名,越多的项目将有越好的表现,但是算法将会越慢;可以尝试进行离线实验,看看检索额外的项目会产生多少更加相关的推荐。

数据降维:主成分分析算法(PCA)

常用于可视化、减少非常大量的特征、数据降维。

数据降维对支持向量机等老牌算法而言有一定的作用但是对于如今的深度学习而言可能作用并没有太大。

数据降维的主要作用是将一组可能存在相关性的变量尽可能转化为一组线性不相干的变量。

目的:找到数据对应的主成分使得将数据投影到上面的时候可以得到最大可能的方差

投影的过程实际上是对数据与该方向上的单位向量做点积。( a ⃗ ⋅ e ⃗ = ∣ a ⃗ ∣ ∣ e ⃗ ∣ c o s ( θ ) = ∣ a ⃗ ∣ c o s ( θ ) \vec{a}\cdot \vec{e}=|\vec{a}||\vec{e}|cos(\theta)=|\vec{a}|cos(\theta) a e =a ∣∣e cos(θ)=a cos(θ))

值得注意的是PCA不是线性回归,线性回归是为了拟合直线使得预测值y与拟合的差值最小,实际上是在y轴上的距离最小。而对于PCA而言所有特征被平等的对待,计算距离时也是综合的距离而不是某个投影的距离。

PCA的重建,将降维后的数据尝试性的重新变成与原数据相差不大的数据点,具体做法是将投影后的数据点放到原先的坐标系下。

对于PCA后的指标explained variance ratio主成分方差贡献率:该方法代表降维后的各主成分的方差值占总方差值的比例,这个比例越大,则越是重要的主成分。

强化学习

对于自动无人机而言是 寻找到函数将状态映射到动作上。

关键在于找到一个激励函数(奖励函数)让他知道当前的是表现的好还是坏。给出判断标准而不是具体操作。

相关术语

状态

研究对象的状态,用 S S S表示,他可以是数值代表,也可以是向量代表

动作

对象的动作,用 a a a表示

奖励

用于激励研究对象到达对应的状态所进行赋值的奖励,对于不希望的设置为负值,对于不同的期望程度设置不同大小的奖励

折扣因子

假如有一个很远的但是奖励比较大的状态,以及近在咫尺但是没有那么大的状态,显然直接选取最近的即可,因为采取一些动作可能需要一些花费等,这些花费的折损被衡量为折扣因子,用于计算最终的回报,详细见回报部分的笔记

回报

( S , a , R ( S ) , S ′ (S,a,R(S),S^{'} (S,a,R(S),S处于状态S可以选择a动作得到奖励 R ( S ) R(S) R(S)变成新的状态 S ′ S^{'} S

动作的回报等于 ∑ i = 1 n γ i − 1 ∗ R ( S i ) \sum_{i=1}^{n}{\gamma^{i-1}*R(S_i)} i=1nγi1R(Si)

比如对于中途没有奖励点,3步后100奖励,奖励折扣为0 .5的回报为 0 + 0.5 ∗ 0 + 0. 5 2 ∗ 0 + 0. 5 3 ∗ 100 0+0.5*0+0.5^2*0+0.5^3*100 0+0.50+0.520+0.53100

策略

强化学习的目标是找到一个策略 π \pi π告诉你采取什么样的动作 a = π ( s ) a=\pi(s) a=π(s)才能最大化回报。

马尔可夫决策过程(MDP)

未来仅取决于当前状态,而不取决于到达当前状态之前可能发生的任何事情。

状态动作值函数

Q ( S , a ) Q(S,a) Q(S,a)表示在状态S的情况下我们仅采用动作a一次所能得到的,最优情况下的回报值。

对于每个状态而言最好的回报是 m a x Q ( S , a ) max{Q(S,a)} maxQ(S,a),同时最好的动作也就是得到最大的 Q ( S , a ) Q(S,a) Q(S,a)的情况下的a

贝尔曼方程

用s表示当前状态,a表示当前动作, s ′ s^{'} s表示a动作之后的状态, a ′ a^{'} a表示在之后会采取的动作,R(s)表示s状态的奖励。值得注意的是这个状态的变化是由动作带来的。
Q ( s , a ) = R ( s ) + γ ∗ m a x ( a ′ ) Q ( s ′ , a ′ ) Q(s,a)=R(s)+\gamma*max_{(a^{'})}Q(s^{'},a^{'}) Q(s,a)=R(s)+γmax(a)Q(s,a)

模拟随机环境

尝试着做某个动作的时候,我们正常可以达到下一个状态,但是在随机环境中我们有可能不能正常进入下一个状态,可能出现意料之外的或者不应该去往的状态。比如小车本应该前往状态3但是却前往了状态5或者侧翻了、滑倒了、齿轮卡住了等。

在随机环境下的贝尔曼方程修改如下:
Q ( s , a ) = R ( s ) + γ ∗ E [ m a x ( a ′ ) Q ( s ′ , a ′ ) ] Q(s,a)=R(s)+\gamma*E[max_{(a^{'})}Q(s^{'},a^{'})] Q(s,a)=R(s)+γE[max(a)Q(s,a)]
其中 E [ ] E[] E[]表示数学期望。

DQN算法

关键思想:训练一个神经网络来计算或近似状态动作值函数 Q ( s , a ) Q(s,a) Q(s,a),在一个状态s中,使用神经网络去计算所有动作的Q函数值并选取最大的那个来最大化 Q ( s , a ) Q(s,a) Q(s,a)

网络架构:输入-64-64-1,其中输入要包含s和a

如何训练这样一个神经网络: 使用贝尔曼方程来闯将包含大量示例x和y的训练集然后使用监督学习算法,来完成从x到y 的映射问题。

如何采集这样的数据集 :对于贝尔曼方程等式右边的部分称为y,而输入的值为状态s和动作a。特别的是由于我们并不知道等式右边的Q函数的具体值是什么,我们实际采用的是一些猜测值,而这些值的效果会随着时间的推移变得更好。

完整过程:1、初始化神经网络随机猜测Q函数。2、采取动作来得到 ( s , a , R ( s ) , s ′ ) (s,a,R(s),s^{'}) (s,a,R(s),s).3、存储10000个最近的元组 ( s , a , R ( s ) , s ′ ) (s,a,R(s),s^{'}) (s,a,R(s),s)。4、通过上述元组训练神经网络,x与y的定义如上。5、训练 Q n e w Q_{new} Qnew使得 Q n e w ( s , a ) Q_{new}(s,a) Qnew(s,a)逼近于y。6、重新赋值Q函数的值使得 Q = Q n e w Q=Q_{new} Q=Qnew

改进的神经网络架构

将输入改成只有s没有a,而输出层的神经元个数为动作的个数,输出层变成了状态s时不同动作下的Q函数值。

ϵ \epsilon ϵ贪心策略

对于某些初始化的情况我们可能认为某个动作不是好的选择从而在后续的更新中从来没有尝试过取使用这个动作,但实际上这个动作可能是一个好的尝试,所以在选择动作的时候我们实际上应该给出较小的概率使得选取的动作不是最优的,而是随机的,这也被称为探索步骤,而正常选择最大化的步骤被称为贪心步骤。

对于这种选择一个小概率 ϵ \epsilon ϵ作为随机的策略被称为 ϵ \epsilon ϵ贪心策略。一种常见的做法是刚开始训练的时候我们采取较大的 ϵ \epsilon ϵ而随着训练次数的增加则逐渐减少这个 ϵ \epsilon ϵ的大小。

小批量和软更新

小批量

小批量的核心思想在于取样而非使用整个巨大的训练集,每次更新的时候仅使用整个训练集的子集。

对于强化学习而言,小批量意味着尽管我们在第3步中存储了10000个样本,但实际上我们仅使用其中的一小部分比如说1000个。

软更新

我们在DQN中学习更新Q函数的时候是直接赋值的,万一新的在某种情况下表现不够优秀,我们就用一个可能更糟糕的神经网络覆盖了Q函数。

软更新的过程就是使用加权的方式均衡完全更新和不更新。具体如下:
Q = 0.01 Q n e w + 0.99 Q Q=0.01Q_{new}+0.99Q Q=0.01Qnew+0.99Q
同样的可以迁移到之前的模型的参数更新中:
θ = 0.05 θ + 0.95 θ n e w \theta=0.05\theta+0.95\theta{new} θ=0.05θ+0.95θnew

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值