softmax回归

softmax回归是由多项分布推导回来的一种回归,主要的做用就是能进行二种以上的分类,它也是广义线性模型中的一种,不过它的特点是它的T(y)和η都是向量值。

  p(y;Φ)=Φ11{y=1}Φ21{y=2}...Φk1{y=k};设(T(y))i=1{y=i}

               =Φ11{y=1}Φ21{y=2}...Φk1-Σ1{y=i};i=1....k-1

      =Φ1(T(y))1Φ2(T(y))2...Φk1-Σ(T(y))i

      =exp((T(y))1log(Φ1)+(T(y))2log(Φ2)+...(1-Σ(T(y))i)log(Φk))

               =exp((T(y))1log(Φ1k)+(T(y))2log(Φ2k)+...(T(y))k-1log(Φk-1k)+log(Φk))

  根据指数分布公式得出:

      η=log(Φ1k)

        log(Φ2k)

          .

                     log(Φk-1k)

      a(η)=-log(Φk)

      b(y)=1

 

      Φi=eηi/Σeηj;j=1...k

  将ηiiTx代入Φi会得出Φi=eθiTx/ΣeθjTx

  hθ(x)=E(T(y)|x;θ)

     =Φ1

      .

      Φk-1

  最大似然估计l(θ)=Σlog(y(i)|x(i);θ)

                           =Σlog∏(eθiTx(i)/ΣeθiTx(i));i是训练集,j是θ的向量数量

 

  然后找了找网上的资料,在斯坦福的WIKI里(http://ufldl.stanford.edu/wiki/index.php/Softmax_Regression)写的还是通过对l(θ)进行变换得到J(θ),然后通过对通过梯度下降算法或牛顿算法求出θ,J(θ)和其导数的公式如下:

  
\ {对齐} J(\θ)=  -  \压裂{1} {M} \ [\ sum_ {i = 1} ^ {M} \ sum_ {J = 1} ^ {k}的1 \左\ { Y ^ {(I)} = J \ \} \ LOG \压裂{E ^ {\ theta_j ^ T x ^ {(I)}}} {\ sum_ {L = 1} ^科^ {\ theta_l ^ T X ^ {(I)}}} \] \ {对齐}

 

    

      
\ {对齐} \ nabla_ {\ theta_j} J(\θ)=  -  \压裂{1} {M} \ sum_ {i = 1} ^ {M} {\ [^ {(I)} \离开(1 \ {Y ^ {(I)} = J \}  -  P(Y ^ {(I)} = J | x ^ {(I)} \θ)\)\]} \ {对齐}

softmax回归与建立多个logistic回归:

  在具体使用过程中是建立一个softmax回归好呢还是建立多个logistic回归好呢,这个取决于你所要分的类别是否完全是互斥的,如果是互斥的话使用softmax回归是适当的,反之建立多个logistic回归是合适的,不过在多分类问题上个人更倾向于建立多个二元分类模型的方案,因为这种方案一般得到的F1值会更高,同时线上模块的性能开销也不大。

  下面是网上找到的关于softmax的c代码(实验的代码参考自http://blog.csdn.net/pennyliang/article/details/7048291):

#include <iostream>
#include <cmath>
#include <assert.h>
using namespace std;

const int K = 2;//有K+1类
const int M = 9;//训练集大小
const int N = 4;//特征数

double x[M][N]={{1,47,76,24}, //include x0=1
{1,46,77,23},
{1,48,74,22},
{1,34,76,21},
{1,35,75,24},
{1,34,77,25},
{1,55,76,21},
{1,56,74,22},
{1,55,72,22},
};

double y[M]={1,
1,
1,
2,
2,
2,
3,
3,
3,};

double theta[K][N]={
{0.3,0.3,0.01,0.01},
{0.5,0.5,0.01,0.01}}; // include theta0

double h_value[K];//h(x)向量值

//求exp(QT*x)
double fun_eqx(double* x, double* q)
{
double sum = 0;
for (int i = 0; i < N; i++)
{
sum += x[i] * q[i];
}
return pow(2.718281828, sum);
}

//求h向量
void h(double* x)
{
int i;
double sum = 1;//之前假定theta[K+1]={0},所以exp(Q[K+1]T*x)=1
for (i = 0; i < K; i++)
{
h_value[i] = fun_eqx(x, theta[i]);
sum += h_value[i];
}

assert(sum != 0);

for (i = 0; i < K; i++)
{
h_value[i] /= sum;
}
}

void modify_stochostic()
{
//随机梯度下降,训练参数
int i, j, k;
for (j = 0; j < M; j ++)
{
h(x[j]);
for (i = 0; i < K; i++)
{
for (k = 0; k < N; k++)
{
theta[i][k] += 0.001 * x[j][k] * ((y[j] == i+1?1:0) - h_value[i]);
}
}
}
}
void modify_batch()
{
//批量梯度下降,训练参数
int i, j, k ;
for (i = 0; i < K; i++)
{
double sum[N] = {0.0};
for (j = 0; j < M; j++)
{
h(x[j]);
for (k = 0; k < N; k++)
{
sum[k] += x[j][k] * ((y[j] == i+1?1:0) - h_value[i]);
}
}
for (k = 0; k < N; k++)
{
theta[i][k] += 0.001 * sum[k] / N;
}
}
}

void train(void)
{
int i;
for (i = 0; i < 10000; i++)
{
//modify_stochostic();
modify_batch();
}
}

void predict(double* pre)
{
//输出预测向量
int i;
for (i = 0; i < K; i++)
h_value[i] = 0;
train();
h(pre);
for (i = 0; i < K; i++)
cout << h_value[i] << " ";
cout << 1 - h_value[0] - h_value[1] << endl;
}

int main(void)
{
for (int i=0; i < M; i++)
{
predict(x[i]);
}
cout << endl;
double pre[] = {1,20, 80, 50 };
predict(pre);
return 0;
}

 

代码实现了批量梯度和随机梯度两种方法,实验最后分别将训练样本带入进行估计,迭代10000次的结果为:
stochastic:
0.999504 0.000350044 0.000145502
0.997555 0.00242731 1.72341e-005
0.994635 1.24138e-005 0.00535281
2.59353e-005 0.999974 6.07695e-017
0.00105664 0.998943 -1.09071e-016
4.98481e-005 0.99995 3.45318e-017
0.0018048 1.56509e-012 0.998195
0.000176388 1.90889e-015 0.999824
0.000169041 8.42073e-016 0.999831
 
batch:
0.993387 0.00371185 0.00290158
0.991547 0.0081696 0.000283336
0.979246 0.000132495 0.0206216
0.000630111 0.99937 4.9303e-014
0.00378715 0.996213 9.37462e-014
0.000299602 0.9997 3.50739e-017
0.00759726 2.60939e-010 0.992403
0.0006897 1.09856e-012 0.99931
0.000545117 5.19157e-013 0.999455
 
可见随机梯度收敛的更快。
对于预测来说,输出结果每行的三个数表示是:对于输入来说,是1 2 3三类的概率分别是多少。
posted @ 2013-01-06 01:32  frog_ww  阅读(1029)  评论(0编辑  收藏  举报