HotSummer

  • 首页
  • 分类
  • 归档
  • 标签

机器学习技法第八课——Adaptive Boosting

发表于 2016-07-28   |   分类于 ML

此文是本人学习林轩田老师教授的机器学习技法第八课——Adaptive Boosting——的笔记。

不同于 Blending and Bagging,Boosting 提供一种增强式集成学习方法,它在顺序训练各模型时,要求后面的模型着重训练前面的模型失误的数据,使得总的模型误差不断减小。Adaptive Boosting,简称 AdaBoost, 是 Boosting 中的一种。

参考

  • 机器学习技法
  • 课件
  • AdaBoost wikipedia

AdaBoost 的形象类比与流程概要

课上举的例子实在太形象了,一定得记下啊。Boosting 好比老师教一群小学生(多个模型)学习如何辨识苹果(集成学习)。这里有一堆图片(数据),其中有的是苹果的,还有不是苹果的。老师让学生 A 讲一条辨识苹果的规则(训练一个模型),然后特别指出他/她出错的图片(强调标识失败数据),让下一个同学提出新的规则(训练下一个模型),如此往复,最终可以得到一系列规则,虽然每条规则的辨识能力可能都很弱,但组合起来可能就是很强了(一系列弱模型集成为强模型)。

那么,AdaBoost 的流程就比较清楚了。模型 $g$ 辨识失败的数据, $g(\mathbf{x_n}) \ne y_n$ ,称为问题数据, 辨识正确的数据,称简单数据。以下是大致流程:

  1. 依次训练各模型
  2. 在一个模型训练完成后,向下一个模型强调问题数据
  3. 为每个模型分配权重,集成各模型

“强调”问题数据

明显流程第二点是关键。如何才能做到对模型”强调”问题数据呢?这里的“强调”,可以翻译为增加模型在问题数据上犯错的代价。在机器学习基石,老师提到过一些方法。比如,在训练前,复制问题数据 $n$ 份,如果模型在其中一个数据上犯错,就相当于犯了 $n$ 次错,达到“强调”的目的。这里使用的方法是,如果抽取到问题数据做训练,就对 error function 乘上一个系数 $u$ (大于一)。这样,如果模型在问题数据上犯错,error 会扩大 $u-1$ 倍。以下把这种处理方法称为“为数据分配权重”。

实际上,AdaBoost 不仅为问题数据分配权重,也为简单数据分配权重。不过没差,只要能达到“强调”问题数据的效果就行。这里引入 $m$:

$$m = \sqrt{\frac{1-e}{e}}$$

其中 $e$ 表示模型的失误率。AdaBoost 对问题数据乘以 $m$ ,对简单数据除以 $m$ 。其中有两点值得注意。

第一,如果 $e \lt 0.5$, 则 $m \gt 1$,问题数据确实会被“强调”;而当 $e \gt 0.5$ 时, $m \lt 1$ ,问题数据似乎不被“强调”,反而简单数据被“强调”了。其实不差,当 $e \gt 0.5$ 时,意味着模型辨识能力比瞎猜( $e=0.5$ )都不如,在最后模型结合时给它分配负权重,把它的辨识结果反过来,这时就应该向后面的模型“强调”简单数据。

第二,注意 $m(e)\;with\;e \gt 0$ 是一个单调下降的函数。这意味着, $e$ 越小,辨识越准确,模型出错也越少, $m$ 也会越大,AdaBoost “强调问题数据”越是“厉害”。为什么在模型出错更少时“更强调”问题数据呢?这是为了平衡简单数据与问题数据的影响,进而训练出更不同(diverse)的模型(对集成学习来说,模型 diversity 越高,效果越好)。(?-?对这话的因果关系存疑)实际上, $m$ 是推导的结果(参见 AdaBoost),在推导过程中似乎并未对此解释或假设,但以上论点也是比较合理的假说。

模型权重公式

$$ \alpha = \ln m = \ln \sqrt{\frac{1-e}{e}}$$

当 $e \gt 0.5$ 时, $\alpha \lt 0$。 所以在预测能力小于0.5时,模型被分配负权重,反之,权重为正。

