• 机器学习之二:分类算法 之 逻辑回归


    分类

    分类应是极为常见的问题,我们生活周边的一切事物,皆是类别分明。机器学习领域,处理分类问题的方法有多种,如逻辑回归、支持向量机、以及无监督学习的K-mean等等。本文主要介始逻辑回归。

    逻辑回归

    逻辑回归,主要用于解决分类问题,例如二分类。

    对于二分类问题,通过给出的样本((x,y))(若为二分类,y={0,1}),确定一个可以对数据一分为二的边界,有了这个边界,对于一个新的样本,根据其特征,便能预测其类属。边界可以是一根直线,或是一个圆,或是一个多边形等。

    对于多分类问题,可以通过执行多次二分类解决:保留要区分的一类,剩下的归为另一类。例如,区分A、B、C类,需执行如下三次二分类:

    首先,保留A类,将B和C归为other,执行二分类,区分出A类。
    接着,保留B类,将A和C归为other,执行二分类,区分出B类。
    同样,保留C类,将A和B归为other,执行二分类,区分出C类。

    分类问题的解决方法,与线性回归类似,一样从误差函数入手,一样使用梯度下降法。

    原理

    分类问题,其 (y) 值一般设置为有限的离散值,例如0、1。所以系统所要做的工作,就是当一个新的样本输入时,需要判断其为可能值的概率分别有多大,以此在确定其y值,即其类属。

    1、模型假设

    令逻辑回归的假设函数为:(h_ heta(x) = g( heta^Tx))

    其中,(g(z) = frac{1}{1+e^{-z}}),为sigmoid函数。

    对g(z)函数的理解

    g(z)函数是来源于最大熵原理,通过拉格朗日乘数法(寻找变量受一个或多个条件限制的多元函数极值的方法)求偏导得出,故而 (h_ heta(x))的值,其实是系统 "认为" 样本为 "1" 的概率值P,即:

    ( h_ heta(x) = P(y=1|x) )

    使用 sigmoid 函数的优点

    以二分类为例,根据输入样本的特征,确定其输出为 0 或 1,显然阶跌函数有这些特性,如下

    image

    可以看到,阶跃函数在 (t_0) 处有两个问题:

    (1) (t_0) 时的值应当认为 0 还是 1?

    (2) (t_0) 发生了跃变,数学上求导麻烦。

    而sigmoid函数,其值满足0~1之间,且为单调递增的连续曲线,比之阶跃函数更有优势。

    2、误差函数

    误差函数为

    ( J = frac{1}{m} sum_{i=1}^{m}[-y^{(i)}log(h_ heta(x^{(i)})) - (1-y^{(i)})log(1-h_ heta(x^{(i)}))] )

    误差函数对 ( heta) 的导数为

    ( grad = frac{1}{m}sum_{i=1}^{m}(h_ heta(x^{(i)})-y^{(i)})x_j^{(i)} )

    一、最简单的二分类,一阶特征,直线边界

    1、误差函数及偏导数

    1.1 误差函数实现

    function [J, grad] = costFunction(theta, X, y)
    
    m = length(y); % number of training examples
    J = 0;
    
    grad = zeros(size(theta));
    
    h = sigmoid(X*theta);
    
    J = ((-y' * log(h)) - (1-y)' * log(1-h))/m;
    
    grad = 1/m .* X' * (h-y); 
    
    % =============================================================
    
    end
    
    

    1.2 误差函数测试

    [m, n] = size(X);
    
    % Add intercept term to x and X_test
    X = [ones(m, 1) X];
    
    % Initialize fitting parameters
    initial_theta = zeros(n + 1, 1);
    
    % Compute and display initial cost and gradient
    [cost, grad] = costFunction(initial_theta, X, y);
    
    fprintf('Cost at initial theta (zeros): %f
    ', cost);
    fprintf('Expected cost (approx): 0.693
    ');
    fprintf('Gradient at initial theta (zeros): 
    ');
    fprintf(' %f 
    ', grad);
    fprintf('Expected gradients (approx):
     -0.1000
     -12.0092
     -11.2628
    ');
    
    % Compute and display cost and gradient with non-zero theta
    test_theta = [-24; 0.2; 0.2];
    [cost, grad] = costFunction(test_theta, X, y);
    
    fprintf('
    Cost at test theta: %f
    ', cost);
    fprintf('Expected cost (approx): 0.218
    ');
    fprintf('Gradient at test theta: 
    ');
    fprintf(' %f 
    ', grad);
    fprintf('Expected gradients (approx):
     0.043
     2.566
     2.647
    ');
    

    2、梯度下降算法

    这里使用优化的函数进行

    %  Set options for fminunc
    options = optimset('GradObj', 'on', 'MaxIter', 400);
    
    %  Run fminunc to obtain the optimal theta
    %  This function will return theta and the cost 
    [theta, cost] = fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);
    
    % Print theta to screen
    fprintf('Cost at theta found by fminunc: %f
    ', cost);
    fprintf('Expected cost (approx): 0.203
    ');
    fprintf('theta: 
    ');
    fprintf(' %f 
    ', theta);
    fprintf('Expected theta (approx):
    ');
    fprintf(' -25.161
     0.206
     0.201
    ');
    
    

    3、预测

    prob = sigmoid([1 45 85] * theta);
    fprintf(['For a student with scores 45 and 85, we predict an admission ' ...
             'probability of %f
    '], prob);
    fprintf('Expected value: 0.775 +/- 0.002
    
    ');
    
    % Compute accuracy on our training set
    p = predict(theta, X);
    
    fprintf('Train Accuracy: %f
    ', mean(double(p == y)) * 100);
    fprintf('Expected accuracy (approx): 89.0
    ');
    

    二、多边形边界

    上面是最简单的分类问题,而现实中的样本,往往需要拟合一条曲线来划分数据,即是多项式拟合。

    其处理方法,基本与上式相同。不同的是需要将特征转为多项式转换,使之能拟合更复杂的边界,如圆、或者其他的不规则图形。

    1、数据预处理,生成多项式特征

    X = mapFeature(X(:,1), X(:,2));
    

    生成多项式的方法如下:

    function out = mapFeature(X1, X2)
    degree = 6;  
    out = ones(size(X1(:,1)));
    for i = 1:degree
        for j = 0:i
            out(:, end+1) = (X1.^(i-j)).*(X2.^j);
        end
    end
    
    end
    

    2、训练

    使用与一阶边界相同的方法

    % Initialize fitting parameters
    initial_theta = zeros(size(X, 2), 1);
    
    % Set Options
    options = optimset('GradObj', 'on', 'MaxIter', 400);
    
    % Optimize
    [theta, J, exit_flag] = ...
    	fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);
    

    3、预测

    二分类的预测方法:对于一个新的样本,分别计算其为0、1概率,取大于0.5的值做为输出。

    p = predict(theta, X);
    fprintf('Train Accuracy: %f
    ', mean(double(p == y)) * 100);
    
    function p = predict(theta, X)
    m = size(X, 1); % Number of training examples
    p = zeros(m, 1);
    p_medium = sigmoid(X*theta);  
    pos = find(p_medium >= 0.5);  
    p(pos,1)=1;  
    end
    
    

    三、多分类问题

    例如给出如下训练集,100张大小为20*20图,内容为0~9的数字

    image

    X 为每张图的像素数值,即特征数 n = 400

    y 为图上的数字,即y = {0,1,2,3,4,5,6,7,8,9}

    1、训练

    [all_theta] = oneVsAll(X, y, num_labels);
    
    

    分别对每个数字进行训练,得出10个theta矩阵。

    function [all_theta] = oneVsAll(X, y, num_labels)
    m = size(X, 1);
    n = size(X, 2);
    all_theta = zeros(num_labels, n + 1);
    
    % Add ones to the X data matrix
    X = [ones(m, 1) X];
    
    initial_thata  = zeros(n+1,1);
    options = optimset('GradObj','on','MaxIter',50);
    for c = 1:num_labels
        [all_theta(c,:)] =  fmincg(@(t)(costFunction(t,X,(y ==c))),initial_thata,options);
    end
    end
    

    2、预测

    输入一张图片,计算其为0~9的各个概率,概率最大的值就是其输出。

    pred = predictOneVsAll(all_theta, X);
    
    fprintf('
    Training Set Accuracy: %f
    ', mean(double(pred == y)) * 100);
    
    
    function p = predictOneVsAll(all_theta, X)
    
    m = size(X, 1);
    num_labels = size(all_theta, 1);
    p = zeros(size(X, 1), 1);
    X = [ones(m, 1) X];
    
    % 计算得出X中,可能的所有概率值,取最大
    h  = sigmoid(X* all_theta');
    [~,p] = max(h,[],2); 
    end
    
    
  • 相关阅读:
    virtual judge(专题一 简单搜索 C)
    virtual judge(专题一 简单搜索 B)
    virtual judge(专题一 简单搜索 A)
    HDU1548(楼梯问题bfs)
    Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2)D(思维,DP,字符串)
    Codeforces Round#522 Div2E(思维,背包,组合数学)
    Codeforces Round #522 Div2C(思维)
    Educational Codeforces Round 53C(二分,思维|构造)
    UPCOJ9526(SG函数打表,nim游戏异或规则)
    Wannafly挑战赛27B(DFS,链表头插法)
  • 原文地址:https://www.cnblogs.com/Fordestiny/p/8561293.html
Copyright © 2020-2023  润新知