在python machine learning(2nd)和 NG 的machine learing 都以监督学习,Cost fuction,gradient descent 作为开端,这个也是机器学习的基础。
监督学习的基础思路
作为监督学习,一般已知是一个多维度形容的东西X,通过X1特征,X2特征···Xn特征等等进行形容,最后,每个X对应一个分类或者分数Y,举个例子,X就是一个人,X1是用车的品牌,X2是年收入,X3是身高,Y就是判断合不合适结婚
监督学习的基础思路就是,就是找出一条公式,
h
(
x
)
=
w
1
∗
x
1
+
w
2
∗
x
2
+
w
3
∗
x
3
h(x) = w1 * x1 + w2 * x2 +w3 *x3
h(x)=w1∗x1+w2∗x2+w3∗x3 来算出每一个X值多少分
如果通过给hx限定一个值,比如8分,来判断是否值得结婚,这就是可监督学习之中的分类问题,如果想预测每个X对应多少分,那么就是一个回归分析的问题。
如何选取参数
调整参数,使得公式
h
(
x
)
=
w
1
∗
x
1
+
w
2
∗
x
2
+
w
3
∗
x
3
h(x) = w1 * x1 + w2 * x2 +w3 *x3
h(x)=w1∗x1+w2∗x2+w3∗x3
的结果和Y接近的过程就是机器学习的过程,核心的步骤就是找到这些w1,w2,w3
方法: 反向操作
很简单, 首先我随机分配了w1,w2,w3,然后我调用X的数据,x1,x2,x3,然后进行计算,算出一个y_predict,如果y_predict比实际的Y大,那么我就使得w1x1,w2x2,w3*x3变小,因为,x1,x2,x3是不变的,所以只能是让系数w1,w2,w3减小,
所以就有了
w
1
=
w
1
−
某
个
东
西
w1 = w1 - 某个东西
w1=w1−某个东西
那么这个某个东西,应该和y_predict和y(实际上的值)差值有关系,这样我们就使得我们预测结果的差值可以改变系数,
所以
w
1
=
w
1
−
(
Y
p
r
e
d
i
c
t
−
Y
r
e
a
l
)
w1 = w1 - (Ypredict~ - Yreal)
w1=w1−(Ypredict −Yreal)
这样呢,当Ypredict比Yreal小,w1就会减去一个负数从而变大,当Ypredict比Yreal大,w1就会减去一个数从而变小,和逻辑符合,注意的是,如果w1 是10000-20000的范围,而Y是0-1的范围,所以为了解决步数的问题,最好还是添加一个参数,来平衡双方的规模,所以就有了参数lambda(步幅度)
w 1 = w 1 − ( Y p r e d i c t − Y r e a l ) ∗ l a m b d a w1 = w1 - (Ypredict~ - Yreal) *lambda w1=w1−(Ypredict −Yreal)∗lambda
这样,如果w1 是10000-20000的范围,而Y是0-1的范围,我们只要设置lambda为1000,就可以使得训练速度加快,步数减少。
好了,到这里好像已经没毛病了,在电脑里试一下,看行不行,参考最下面的octave代码1
正如代码中解释的,
function w_best = CH01computeWeight(X,y,n_iter,lambda)
这个函数是为了返回一个w_best[w1,w2,w3],使得
h
(
x
)
=
w
1
∗
x
1
+
w
2
∗
x
2
+
w
3
∗
x
3
h(x) = w1 * x1 + w2 * x2 +w3 *x3
h(x)=w1∗x1+w2∗x2+w3∗x3
的结果和我们想要的 y是一样的.
第一次尝试:
X=[1,2,3],y=10,n_iter=10,lambda=1
y_predict = 0
y_predict = 140
y_predict = -1680
y_predict = 21980
y_predict = -285600
y_predict = 3712940
y_predict = -48268080
y_predict = 627485180
y_predict = -8.1573e+09
y_predict = 1.0604e+11
不好!!原因是步子太大了,走偏了,w每次加减的数越来越大,这样w不会变小,所以我们将lambda设置为0.01试一下,这样调整
y_predict = 0
y_predict = 1.4000
y_predict = 2.6040
y_predict = 3.6394
y_predict = 4.5299
y_predict = 5.2957
y_predict = 5.9543
y_predict = 6.5207
y_predict = 7.0078
y_predict = 7.4267
好像可以了,用1000次循环试一下y_predict最后会不会变成10!
完美!完成了目标!这个时候又有一个新的一问题,是经历了多少次之后,y_predict = 10,因为我们得到的数只能无限接近10,而不能达到10,为了回答这个问题,我们在代码中设定当y_predict -y_real <0.0001的时候,返回n_iter,
代码如下:
if(abs(y_predict - y)< 0.0001),
n_last_iter=i;
break;
end
那么我们可以看到,执行之后
返回
n_last_iter = 189
所以是经历的189次之后达到,有没可能更快呢?
公式:
w
1
=
w
1
−
(
Y
p
r
e
d
i
c
t
−
Y
r
e
a
l
)
∗
l
a
m
b
d
a
w1 = w1 - (Ypredict~ - Yreal) *lambda
w1=w1−(Ypredict −Yreal)∗lambda
我们可以得知,w2,w3,减去的数也是和w1一样的?到但是,x2是2,x3是3,所以,如果w2减去两份,w3减去3份是不是更合适呢?这样我们每次就是改变Y的百分比(不展开论述),这样是不是更快?
所以在原来的公式上加上xi,变成
w 1 = w 1 − ( Y p r e d i c t − Y r e a l ) ∗ l a m b d a . ∗ x 1 w1 = w1 - (Ypredict~ - Yreal) *lambda.*x1 w1=w1−(Ypredict −Yreal)∗lambda.∗x1
运行一下,可以看到
n_last_iter = 79!!!
果然是这样子!!!
到这里,已经完成第一个机器学习识别器,也知道了如果参数设置不好,结果可能会走偏,所以在公式
w 1 = w 1 − ( Y p r e d i c t − Y r e a l ) ∗ l a m b d a . ∗ x 1 w1 = w1 - (Ypredict~ - Yreal) *lambda.*x1 w1=w1−(Ypredict −Yreal)∗lambda.∗x1
里面数值lambda,每一步的大小,和方向(选择加入x1到公式)关系重大,同时w,y的规模不能相差太大,这是从中学习到的!
octave 代码1如下
这里用octave(免费的Matlab),比较容易理解:
function w_best = CH01computeWeight(X,y,n_iter,lambda)
% ====================== introduction ======================
%this function select the best weight vector for a giving y and X vector
%parameters:
% X: 1*3 vector,like [1,2,3]
% y: number,like 10
% n_iter:how many times you would like computer to run
%Application situation:
%the question is like below,suppose Y is 10 ,and we want to know for a given X vector
% ,like X = [1,2,3],what is the best weight vectore w = [w1,w2,w3] that can give us the correct answer,10.
% ====================== CODE HERE ======================
% set some useful variables
w = zeros(1,3); % I initalize the w vector as [0,0,0]
Y_predict = 0 ;
gap_of_Y = 0 ;
y_lasttime= 0 ;
n_last_iter=0 ;
% comput the Y_predict
for i = 1:n_iter,
if(abs(Y_predict - y)< 0.0001),#如果预测的y和实际的y很接近就返回n_iter
n_last_iter=i;
break;
end
Y_predict = X * w';% vector computation, Y_predict = x1w1+x2w2+x3w3
gap_of_Y = Y_predict - y; % show the gap
w = w - gap_of_Y *lambda
end
Y_lasttime = Y_predict
w_best = w
n_last_iter=n_last_iter
end