AdaBoost 流程

  • $\mathbf{u}=[\frac{1}{N},\frac{1}{N},\frac{1}{N},…]$,长度为 $N$ ,记录每个数据的权重
  • for t=1,2,…,T

    • 根据训练数据与 $\mathbf{u}$ 训练出模型 $g_t$
    • 计算

    $$m = \sqrt{\frac{1-e}{e}}\quad with\; e=\frac{\sum u_n[y_n \ne g_t(\mathbf{x_n})]}{\sum u_n}$$

    • 更新 $\mathbf{u}$

      $$u_n = \left{ \begin{array}{l}
      u_n \cdot m,\quad y_n \ne g_t(\mathbf{x_n})\
      u_n / m,\quad y_n = g_t(\mathbf{x_n})
      \end{array} \right.$$

    • 计算 $\alpha_t = \ln (m)$

  • 返回模型 $G(\mathbf{x})=sign (\sum \alpha_t g_t(\mathbf{x}))$

AdaBoost 的理论保证

VC Bound:

$$E{out}(G)\le E{in}(G) + O\left( \sqrt{O(d_{vc}(H) \cdot T\log T) \cdot \frac {\log N}{N}} \right)$$

$T$ 表示迭代的次数,实践证明,当迭代达到 $T=\log N$ 时, $E{in}$ 会比较小,而此时的 VC Bound 也不太大,所以 $E{out}$ 可以做得比较小。

基础模型选择——决策树桩

流行选择 决策树桩(decision stump) 作为基础模型(base algorithm)。决策树桩是深度为一的决策树,典型的弱分类器,常被用作集成学习中的基础模型。它的分类器为:

$$h_{s,i,\theta}(\mathbf{x}) = s \cdot sign(x_i - \theta)$$

机器学习技法第七课——Blending and Bagging

发表于 2016-07-23   |   分类于 ML

此文是本人学习林轩田老师的机器学习技法第七课——Blending and Bagging。第七至第十一课学习 ML 中的各种集成学习(Ensemble Learning)算法。简单地讲,Ensemble 集成各种模型为一个最终模型。

参考

  • 机器学习技法
  • 课件
  • Kaggle Ensembling Guide
  • Understanding the Bias-Variance Tradeoff
  • 模型验证
  • Bootstrapping

误差的 bias 和 variance

在此文——Understanding the Bias-Variance Tradeoff——中有介绍,同种模型训练由于参数、抽样等不同,得到的模型的误差会有一定的随机性,所以有了模型误差的 bias 与 variance 的概念。

简单地讲,bias 指误差的期望,即模型的预测偏离正确值的期望。而 variance 即误差的方差,衡量模型误差的分散程度。这两个值当然是越小越好。

Blending

Blending 是十分自然的集成方法。简单地讲,就是将各模型的预测作为数据进行回归或分类训练将其结合。训练过程如下:

  1. 将训练集 $D{train}$ 分为 $D{train}^-$ 和 $D_{val}$,每条数据可表示为 $(x_1, x_2,…,y)$
  2. 在 $D_{train}^-$ 上,训练出各模型 $G^-=(g_1^-(\mathbf{x}), g_2^-(\mathbf{x}), g_3^-(\mathbf{x}),…)$
  3. 在 $D{val}$,各模型分别做出预测,组合成新的数据集 $D{pred}$,每条数据可表示为 $\Phi(\mathbf{x}) = (g_1(\mathbf{x}),g_2(\mathbf{x}),g_3(\mathbf{x}),…,y)$
  4. 在 $D_{train}$ 上,训练出各模型 $G=(g_1(\mathbf{x}), g_2(\mathbf{x}), g_3(\mathbf{x}),…)$
  5. 在 $D_{pred}$ 上,进行分类或回归训练,得到 Blending 模型参数,结合 $G$ 得到最终模型

(注:$x_i$ 表示数值,加粗 $\mathbf{x}$ 表示一个向量,$\mathbf{x}=(x_1, x_2,…,x_n)$) 进行测试时,先用 $G$ 做出预测作为输入代入 Blending 模型得到最终预测值。这里有2个问题。

为什么要把 $D{train}$ 分为 $D{train}^-$ 和 $D_{val}$,而不直接在训练集上做训练同时做预测,然后作为 Blending 的训练数据?因为训练得到的模型已经“知道了”其训练数据,在其训练数据上做预测不能反映其预测能力的真实情况,会付出复杂度方面的代价。所以,跟模型选择中所做的验证一样,需要使用模型未知的数据做验证。

为什么使用 $G$ 而非 $G^-$ 得到最终模型?$G$ 在 $D{train}$ 上训练得到,比在更小的训练集 $D{train}^-$ 得到的 $G^-$ 更优。

在课上,老师证明了各模型 $E{out}$ 的期望大于 Blending 模型 $E{out}$ 的期望,也就是说,Blending 模型的预测优于各模型的“平均水平”。(实际上只证明了 uniform blending,在此不细究)

Stacking

根据博文 Kaggle Ensembling Guide,Blending 可视为 Stacking 的简化。(Stacking 远早于 Blending 被提出)现在很多研究者视两者等同。

可以很容易发现,Blending 的一至三步与 Hold-out Validation 的步骤是相同的。存在多个模型时,常使用验证来选择模型,而 Hold-out 就是其中最基本的一种。而 Stacking 使用 Cross-Validation。

在 模型验证 中, Cross-Validation 虽然比使用 Hold-out Validation 复杂,但是 Stacking 得到的 $D{pred}$ 与 $D{train}$ 数据量相等,而 Blending 得到的 $D{pred}$ 与 $D{val}$ (一般取 $D_{train}$ 的10%)等量,较小。

Bagging

又称 Bootstrap Aggregation, 基于统计学上的 Bootstrapping 方法。简单地讲,就是从一个样本集中有放回地抽样得到多个样本集。

Bagging 利用 Bootstrapping 的原理,在训练集 $D_{train}$ 上有放回地抽样得到多个训练集 $D_1^-$, $D_2^-$, $D_3^-$,…,然后用抽取的训练集训练模型,由于抽取得到的训练集各不相同,得到的模型也各不相同(除非训练不受训练集影响,那还训练干嘛)。在预测时,取所有模型预测的均值。

Bagging 能够降低模型预测的 varaince 误差,特别适用于对样本敏感的波动比较大的模型。

机器学习技法第六课——Support Vector Regression

发表于 2016-07-10   |   分类于 ML

此文是本人学习林轩田老师的机器学习技法第六课——Support Vector Regression——的课堂笔记。

这节课介绍两个模型,与之前的 SVM 不同,都采用二次误差,一个是”kernel ridge regression”,另一个比较重要,是”Support Vector Regression”。最后,针对“机器学习基石”及本课程所讲的分类方法做一个总结。

参考

  • 机器学习技法
  • 课件
  • Kernel Logistic Regression
  • 岭回归
  • Soft Margin SVM

Kernel Ridge Regression

ridge regression,即岭回归,简单地讲,是“在平方误差的基础上增加 L2 正则项的回归”。以下是基本公式,这部分目标是将其 kernel 化。
$$ \min{\mathbf{w}} \frac{\lambda}{N}\mathbf{w^Tw} + \frac{1}{N} \sum{n=1}^{N}{ (y_n - w^T z_n)^2 }
$$

在上节课”“中的“Kernel Logistic Regression”一节,已经讲过“带 L2 正则化的线性模型”可以被 kernel 化,而且 $\mathbf{w}$ 可以被 $\mathbf{z}$ 线性表示,即 $\mathbf{w} = \sum \beta_n z_n$。

因为这部分推导与”Kernel Logistic Regression”的推导相似,在此给出结果:
$$ \min{\beta} { \frac{\lambda}{N} \sum{n=1}^{N}\sum_{n=1}^{M} \beta_n \beta_m K(\mathbf{x_n, xm})
+\frac{1}{N} \sum
{n=1}^{N}{ ( yn - \sum{m=1}^N {\beta_m K(\mathbf{x_m, x_n})} )^2 }}
$$

接下来求解。首先矩阵化,代入 $\mathbf{\beta, y}$ 列矩阵,$\mathbf{K{n \times n}}$ 矩阵,$\mathbf{K{m,n}} = K(\mathbf(x_m, xn)$:
$$ \min
{\beta} {\frac{\lambda}{N} \mathbf{\beta^T K \beta} + \frac{1}{N} ( \beta^T K \beta K - 2 \beta^T K^Ty + y^T y )}
$$

求导,梯度为:
$$ \nabla = \frac{2}{N} \mathbf{K^T}( (\lambda \mathbf{I} + \mathbf{K}) \mathbf{\beta} - \mathbf{y} )
$$

令梯度为 0, 则解得:
$$ \mathbf{\beta} = (\lambda \mathbf{I} + \mathbf{K})^{-1} \mathbf{y}
$$

推导过程中省略了许多步骤 :-P。需要注意的是,该求解方法时间复杂度为 $O(N^3)$,而且 $\beta$ 内元素值多不为 0。课中讲到,用于分类的”Kernel Ridge Regression”被称作“least squares SVM (LSSVM)”。因为 $\beta_n$ 多数非 0,它求解得到的”Support Vector”非常多。

Support Vector Regression

“Support Vector Regression (SVR)”尝试避免”Kernel Ridge Regression”的“Support Vector” dense 问题,同时保留类似二次误差(least squares error)的形式。

相对于 SVM 的 hinge regression,Support Vector Regression 采用 tube regression(在上节课”“介绍过)。令 $s=w^T z + b$,两者加上 squared error 的 error function 表达式为:

err type function
squared err $(s-y)^2$
tube err $\max(abs(s - y) - \epsilon,\; 0)$
hinge err $\max(1-ys,\; 0)$

(abs 取绝对值函数)很明显,squared err 与 tube err 的变化趋势相近,当 $s \rightarrow +\infty$,$err \rightarrow +\infty$,当 $s \rightarrow -\infty$,$err \rightarrow +\infty$。如果作图,两者都呈一个山谷状。

在 Soft Margin SVM 中,使用了 hinge error,在此将其替换成 tube error 重新推导。
$$ \min{b, \mathbf{w}} \frac{1}{2}\mathbf{w^Tw} + C \sum{n=1}^{N}{\max(0, |w^T z_n + b - y_n| - \epsilon)}
$$

首先,引入松弛变量 $\xi_n^\bigwedge, \xin^\bigvee$,同时去掉绝对值:
$$ \min
{b,\mathbf{w},\xi_n^\bigwedge, \xi_n^\bigvee} \frac{1}{2}\mathbf{w^Tw} + C \sum{ (\xi_n^\bigwedge + \xi_n^\bigvee) } \\
s.t.\quad -\epsilon - \xi_n^\bigvee \le y_n - w^T z_n - b \le \epsilon + \xi_n^\bigwedge \\
\xi_n^\bigwedge \ge 0,\quad \xi_n^\bigvee \ge 0
$$

之后,引入拉格朗日乘数 $\alpha_n^\bigwedge, \alphan^\bigvee$,分别对应限制条件的上限与下限,又经过一系列求导、KKT 条件、化简等处理(参考“Soft Margin SVM” :-P),得到最终公式:
$$ \min \frac{1}{2} \sum
{n=1}^{n}\sum_{m=1}^{n} (\alpha_n^\bigwedge - \alpha_n^\bigvee)(\alpha_m^\bigwedge - \alpha_m^\bigvee)K(x_n, xm) + \sum{n=1}^N( (\epsilon - y_n) \alpha_n^\bigwedge + (\epsilon + y_n) \alpha_n^\bigvee) \\
s.t.\quad \sum(\alpha_n^\bigwedge - \alpha_n^\bigvee) = 0 \\
0 \le \alpha_n^\bigwedge \le C, 0 \le \alpha_n^\bigvee \le C
$$
同样是 QP 问题,求解得出
$$ \mathbf{w} = \sum(\alpha_n^\bigwedge - \alpha_n^\bigvee)\mathbf{z_n}
$$
Support Vector 为 $\alpha_n^\bigwedge - \alpha_n^\bigvee \ne 0$ 对应的数据点,SVR 保证了 SV 的稀疏性。

分类器小结

目前学习的(二)分类器,可以“线性的”与“kernel化的”,从 error function 看,可分为 “0/1 error”, “hinge error”, “squared/tube error”, “logistic error”。

linear / kernel 0/1 or hinge error squared/tube error  logistic error
linear PLA/pocket linear SVR
linear linear soft-margin SVM linear ridge regression regularized logistic regression
kernel kernel ridge regression kernel regularized logistic regression
kernel SVM SVR probabilistic SVM

其中第二、四行是最常用的,老师推荐了开源库 LIBLINEAR 与 LIBSVM。

微积分笔记

发表于 2016-06-30   |   分类于 Math

参考

  • 《微积分(第2版)(上册)》,傅英定 谢云荪 主编,高等教育出版社

微积分系列笔记

  • 极限
  • 导数
  • 不定积分计算
  • 导数应用
  • 定积分
  • 定积分的应用
  • 常微分方程
  • 重积分
  • 多元函数最值

常见处理

对 $e^{x^2}$ 的积分

考虑正态分布

根式常见处理

  • 平方
  • 分子、分母有理化
  • 换元

幂指函数处理

  • 指数真底互换
  • 取对数

乘法变加法

取对数

积分被积变量

非被积变量被视为常数,即使是自变量,如 $f(x) =x \int_a^x f(t) dt$, 也可以自由“出入”积分,如 $f(x) = \int_a^x x f(t) dt$

2 变量不等式证明

固定一个,变动另一个,即其中一个作为常数,另一个作为变量。另外,区间端点如 $a, b$, 也可视为 2 个变量。

无穷项数列和的极限

  • 夹逼准则
  • 定积分定义
  • 构造函数项无穷级数

不定积分

不定积分的定积分形式: $\int f(x) dx = \int_0^x f(x) dx + C$

max 与 min 函数不等式

  1. $\max(a,b) < c$ 等价于 $a < c\; \&\& \; b < c$
  2. $\min(a,b) > c$ 等价于 $a > c\; \&\& \; b > c$
  3. $\max(a,b) > c$ 的逆命题是 $\max(a,b) \le c$, $\min$ 函数同理

公式

对数换底公式

$$\log_a b = \frac{\log_c b}{\log_c a}=\frac{\ln b}{\ln a}$$

指数真底互换

$$x^y =a^{y\log_a x}= e^{y\ln{x}}$$

求导公式

$$(x^a)’ = a x^{a-1}$$

$$(e^x)’ = e^x, \quad (a^x)’ = a^x \ln a$$

$$(\ln x)’ = \frac{1}{x}, \quad (\log_a x)’ = \frac{1}{x \ln a} $$

$$(\sin(x))’ = \cos(x), \quad (\cos(x))’ = -\sin(x)$$

$$(\tan(x))’=\frac{1}{\cos^2 x}, \quad (\cot(x))’ = -\frac{1}{\sin^2(x)}$$

$$(\arcsin(x))’ = \frac{1}{\sqrt{1-x^2}}, \quad (\arccos(x))’ = -\frac{1}{\sqrt{1-x^2}}$$

$$(\arctan (x))’ = \frac{1}{x^2 + 1},\quad (arccot(x))’ = -\frac{1}{x^2 + 1}$$

$$(\sec(x))’ = \sec(x)\tan(x),\quad (\csc(x))’ = -\csc(x)\cot(x)$$

$$\frac{d}{dx}\int_{\psi (x)}^{\varphi (x)}f(t)dt=f\left[\varphi
(x)\right]\varphi ‘(x)-f[\psi (x)]\psi ‘(x)$$

不定积分

$$\int \frac{1}{\sqrt{a^2-x^2}} dx = \arcsin \frac{x}{a} + C$$

$$\int \frac{1}{a^2+x^2} dx = \frac{1}{a} \arctan \frac{x}{a} + C$$

$$\int \frac{1}{a^2-x^2} dx = \frac{1}{2a} \ln |\frac{a+x}{a-x}| + C$$

$$\int \sec x dx = \ln |\sec x + \tan x|+ C$$

$$\int \csc x dx = \ln |\csc x - \cot x|+ C$$

$$\int \frac{1}{\sqrt{x^2 \pm a^2}} dx = \ln |x +\sqrt{x^2 \pm a^2}| + C$$

分部积分可循环形式

$\sqrt{x^2 \pm a^2}, \quad \sqrt{a^2 - x^2}$

几个简单函数的 n 阶导数

$$(x^\alpha)^{(n)} = \alpha(\alpha-1)…(\alpha-n+1)x^{\alpha-n},\quad (x^n)^{(n)} = n!$$

$$\sin^{(n)}x = \sin(x+\frac{\pi}{2}n), \quad \cos^{(n)}{x} = \cos(x+\frac{\pi}{2}n)$$

$$(\frac{1}{x})^{(n)} = \frac{(-1)^n n!}{x^{n+1}}$$

$$[\alpha u(x) + \beta v(x)]^{(n)} = \alpha u^{(n)}(x) + \beta v^{(n)}(x)$$

$$(uv)^{(n)} = \sum_{k=0}^n u^{(n-k)} v^{(k)}\quad Leibniz 公式$$

三角公式

三角与反三角

$\sec(x)\cos(x)=1,\quad \csc(x)\sin(x)=1,\quad \cot(x)\tan(x)=1,\quad$

两角和

$$\cos(\alpha+\beta)=\cos \alpha \cdot \cos \beta-\sin \alpha \cdot \sin \beta$$

$$\sin(\alpha + \beta)=\sin \alpha \cdot \cos \beta + \cos \alpha \cdot \sin \beta$$

$$\tan(\alpha+\beta)=\frac{\tan\alpha+\tan\beta}{1-\tan\alpha \cdot \tan\beta}$$

倍角公式

$$\sin(2\alpha)=2\sin\alpha\cdot\cos\alpha$$

$$\cos(2\alpha)=(\cos\alpha)^2-(\sin\alpha)^2=2(\cos\alpha)^2-1=1-2(\sin\alpha)^2$$

$$\tan(2\alpha)=\frac{2\tan\alpha}{1-\tan^2\alpha}$$

等价无穷小

$$\sqrt[n]{x+1} - 1 \sim \frac{x}{n}$$

$$1-\cos{x} \sim \frac{1}{2} x^2$$

$$\arcsin(x) \sim \sin(x) \sim \tan(x) \sim \arctan(x) \sim x$$

$$\tan(x) - \sin(x) \sim \frac{1}{2}x^3$$

$$ \ln(1+x) \sim x, \quad \log_a(1+x) \sim \frac{x}{\ln a} $$

$$ e^x - 1 \sim x, \quad a^x - 1 \sim x\ln a $$

不等式

  • 基本不等式:$a + b \ge 2\sqrt{a b}$
  • $a + b \le 2(a^2 + b^2)$

方向余弦

对 $(\cos \alpha, \cos \beta)$ 有

$$ \cos^2 \alpha + \cos^2 \beta = 1 $$

数列和

等比数列(几何数列) ${a_n}$ ,$a_n = a_1q^{n-1}$, 和:

$$ S_n = \frac{a1(1-q^n)}{1-q} = \frac{a{n+1} - a_1}{q-1} $$

导数运算

除法:

$$ (\frac{u}{v})’(x) = \frac{u’(x)v(x) - u(x)v’(x)}{v^2(x)} $$

参数方程: $y=y(t),\; x= x(t)$

$$ \frac{dy}{dx} = \frac{dy}{dt}\frac{dt}{dx} = \cfrac{\frac{dy}{dt}}{\frac{dx}{dt}} $$

复合函数求导的链式法则: $z=z(u(x,y), v(x,y))$

$$ \frac{\partial z}{\partial x} = \frac{\partial z}{\partial u}\frac{\partial u}{\partial x} + \frac{\partial z}{\partial v}\frac{\partial v}{\partial x} $$

隐函数:若 $F(x,y)=0$ 隐函数存在,则

$$ \frac{dy}{dx} = -\frac{F_x}{F_y} $$

隐函数推广到二元 $F(x,y,z)=0$ 有

$$ \frac{\partial z}{\partial x}=-\frac{F_x}{F_z} $$

定义

数列极限

$\forall \epsilon \gt 0$,$\exists N \gt 0$,当 $n \gt N$ 时,有 $|an - A| \lt \epsilon$,则 $\lim{n \rightarrow \infty}{a_n} = A$

函数极限(有限值)

要求 在 $x_0$ 的某去心邻域有定义,对 $\forall \epsilon \gt 0$,都 $\exists \delta > 0$,使满足 $0 \lt |x-x0| \lt \delta$ 的所有x,都有 $|f(x) - A| \lt \delta$,则 $\lim{n \rightarrow x_0}{f(x)} = A$

二重函数极限

$f(x,y)$ 的定义为 $D$, $P_0(x_0,y_0)$ 为 $D_f$ 的聚点,对 $\forall \epsilon \gt 0$,都 $\exists \delta > 0$, 使满足 $0<||PP_0||=\sqrt{(x-x_0)^2+(y-y_0)^2}<\sigma$ 的所有 $P(x,y)$, 都有 $|f(x,y)-A|<\sigma$, 则

$$ \lim_{(x,y)\rightarrow (x_0,y_0)} f(x,y) = A$$

二重极限存在则 $P(x,y)$ 以 任意方式 接近 $P_0(x_0,y_0)$, 其极限都存在。可以推广到更多元函数极限。

连续

极限等于函数值,则该处连续。

导数

$$ f’(x0) = \lim{\Delta x \rightarrow 0} \frac {f(x_0 + \Delta x) - f(x_0)} {\Delta x} $$

偏导数

$$ zx= \frac{\partial z}{\partial x} = \lim{\Delta x \rightarrow 0} \frac{f(x_0 + \Delta x, y_0) - f(x_0, y_0)}{\Delta x} $$

二阶偏导

$$ \frac{\partial }{\partial x}(\frac{\partial z}{\partial x})=\frac{\partial^2 z }{\partial x^2} = f{xx}(x,y),\quad \frac{\partial }{\partial y}(\frac{\partial z}{\partial x})=\frac{\partial^2 z }{\partial x \partial y} = f{xy}(x,y) $$

方向导数

若 $z=f(x,y)$ 可微,则存在沿 方向余弦 为 $(\cos\alpha, \cos\beta)$ 的方向 l 的方向导数

$$ \frac{\partial z}{\partial l} = \frac{\partial z}{\partial x} \cos \alpha + \frac{\partial z}{\partial l} \cos \beta $$

方向导数是函数沿 l 方向的变化率。偏导数是沿坐标轴的函数变化率。

梯度

梯度是一个向量:

$$ \mathbf{grad} f= \frac{\partial f}{\partial x} \mathbf{i} + \frac{\partial f}{\partial y} \mathbf{j} $$

全微分

全增量:

$$ \Delta z = f(x+\Delta x, y+\Delta y) - f(x,y) $$

若偏导数 $f_x(x_0, y_0), f_y(x_0, y_0)$ 均存在,且存在极限:

$$ \lim_{\Delta x,\Delta y \rightarrow 0} \frac{\Delta z - (f_x(x_0, y_0) \Delta x + f_y(x_0, y_0) \Delta y)}{\sqrt{\Delta x^2 + \Delta y^2}} = 0 $$

则全微分存在:

$$ dz = f_x(x_0, y_0) dx + f_y(x_0, y_0) dy $$

$f_x(x_0, y_0) dx + f_y(x_0, y_0) dy$ 称为线性主部。可微时有: $\Delta z = f_x(x_0, y_0) \Delta x + f_y(x_0, y_0) \Delta y + o(\sqrt{\Delta x^2+\Delta y^2})$

微分

若函数在某处可导,则有 $\Delta y = f’(x) \Delta x + o(\Delta x)$, 其中 $dy = f’(x)\Delta x = f’(x) dx$ 即该处微分。$f’(x)\Delta x$ 称为线性主部。

定积分

关键字:分割,近似,求和,取极限

设函数 $f(x)$ 在有限区间 $[a, b]$ 上有界,将 $[a, b]$ 任意划分为 $n$ 个小区间,分点为:

$$a=x_0<x_1<x_2<…<x_n=b$$

在每个小区间 $[x_{i-1}, x_i]\; (i=1,2,…,n)$ 上任取一点 $\xii\; (x{i-1} \le \xi_i \le x_i)$, 记

$$ \Delta x_i =xi - x{i-1}\; (i=1,2,…,n),\; \lambda=\max_{1\le i \le n}{\Delta x_i} $$

作和式

$$ \sum_{i=1}^n f(\xi_i)\Delta x_i $$

如果无论区间 $[a,b]$ 怎样划分及点 $\xi_i$ 怎样选取,极限

$$ \lim{\lambda \rightarrow 0} \sum{i=1}^n f(\xi_i)\Delta x_i $$

的值都为同一常数,则称 $f(x)$ 在 $[a,b]$ 上可积,此极限值称为 $f(x)$ 在 $[a,b]$ 上的定积分,记为 $\int_a^b f(x) dx$, 即

$$ \inta^b f(x) dx = \lim{\lambda \rightarrow 0} \sum_{i=1}^n f(\xi_i)\Delta x_i $$

其中 $x$ 称为 被积分变量, $f(x)$ 称为 被积函数 , $f(x)dx$ 称为 被积表达式 , $a,b$ 分别为 积分下限, 积分上限, $\int$ 称为 积分符号, 表示和, $[a,b]$ 为 积分区间 。

不定积分

在定义域内,如果 $(F(x))’ = f(x)$,则
$$\int f(x) dx = F(x) + C$$

间断点

不连续的点。第一类间断点,左右极限都存在。第二类间断点即不属于第一类间断点的间断点。

基本初等函数

指六类函数:常量函数、幂函数、指数函数、对数函数、三角函数和反三角函数。以上函数通过有限次四则运算或有限次算命运算所得,且能用一个解析式表示的函数,称为 初等函数。

驻点

一阶导数为 0 的 $x$ 值。

极值点

对 $\forall x \in$ 去心邻域 $(x_0, \delta)$, 都有 $f(x) \lt f(x_0)$ (或 $f(x) \gt f(x_0)$) 则称 $x_0$ 为极大(小)值点。

函数凹凸性

$f(x)$ 在 $[a,b]$ 连续

$$f(\frac{x_1+x_2}{2}) < \frac{f(x_1) + f(x_2)}{2}$$

则下凸,大于则上凸

拐点

$f(x)$ 在 $x_0$ 附近连续,且两侧凸性相反,则 $(x_0, f(x_0))$ 为拐点

函数渐近线

  • 垂直渐近线 $x=x_0$

$$\lim_{x \rightarrow x_0} f(x) = \infty$$

  • 水平渐近线 $y=b$

$$\lim_{x \rightarrow \infty} f(x) = b$$

  • 斜渐近线 $y=k x + b$

    • $$\lim_{x \rightarrow \infty} f(x) - (k x + b) = 0$$

    • $$k =\lim{x\rightarrow \infty} \frac{f(x)}{x},\quad b = \lim{x \rightarrow \infty} f(x) - k x$$

函数曲率

$\alpha \sim 角度,\quad s \sim 弧长,\quad K \sim 曲率$

$$K = \lim_{\Delta s \rightarrow 0} |\frac{\Delta \alpha}{\Delta s}| = \frac{|y’’|}{(1+y’^2)^{\frac{3}{2}}}$$

圆的曲率: $K = 1 / R$。 曲率半径: $1/K$, 曲率圆与函数曲线相切,以曲率半径为半径,曲率中心为曲率圆的圆心。

反常积分

反常积分又叫广义积分,是对普通定积分的推广,指含有无穷上限/下限,或者被积函数含有瑕点的积分,前者称为无穷限广义积分,后者称为瑕积分(又叫无界函数的反常积分)。

无穷级数

一个无穷序列的元素的和称为无穷级数。序列的通项称作级数的 通项, 若为常数,则称作常数项无穷级数,若为函数,称作函数项无穷级数。无穷级数是 函数逼近理论 的重要内容之一。

定理

微分、偏导与连续

对一阶,可微必可导,可导必连续,连续有极限。

对二阶,可微必偏导和连续,连续有极限。可微的充分条件:偏导函数存在且偏导函数连续。

微分中值定理

罗尔中值定理(导数根存在定理)

$f(x)$ 满足三个条件,一、在 $[a,b]$ 连续,二、在 $(a,b)$ 可导,三、 $f(a)=f(b)$ ,则 $\exists \xi \in (a,b)$, 使得 $f’(\xi)=0$。几何意义:存在切线与端点连线平行。

拉格朗日定理

$f(x)$ 满足二个条件,一、在 $[a,b]$ 连续,二、在 $(a,b)$ 可导,则 $\exists \xi \in (a,b)$, 使得

$$ f’(\xi) = \frac{f(b) - f(a)}{b - a} $$

几何意义:存在切线与端点连线平行。

柯西中值定理

$f(x),\;g(x)$ 满足二个条件,一、在 $[a,b]$ 连续,二、在 $(a,b)$ 可导,另外, $\forall x \in (a,b)$, $g’(x) \ne 0$, 则 $\exists\xi \in (a,b)$, 使得

$$ \frac{f(b) - f(a)}{g(b) - g(a)} = \frac{f’(\xi)}{g’(\xi)}$$

泰勒公式

$f(x)$ 在 $x_0$ 处 $n$ 阶可导,则

$$ f(x) = f(x_0) + f’(x_0)(x-x_0) + \frac{f’’(x_0)}{2!}(x-x_0)^2 + … + \frac{f^{(n)}(x_0)}{n!}(x-x_0)^n + R_n(x)
$$

$R_n(x)$ 称为余项

  • 偑亚诺余项 $R_n(x) = o((x-x_0)^n)$,
  • 拉格朗日余项 , $\xi$ 在 $x_0$ 与 $x$ 之间

$$R_n(x)=\frac{f^{n+1}(\xi)}{(n+1)!}(x-x_0)^{n+1}$$

有界性定理

函数连续则有界

介值定理

$f(x)$ 在 $[a,b]$ 上连续,则存在一个介于 $f(a) \sim f(b)$ 的值

根/零点存在定理

如果 $f(x)$ 在 $[a,b]$ 连续,且 $f(a) \cdot f(b) < 0$, 则 $f(x) = 0$ 存在根,如果 $f(x)$ 单调,则只存在一个根。

可积的充要条件

满足以下条件之一:

  • f(x) 连续(则原函数可导)
  • 单调有界
  • 只有有限个第一类间断点且有界

定积分的性质

(定)积分中值定理

$f(x)$ 在 $[a,b]$ 上连续,则存在 $\xi \in (a,b)$

$$\int_a^b f(x) dx = f(\xi) (b-a)$$

估值定理

设 M 与 m 分别为 f(x) 在 [a,b] 上的最大最小值,则

$$ m(b-a) \le \int_a^b f(x) dx \le M(b-a) $$

保号性

如果在 [a,b] 上 $f(x) \ge 0$, 则 $\int_a^b f(x) dx \ge 0$

推论1, 保序性: 如果在 [a,b] 上 $f(x) \ge g(x)$, 则 $\int_a^b f(x) dx \ge \int_a^b g(x) dx$

推论2: $\int_a^b |f(x)| dx \ge |\int_a^b f(x) dx|$

区间可加性

不论 a,b,c 三点相对位置,恒有 $\int_a^b f(x) dx = \int_a^c f(x) dx + \int_c^b f(x) dx$

线性性

$\int_a^b [k_1 f(x)+k_2 g(x)] dx = k_1 \int_a^b f(x) dx + k_2 \int_a^b g(x) dx$

奇偶函数的导函数

奇函数的导数为偶函数,偶函数的导数为奇函数

极限的性质

(局部)有界性

若 $lim_{x \rightarrow x_0} f(x) = A$, 则 $\exists\;M>0,\;\delta > 0$,对 $\forall\; x \in U^\circ(x_0, \delta)$, 都有 $|f(x)| \le M$

局部保号性

若 $lim_{x \rightarrow x_0} f(x) = A > 0$ (或 $<0$ ),="" 则="" $\exists="" \delta="">0$, 使得对 $\forall x \in U^\circ(x_0,\delta)$, 都有 $f(x) > 0\;(<0)$

极限存在准则

夹逼准则

若在 $x_0$ 的某个空心邻域 $(x_0,\delta0)$ 内,有 $g(x) \le f(x) \le h(x)$ ,且 $\lim{x\rightarrow x0} g(x) =lim{x\rightarrow x0} h(x)=A$, 则 $lim{x\rightarrow x_0} f(x)=A$

单调有界准则

单调有界数列必有极限,包括单调增加有上界,单调减少有下界两种情况

隐函数存在定理(一个方程)

设方程 $F(x,y)=0$ 的左端函数 $F(x,y)$ 满足

  • 在点 $P_0(x_0,y_0)$ 的某一邻域内具有连续的偏导数 $F_x,\; F_y$
  • $F(x_0,y_0)=0$
  • $F_y(x_0,y_0)\ne 0$

则在点 $P_0(x_0, y_0)$ 的某一邻域内,由方程 $F(x,y)=0$ 唯一确定单值连续且有连续导数的函数 $y=f(x)$, 使得 $F(x, f(x)) \equiv 0$, 且 $y_0=f(x_0)$ 并有:

$$ \frac{dy}{dx} = -\frac{F_x}{F_y} $$

可推广到多元隐函数

偏导数与梯度

单位向量 $\mathbf{l}(\cos \alpha, \cos \beta)$ 的偏导数

$$ \frac{\partial f}{\partial l} = (\frac{\partial f}{\partial x}, \frac{\partial f}{\partial y}) \cdot (\cos \alpha, \cos \beta) = \mathbf{grad } f \cdot \mathbf{l} = ||\mathbf{grad} f|| \cdot \cos \theta $$

其中 $\theta$ 为梯度 $\mathbf{grad} f$ 与方向向量 $\mathbf{l}$ 的夹角。有以下结论:

  • 方向导数沿梯度方向取得最大值 $||\mathbf{grad}f||$
  • 方向导数沿梯度反方向取得最小值 $-||\mathbf{grad}f||$

机器学习技法第五课——Kernel Logistic Regression

发表于 2016-06-26   |   分类于 ML

此文是学习林轩田老师的机器学习技法第五课——Kernel Logistic Regression——的课程笔记。

这节课主要讨论了 SVM 与 Logistic 回归的相似性,其目标是解决“SVM 从 0/1 分类到概率分类的转换”以及“Logistic 从低维空间到高维空间的转换”,提出了二个方法,一是,将 SVM 训练结果代入 Logistic 中训练,二是,使用 Logistic Regression 的 kernel 模型进行训练。

参考

  • 机器学习技法
  • Soft Margin SVM
  • 课件
  • Platt scaling
  • Kernel SVM

SVM 与 L2 正则化

推导 Soft Margin SVM 的原始公式:
$$ \min{b,\mathbf{w},\xi} \frac{1}{2}\mathbf{w^Tw} + C \sum{n=1}^{N}\xi_n \\
s.t.\ y_n(\mathbf{w^Tz_n} + b) \ge 1 - \xi_n \\
s.t.\ \xi_n \ge 0
$$
$\xi$ 是松弛变量,也可视作 err,衡量越过 Margin 或分类超平面的程度,大致可以写成 $err = \xi_n = \max{(1-y_n(w^T zn + b),\; 0)}$, 原式大概可以写成:
$$ \min
{b,\mathbf{w}} \frac{1}{2}\mathbf{w^Tw} + C \sum_{n=1}^{N}{\max{(1-y_n(w^T z_n + b),\; 0)}}
$$
$$即\;\min{\frac{1}{2}\mathbf{w^Tw} + C\sum{err}}$$
这个公式与机器学习基石部分的带 L2 正则化的 PLA 算法比较相似。SVM 大致可以视作一个带 L2 正则化的分类器。(这个 error 常被称作 hinge loss)

SVM 与 Logistic 相似

令 $s=w^T z + b$ (超平面分类得分),引入机器学习基石中的 0/1 错误、 Logistic 回归的错误与 SVM 错误比较:

err type function
0/1 [$ys \le 0$]
logistic $\ln(1+\exp(-ys))$
SVM $\max(1-ys,\; 0)$

课程中作图更直观,在此就大致解释下 :P。 $y, s$ 同号时,分类正确,0/1 分类中 “[]” 表示 bool 判断,如果 $ys \le 0$ 取1,反之取0,即分类正确 err 为 0,错误取 1 以记录错误。与之不同的是,Logistic 与 SVM 在分类错误时,不止记录了错误,而且在 $ys$ 越小时,err 取值越大。在分类正确时,后两者要么直接取 0,要么取一个 $0 \sim 1$ 的数。Logistic 与 SVM 都放大了分类错误数据的影响,而忽略分类正确数据的影响。

Platt’s scaling

Platt scaling 又称 Platt calibration,将分类模型对数据的预测评分作为输入,训练 Logistic 模型,将它转化成概率模型。运用这个方法将 SVM 与 Logistic 结合,使得 SVM 拥有概率特征,而 Logistic 可以用 SVM kernel 处理多维空间转换。大致过程为

  • run SVM get $\Phi_{svm}(z_n) = w^T z_n + b$
  • run Logistic problem get A, B:
    $$ \min{A, B} {\frac{1}{N} \sum{n=1}^{N}{ \ln{(1 + \exp(-yn (A \Phi{svm}(z_n) + B)))} }}
    $$
    这里 A 是对 SVM 模型的一个放缩,对结果影响不大,而 B 有对原 SVM 有一定影响,应该尽量接近 0。在课程中,将这个模型称为 probabilistic SVM。

Kernel Logistic Regression

这一部分试图推导出 Logistic 的 kernel,以解决 Logistic 向高维空间映射的问题。提前声明一下,由于此模型不具有 SVM 的稀疏性,林老师在下节课会说明此方法相对 Platt’s scaling 较少使用。

首先,对于以下形式的“带 L2 正则化的线性模型”
$$ \min{\mathbf{w}} \frac{\lambda}{N}\mathbf{w^Tw} + \frac{1}{N} \sum{n=1}^{N}{err(y_n, w^T zn)}
$$
老师用奇妙的方法证明了其中的 $\mathbf{w}$ 可以被 $\mathbf{z}$ 线性表示
$$\mathbf{w} = \sum
{n=1}^N \beta_n z_n$$
,而且该模型能被转换成 kernel 形式。(至于如何证明的,因为十分奇妙在此略过 :P)

当然,带 L2 正则化的 Logistic 回归模型符合以上条件。
$$ \min{w} { \frac{\lambda}{N}\mathbf{w^Tw} +\frac{1}{N} \sum{n=1}^{N}{ \ln{(1 + \exp(-y_n w^T z_n))} }}
$$

在 Kernel SVM 中,用 kernel 函数 $K(\mathbf{x, x’})$ 替换 $\mathbf{z^Tz’}$,所以,接下来要把高维空间的 $\mathbf{w, z}$ 用 kernel 替换。
$$ \mathbf{w^Tw} = \sum{n=1}^{N}\sum{n=1}^{M} \beta_n \beta_m K(\mathbf{x_n, x_m})\quad (向量内积分配律)\\
\mathbf{w^Tzn} = \sum{m=1}^N {\beta_m K(\mathbf{x_m, x_n})}
$$

最后问题变成求解 $\beta$
$$ \min{w} { \frac{\lambda}{N} \sum{n=1}^{N}\sum_{n=1}^{M} \beta_n \beta_m K(\mathbf{x_n, xm})
+\frac{1}{N} \sum
{n=1}^{N}{ \ln{(1 + \exp(-yn \sum{m=1}^N {\beta_m K(\mathbf{x_m, x_n})}))} }}
$$
需要说明,$\beta$ 往往非 0,而对比 SVM 中的 $\alpha$,则大多是 0(非支持向量),后者具有稀疏性。

机器学习技法第四课——Soft-Margin SVM

发表于 2016-06-09   |   分类于 ML

此文是本人学习林轩田老师的机器学习技法第四课——Soft-Margin Support Vector Machine——的课堂笔记。

前几节课的 SVM 不能容忍错误——包括不可分错误及可分分却在 margin 内的错误,这节课要解决这个问题,推导出 Soft Margin SVM。

参考

  • 机器学习技法
  • 课件
  • 支持向量机
  • Dual Support Vector Machine

松弛变量

引入松弛变量 $\xi$,放宽条件,同时避免过度放宽,在最小化公式中也加入 $\xi$:
$$ \min{b,\mathbf{w},\xi} \frac{1}{2}\mathbf{w^Tw} + C \sum{n=1}^{N}\xi_n \\
s.t.\ y_n(\mathbf{w^Tz_n} + b) \ge 1 - \xi_n \\
s.t.\ \xi_n \ge 0
$$
此处 $C$ 是一个常量,作为平衡“large margin”与”margin violation”的参数。
$\xi$ 在限制条件中确实减小了下限,放宽了条件,但至于这背后为何能使 SVM 容忍错误,这可能要从头开始推导了。很明显,这已经可以用二次规划求解。

对偶问题

转换成对偶问题,用前面课程 Dual Support Vector Machine 中同样的方法。

拉格朗日乘数

$$ L(b,\mathbf{w},\alpha,\beta) = \frac{1}{2}\mathbf{w^Tw} + C \sum_{n=1}^{N}\xin + \sum{n=1}^N \alpha_n(1-\xi_n-y_n(\mathbf{w^T zn} + b)) + \sum{n=1}^N \beta_n (-\xin)
$$
求解:
$$ \max
{\alpha_n \ge 0,\ \betan \ge 0} (min{b,\mathbf{w},\xi} L(b,\mathbf{w},\alpha,\beta))
$$

求导化简成关于 $\alpha$ 的函数

$$ \frac{\partial L}{\partial \xi_n} = C - \alpha_n - \beta_n\\
let\ \ \beta_n= C -\alpha_n
$$
因为条件中有 $\alpha_n \ge 0$,故 $C \ge \alphan \ge 0$。如此原式变换为:
$$ \max
{$0 \le \alpha_n \le C,\ \beta_n=C-\alphan} (\min{b,\mathbf{w},\xi} \frac{1}{2} \mathbf{w^T w} + \sum_{n=1}^{N}\alpha_n(1 - y_n(\mathbf{w^T \mathbf{z_n}} + b)))
$$
这一步增加了限制条件,但消去了 $\beta, \xi, C$。接下来与 Dual Support Vector Machine 的过程相同,令 $\frac{\partial L}{\partial b} = 0, \frac{\partial L}{\partial wi} = 0$ 化简得:
$$
\min
{\alphan} (\frac{1}{2}\sum{m=1}^{N} \sum_{n=1}^{N} y_m y_n \mathbf{z_m^T} \mathbf{z_n} \alpha_m \alphan - \sum{n=1}^{N}\alphan) \\
s.t.\ \ \sum
{n=1}^N y_n \alpha_n = 0,\ \ all\ 0 \le \alpha_n \le C
$$
看上去与之前的差别只有对 $\alpha$ 加上上限 C。

求解 $b$

部分 KKT 条件:
$$ \alpha_n(1-\xi_n-y_n(\mathbf{w^T z_n} + b)) = 0 \\
(C - \alpha_n) \xi_n = 0 $$
因为除 $\xi,\ b$ 其他都是已知量,所以只要求解方程组就能得到解。而多数情况下,当 $0 \lt \alpha_n \lt C$ 时,被称为 free Support Vector,可推导出
$$ b = y_s - \mathbf{w^T z_s}
$$
之后的求解过程与前面课程没什么不同。

$\alpha_n$ 与向量角色

根据 KKT 条件,当 $\alpha_n = 0$ 时,松弛变量 $\xi_n=0$,没有错误,被称为非支持向量,non SV,处于 margin 外界;

当 $0 \lt \alpha \lt C$ 时,$\xi_n=0$,没有错误,而且可以求解 $b$,被称为 free SV,位于 margin 上;

当 $\alpha = C$ 时, $\xi_n \ne 0$,有错误,同样可以帮助求解,被称为 bounded SV,位于 margin 内部或越过了超平面。

LOOC 帮助模型选择

模型选择时,可以用 Cross Validation 做参考,其中特别的有 Leave-One-Out CV,即只留一个数据点做验证。

将 Leave-One-Out CV 与全数据集(不留验证数据)的训练做比较。如果验证数据是一个 non-SV,那么,2 者的错误是相同的,而如果验证数据是一个 SV,那么有可能分类错误。所以有
$$ E_{loocv} \le \frac{num(SV)}{N} $$
这里存在疑问的是,如果验证数据是一个很关键的 SV,可能极大地影响超平面的训练结果,这个 bound 是否成立。

这个上限可以用做安全检查,在训练模型之后便能得到 $E_{loocv}$ 的上限,可以排除一些结果太差的模型,节省时间,但它的作用有限,不能断定一个模型的好坏。

算法时间复杂度

发表于 2016-06-07   |   分类于 Algo

Coursera 上 Algorithms: Design and Analysis, Part 1 by Tim Roughgarden 的学习笔记。第二课,有关时间复杂度。

The Gist

时间复杂度计算概略地讲,就是“suppress constant factors and lower-order terms”

Big-Oh Notation

Formal Definition: $T(n) = O(f(n))$ \
if and only if exist constants $c, n_0$ such that $T(n) \le cf(n)$ \
for all $n \gt n_0$

即 $n \rightarrow +\infty$ 时,$cf(n)$ 为 $T(n)$ 上限

Omega Notation

Formal Definition: $T(n) = \Omega(f(n))$ \
if and only if exist constants $c, n_0$ such that $T(n) \ge cf(n)$ \
for all $n \gt n_0$

即 $n \rightarrow +\infty$ 时,$cf(n)$ 为 $T(n)$ 下限

Theta Notation

Formal Definition: $T(n) = \Theta(f(n))$ \
if and only if $T(n)=O(f(n))$ and $\Omega(n)=O(f(n))$

即 $n \rightarrow +\infty$ 时,$cf(n)$ 既能作 $T(n)$ 下限也能作上限,

机器学习技法第三课——Kernel SVM

发表于 2016-06-05   |   分类于 ML

此文是学习林轩田老师的机器学习技法第三课——Kernel Support Vector Machine——的课堂笔记。

给定上节课的公式:
$$
\min_{\alphan} (\frac{1}{2}\sum{m=1}^{N} \sum_{n=1}^{N} y_m y_n \mathbf{z_m^T} \mathbf{z_n} \alpha_m \alphan - \sum{n=1}^{N}\alpha_n) \\
s.t.\ all\ \alphan \ge 0,\ \sum{n=1}^N \alpha_n y_n = 0
$$
这里 $\mathbf{z}$ 是由 $\mathbf{x}$ 变换得到。在 $\mathbf{x}$ 向量所处的空间里,如果所有超平面都不能对数据进行分类,可以将 $\mathbf{x}$ 映射到高维空间,也就是 $\mathbf{x}$ 变换成 $\mathbf{z}$。这次课的目标包括:了解这种变换带来的求解问题,引入核函数、多项式核函数、高斯核函数,及了解如何选择核 SVM 或线性 SVM。

参考

  • 机器学习技法
  • Dual Support Vector Machine
  • 课件

求解复杂度

考虑将 $\mathbf{x}$ 从一次变换到二次:
$$\mathbf{x} = (x_1, x_2, …, x_d) \ \ \rightarrow \\
\mathbf{z} = (1, x_1, x_2, …, x_d, x_1 x_1, x_1 x_2, …, x_1 x_d, x_2 x_1, x_2 x_2, …, x_2 x_d, …, x_d x_d)$$

向量长度增加了 $d^2 + 1$,由于在求解公式中需要计算任意2个 $\mathbf{x}$ 的内积($\mathbf{z_m^T z_n}$),计算复杂度从 $o(d^2)$ 增加到 $o(d^4)$,陡增了不少困难。而这仅是变换到二次的情况。

核函数

就 求解复杂度 一节所举一次变二次,有以下推导:
$$\mathbf{z^T z’} = 1 + \sum_{i=1}^d x_i x’i + \sum{i=1}^d \sum_{j=1}^d x_i x_j x’_i x’j \\
=1 + \sum
{i=1}^d x_i x’i + (\sum{i=1}^d x_i x’i) (\sum{j=1}^d x_j x’_j) \\
=1 + \mathbf{x^T x’} + (\mathbf{x^T x’})(\mathbf{x^T x’})$$
可见任意2个 $\mathbf{w}$ 的内积($\mathbf{z^T z’}$)可以用 $\mathbf{x}$ 的内积表示。这可以推广到更高次变换。

这种处理有何好处?复杂度大幅降低,从原来的 $o(d^4)$ 回降到 $o(d^2)$。

核函数

简单来说,核函数(核)应该是:
$$\mathbf{z^T z’} = K(\mathbf{x}, \mathbf{x’})$$
在一次变二次例子中 $K(\mathbf{x}, \mathbf{x’}) =1 + \mathbf{x^T x’} + (\mathbf{x^T x’})(\mathbf{x^T x’})$。

原求解公式变换为:
$$
\min_{\alphan} (\frac{1}{2}\sum{m=1}^{N} \sum_{n=1}^{N} y_m y_n K(\mathbf{x}_m, \mathbf{x}_n) \alpha_m \alphan - \sum{n=1}^{N}\alpha_n) \\
s.t.\ all\ \alphan \ge 0,\ \sum{n=1}^N \alpha_n y_n = 0
$$
设 $(\mathbf{x}_s, y_s)$ 为支持向量($\alpha_s = 0$)解出 $b$:
$$
b = y_s - \mathbf{w^T \mathbf{z_s}} \\
= ys - (\sum{n=1}^{N} \alpha_n y_n \mathbf{z_n})^\mathbf{T} \mathbf{z}_s \\
= ys - \sum{n=1}^{N} \alpha_n y_n K(\mathbf{x}_n, \mathbf{x}s)
$$
求解 $\mathbf{w}$ 似乎有点复杂,但不影响最终分类。分类公式变换为
$$g
{svm}(\mathbf{x}) = sign(\mathbf{w^T z} + b)
=sign(\sum_{n=1}^{N} \alpha_n y_n K(\mathbf{x}_n, \mathbf{x}) + b)$$

多项式核函数

$$K(\mathbf{x}, \mathbf{x’}) = (\zeta + \gamma \mathbf{x^T x’})^q,\ with\ \zeta \ge 0,\ \gamma \gt 0$$
例如,当 $q = 2$ 时,
$$\mathbf{z^T z’} = K(\mathbf{x}, \mathbf{x’}) =1 + 2\zeta\gamma\mathbf{x^T x’} + \gamma^2(\mathbf{x^T x’})^2 \\
\Rightarrow \mathbf{z} = (1, \sqrt{2\zeta\gamma}x_1, \sqrt{2\zeta\gamma}x_2, …, \sqrt{2\zeta\gamma}x_n, \gamma x_1 x_1, \gamma x_1 x_2, …, \gamma x_n x_n)$$
感觉这个核不能满足所有从 $\mathbf{x}$ 到 $\mathbf{z}$ 的多项式变换,比如 $\mathbf{z}$ 中至少所有一次项系数都相等(在上例中为 $\sqrt{2\zeta\gamma}$)。

高斯核函数

$$K(\mathbf{x}, \mathbf{x’}) = exp(-\gamma |\mathbf{x - x’}|^2),\ with\ \gamma \gt 0$$
高斯(Gaussian)核函数可以将 $\mathbf{x}$ 扩展到无限维。

课上只给了 $\gamma = 1,\ \mathbf{x} = (x)$($\mathbf{x}$ 只有一个维度)时的推导:
$$K(\mathbf{x}, \mathbf{x’}) = exp(-(\mathbf{x - x’})^2) \\
=exp(-x^2)exp(-x’^2)exp(2xx’)\\
=exp(-(x)^2)exp(-(x’)^2) \sum{i=0}^\infty \frac{(2xx’)^i}{i!},\ \ taylor\ expansion \\
=\sum
{i=0}^\infty(exp(-x^2)exp(-x’^2) \sqrt{\frac{2^i}{i!}} \sqrt{\frac{2^i}{i!}} x^i x’^i) \\
=\mathbf{z^T z’} \\
with\ \mathbf{z}=exp(-x^2)(1, \sqrt{\frac{2}{1!}} x, \sqrt{\frac{2^2}{2!}}x^2, …)
$$

如果 $\gamma$ 取值过大(方差过大),高斯核会过拟合。

核函数并非万能

线性 SVM 指原始的,$\mathbf{x}$ 未经变换的 SVM,求解相对多项式核 SVM 简单(系数矩阵为对角矩阵),而且,参数选择较少。而高斯核的模型难以解释,且容易过拟合。

对于高次的多项式 kernel,可以考虑用原始的方法,将 $\mathbf{x}$ 转化成 $\mathbf{z}$ 之后代入线性 SVM 求解,如果维度不高,求解速度会更快。

其他核函数

课上指出,能成为核函数的充要条件是,核函数导出的矩阵 $\mathbf{K}$,$k_{i,j}=K(\mathbf{x_i, x_j})$,是对称且半正定的。这2个条件被称为 Mercer’s condition。

Python 杂记

发表于 2016-06-03   |   分类于 Tools

参考

  • python代码 `if not x:` 和`if x is not None:`和`if not x is None:`使用
  • python变量和作用域
  • Python 序列的切片操作与技巧

函数和常用语法

raw_input 与 input

raw_input 只在 2 中存在,返回字符串,在 2 中,input 返回输入表达式的值;\
3 中 input 返回字符串。

type

查看变量类型

交换两变量值

1
a, b = b, a

while/for else 语句

跟 if else 相同,在 while/for 条件为假时执行 else。所以,在未进入循环或循环正常完成后,else 部分会执行,而循环被 break 或出现异常,则不会执行 else。

1
2
3
4
5
6
for value in ["Sat","Sun","Mon"]:
if value == "Sun":
print("Bingo!")
break
else:
print("No Sunday.")

yield 关键字

在函数中使用 yield 关键字让函数返回一个 生成器。 该生成器调用方式十分奇特,类似于断点调试,在调用其 next() 方法时运行到 yield 关键字处并返回参数,可多次调用直到函数结束(抛出 StopIteration 异常)。可以在函数中使用多个 yield,就像设置多个断点。隐含的一个特性是,每次只能取到下一个值,而不能回退取到上一个值。通常用 for/while 循环使用生成器,以代替循环调用 next(),

1
2
3
4
5
6
7
8
9
10
11
def gen(stop):
print "step in"
for i in range(stop):
yield i # 当代码运行到此处返回 i
print "yield %g" % i
i += 1

g = gen(3) # 函数返回一个生成器
print "called gen" # 在调用 g.next() 方法前,gen 内代码不会执行
for i in g:
print i

sign 函数

1
sign = lambda a: 1 if a > 0 else -1 if a < 0 else 0

print 不换行

python2 中 print 不换行,python3 中使用参数 end=''

1
print("Hello World", end='')

dict 键列表

使用 list(dict) 获取 dict 的键列表

惯用处理

pip 更换仓库源

1
pip install numpy -i http://pypi.mirrors.ustc.edu.cn/simple/ # 临时用中科大源安装numpy

pip 下载安装包并离线安装

1
2
3
4
# 只下载包
pip download -d ./download_packs_dir -r ./requirements.txt
# 只安装
pip install --no-index --find-links=./download_packs_dir -r ./requirements.txt

从文件路径获取文件名与扩展名

1
2
3
4
import os
filepath = '/tmp/log.txt'
filename = os.path.basename(filepath) # 文件名
print(os.path.splitext(filename)) # 分离扩展名

时间

datetime 与 字符串相互转换

1
2
3
4
5
from datetime import datetime
id_s = "337259199211056344"[6:14] # 身份证号
d = datetime.strptime(id_s, '%Y%m%d')
print((datetime.now() - d).days) # 距今多少天,datetime相减得delta对象
print(d.strftime('%Y-%m-%d')) # datetime 格式化输出字符串

判断对象为数字

1
2
3
import numbers
x = 1
print(isinstance(x, numbers.Number))

读 excel 表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import xlrd
def read_excel(excel_name, sheet_name):
bk = xlrd.open_workbook(excel_name)
sh = bk.sheet_by_name(sheet_name)

nrows = sh.nrows #获取行数
ncols = sh.ncols #获取列数

print("excel %s, sheet %s, nrows %d, ncols %d" % (excel_name, sheet_name, nrows,ncols))

row_list = []
for i in range(0, nrows): #获取各行数据
row_data = sh.row_values(i)
row_list.append(row_data)

return row_list

生成随机数

random
1
2
3
4
import random
random.random() # 0 到 1 小数
random.randint(m,n) # m 到 n 整数
random.sample(list, n) # 从 list 不放回抽样 n 个,返回列表
正态随机

生成正态随机数列可用numpy.random.normal(mu, sigma, sample_num)

正则

匹配例子

1
2
3
import re
str = "截止日期:2016-7-11 2:44:29。余额:137533。逾期金额:28747。"
print(re.findall(r"余额:(.+?)。", str))

list 操作

range()

1
2
3
4
5
# range(stat=0,stop,step=1)
range(10) # 返回 0 到 9 列表
range(1,10) # 返回 1 到 9 列表
range(1,10,2) # 返回以 2 为步长 1 到 9 列表
range(0,-10,-1) # 返回 0 到 -9 列表

列表推导式

1
[x**2 for x in range(10)] # 创建一个新 list

切片

list 切片作为右值,会复制数据并返回引用。而对切片的修改会直接作用于原 list 上。

1
2
3
4
5
6
7
# list[start:stop:step], 用法类似 range,如果意义明确,可省略参数
# 索引可为负,可以超出范围
la = lb # 只能复制引用
la = lb[:] # 复制数据,返回引用给 la
lb[::-1] # lb 逆序列表 copy
lb[-2:-1] = [2, 4] # 将 lb 最后两个数赋为 2, 4
del lb[0:2] # 删除 lb 第 0、1 号元素

增加元素

1
2
3
4
list.append(x) # 追加到末尾
list.insert(i, x) # 插入到 i 处
la = lb + lc # 创建一个新 list,顺序加入 lb、lc 中元素
la.extend(lb) # 在 la 中依次添加 lb 中元素

判断元素存在

1
2
x in list # 返回 bool 类型,是否存在 x
list.count(x) # 返回 x 出现次数

按索引查元素

索引可为负,范围: [-len, len-1]

按元素查索引

1
list.index(x) # 第一次出现 x 位置,如果 x 不存在会报错

删除元素

1
2
3
4
del list[index] # 删除 index 处元素
list.remove(x) # 删除 x 元素,如果不存在会报错
list.pop(index=-1) # 返回并删除 index 处元素
# 直接用切片复制保留元素到新列表中,也是一种方法

反转

1
list.reverse()

zip 合并

1
2
zip(la,lb,lc) # “同索引元素”组成元组,构成列表,长度为输入最短列表的长度
[a + b for a,b in zip(la,lb)]

模块

一个模块是一个源文件,文件名即模块名。模块由 import 语句加载后,便可以访问其中定义的对象。

import 与 from import

当 python 解释器 import 一个模块时,会执行其中的代码。

1
2
import module # 加载 module,使用其中对象时应该用 module.obj
from module import obj # 加载 module,只能使用 obj 对象,不用加 module 前缀

__name__ 属性

当 python 解释器加载一个模块时,会设置每个模块的属性 __name__。 只有当前运行模块的该属性被设置为 __main__,所以可用以下语句判断当前模块是否是程序入口

1
2
if __name__ == "__main__":
pass

模块搜索路径

1
2
3
# sys.path 列表存储了模块搜索路径
import sys
sys.path # 可修改该列表以修改模块搜索路径

搜索路径初始包括:

  • 运行脚本目录
  • 环境变量 PYTHONPATH 中存储的值
  • Python 模块的安装目录

dir()

1
2
dir() # 返回当前模块定义的对象名列表
dir(module) # 返回 module 定义的对象名列表

模块安装

三种方式:

进入下载安装包目录,运行 setup.py 程序:

1
2
3
4
5
6
7
# 源码安装
cd download_dir
python setup.py install # 运行 setup.py 安装程序
# 用 pip 安装,自动安装依赖包
pip install PackageName
# 用 easy_install 安装,不推荐使用
easy_install PackageName

win下 Anaconda 安装依赖包

进入Anaconda安装目录

1
2
3
cd Scripts
pip install PackageName -i https://pypi.tuna.tsinghua.edu.cn/simple/
# -i 后接国内镜像地址url,提升速度

更换conda源(清华):

1
2
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes

包

是一个包含 __init__.py 的文件夹,导入模块时需要加上包前缀,类似 Java。

作用域

三大作用域

只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等,甚至列表推导式也是)不会引入新的作用域

子级作用域与上级

在子级作用域可访问上级作用域变量。让上级变量指向另一个对象不能使用语句 same_name = obj, 该句被视为在子级作用域定义一个同名变量,并隐藏了上级变量。

1
2
3
4
5
6
7
def run():
print("read y: %d" % y) # 读取全局变量
x = 1 # 创建一个局部变量 x

x, y = 0, 0
run()
print("global x: %d" % x)

global 与 nonlocal 语句

如果想在子级作用域中让上级作用域变量指向其他对象,可以用 global 与 nonlocal 语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
x, y = 0, 0
def outer():
# nonlocal x 这样声明会报错,python 不能找到非全局的上级变量 x
x, y = 1, 1
def inner():
nonlocal x
x = 2
global y
y = 2

inner()
print("outer:", x, y)

outer()
print("global:", x, y)
# 输出:
# outer: 2 1
# global: 0 2

global 最先出现,用于在局部引用全局变量,随后又加入 nonlocal,使子级作用域引用 非全局的 上级变量。

类变量与实例变量

类变量的定义与访问其中两种方式:

  • class_name.class_var
  • 类定义内方法定义外 class_var

实例变量定义与访问有两种方式:

  • obj_name.obj_var
  • 在有 self 参数的方法定义中 self.obj_var

用访问实例的方式可以访问类变量,就像 在子级作用域访问上级变量,只能访问而不能让其指向另一个对象,而且如果实例变量与类变量同名则访问实例变量。

1
2
3
4
5
6
7
8
9
10
class cls:
v1 = 0 # 定义类变量

def __init__(self):
self.v1 = 1 # 定义实例变量,隐藏同名类变量

cls.v2 = 0 # 定义类变量
obj = cls()
print cls.v1, cls.v2 # 访问类变量
print obj.v1, obj.v2 # 分别访问实例变量 v1 与类变量 v2

字符串

模板

类似 C 语言的格式化字符串,用 % 号连接模板字符串(Template)与匹配元组。

1
2
3
4
'%s is a string. %d is a int.' % ("Hello World", 0) # 该表达式返回一个字符串

# 也可将元组替换成字典,模板对应加入 (key)
"I'm %(name)s, and I love %(num)g." % {"num":math.pi, "name":"Mike"}

原生字符串(常量)

在字符串字面量前加 r ,会使之成为原生字符串字面量,不会对字符进行转义。

1
r"\n" == "\\n" # 返回 True

加操作

字符串只允许与字符串进行加操作

函数参数

参数传递

函数形参(函数定义参数)复制了实参(传入函数的变量)的引用,类似 Java,对形参引用对象的修改实际上在修改实参引用对象,但让形参指向其他对象不会对实参有影响。

缺省与变长

函数参数的定义顺序与调用顺序应该遵循:关键字参数–>缺省参数–>变长参数–>关键字参变长数

关键字参数

最基本的一类参数,调用时可指明形参名(关键字)。与其他参数不同,必需赋值。

1
2
3
4
5
6
7
def fun(a, b):
print a, b
fun(1, 2) # 一般调用方法
fun(b=1, a=2) # 指明形参名可乱序
fun(1, b=2) # 可行
fun(1, a=2) # 这样调用出错
fun(a=1, 2) # 同样出错

缺省参数

缺省参数有缺省值。除了顺序在关键字参数后以及有缺省值外,与关键字参数基本相同。

1
2
3
def fun(a, b=2):  # b 为缺省参数
print a, b
fun(1, 2)

变长参数

参数个数不定,形参最终得到元组,调用时可不传,一个个传递或传一个元组。

1
2
3
4
5
6
def fun(a, *b): # b 为变长参数
for i in b:
print a + i
fun(1, 2, 3)
fun(1, *(2, 3)) # 用元组传递变长参数,加星号,称作解包
fun(1) # 不传或解包空元组都可行

关键字变长参数

参数个数不定,而且必须指明关键字。形参最终得到字典,与变长参数类似,调用时可不传,一个个传递或传一个字典。

1
2
3
4
5
def fun(**kwargs):
for k, v in kwargs.items():
print "get " + k + "=" + str(v)
fun(a=1, s="hi")
fun(**{"a": 1, "s": "hi"}) # 字典解包,注意关键字必须为字符串

参数顺序
1
2
3
def fun(a, b=1, *c, **d): # 函数定义时形参须根据类型按序定义
pass
fun(1, 2, 3, d1=4) # 函数调用时也根据类型按序传入

常识

元组

  • 元素不能改变

False

判断语句中None,False,空字符串””,0,空列表[],空字典{},空元组()都相当于False

虚拟环境

1
2
3
4
5
6
sudo pip3 install virtualenv
# 创建虚拟环境,python3,无已安装包
virtualenv -p python3 --no-site-packages venv
source venv/bin/activate # 激活
pip freeze > requirement # pip freeze
deactivate # 退出虚拟环境

文件操作

当前目录

1
2
import os
os.getcwd()

简单文件读写

1
2
3
4
5
6
7
8
9
col = []
with open('file_path.csv', 'r') as df:
for line in df:
tmp = line.strip().split(',')
col.append(int(tmp[3])) # 读取第4列

with open('out_path', 'w') as df: # 'a' 追加
for val in col:
df.write("%d\n" % val)

在控制台运行源文件

1
execfile('python_code.py')

错误及解决办法

pip安装出现SOCKS支持问题

报错Missing dependencies for SOCKS support。在Ubuntu下,用unset all_proxy && unset ALL_PROXY命令解除代理设置。

C/Cpp 杂记

发表于 2016-06-03   |   分类于 C/C++

文件操作

简单文件读写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<fstream>
using namespace std;

ifstream in;
in.open("file_path");
int k;
while(in >> k) // 读取 int 型数据
cout << k << endl;
in.close();

ofstream out;
out.open("out_path", ios::app); // app模式追加,默认覆写
out << ‘hello world’ << endl;
out.close();

编程规范

循环计数器与 ++ 运算符

考虑 while 和 do 计数循环:

1
2
3
4
5
6
7
8
i = 0;
while(++i < 1)
cout << "while: " << i << endl; // i 不会被打印

i = 0;
do{
cout << "do: " << i << endl; // i 被打印2次
}while(i++ < 1);

这里计数器 i 不能正常工作(打印一次),应该将计数器更新放在循环体避免失误,使用标准的 for 循环最好。

结构体声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct struct_label{

}; // 结构标记声明
struct struct_label var_name; // 结构变量声明
struct struct_label{

} var_name; // 结构标记与变量同时声明

typedef struct {

} struct_type, *p_struct_type; // 结构typedef名声明
struct_type var_name; // 结构变量声明
p_struct_type var_name; // 结构指针变量声明

typedef struct struct_label{

} struct_type, *p_struct_type; // 结构标记与typedef名同时声明

typedef struct node{
ElemType data;
struct node *next;
} Node, *PNode; // 链表结点结构体典型声明
1…5678
Blunt

Blunt

email:summer15y@163.com

72 日志
7 分类
37 标签
© 2019 Blunt
由 Hexo 强力驱动
主题 - NexT.Muse