ex2练习

 

  • 特征映射(两个特征映射成六次多项式)
    X = mapFeature(X(:,1), X(:,2));
    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

     

  • 假设函数
    g = 1./(1+exp(-z)); % 计算时z用 X*theta 替换
                        % g是m*1向量,用./对每一项进行计算

         h_\theta(x)=g(\theta^\intercal x)=g(z)=\frac{1}{1+e^{-z}}

  •  代价函数和偏导 
% 无正则项
J =(1/m)*((-y)'*log(sigmoid(X*theta))-(1-y)'*log(1-sigmoid(X*theta)));
grad = ((1/m)*(sigmoid(X*theta)-y)'*X)'; % 和theta维度一样,m*1
% 引入正则项
theta_cp =theta;
theta_cp(1) = 0;
% 计算正则项不包括theta(1)
J = (1/m)*((-y)'*log(sigmoid(X*theta))-(1-y)'*log(1-sigmoid(X*theta)))+(lambda/(2*m))*(theta_cp'*theta_cp);
grad = ((1/m)*(sigmoid(X*theta)-y)'*X)' + (lambda/m)*theta_cp;

 无正则项:

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

\frac{\partial(J(\theta))}{\partial(\theta_j)}=\frac{1}{m}\sum_{i=1}^m{(h_\theta(x^{(i)})-y^{(i)})x^{(i)}_j}

引入正则项: 

       J(\theta)=\frac{1}{m}\sum_{i=1}^{m}[-y^{(i)}log{(h_\theta(x^{(i)})})-(1-y^{(i)})log{(1-h_\theta(x^{(i)})})]+\frac{\lambda}{2m}\sum_{j=1}^n\theta_j^2

       \frac{\partial(J(\theta))}{\partial(\theta_j)}=\frac{1}{m}\sum_{i=1}^m{(h_\theta(x^{(i)})-y^{(i)})x^{(i)}_j} \dots (j=0)

       \frac{\partial(J(\theta))}{\partial(\theta_j)}=\frac{1}{m}\sum_{i=1}^m{(h_\theta(x^{(i)})-y^{(i)})x^{(i)}_j}+\frac{\lambda}{m}\theta_j \dots (j>=1) 

 

 

 

  • 使用fminunc得到theta 
    data = load('ex2data1.txt');
    X = data(:, [1, 2]);
    y = data(:, 3);
    [m, n] = size(X);
    X = [ones(m, 1) X];
    initial_theta = zeros(n + 1, 1);
    options = optimset('GradObj', 'on', 'MaxIter', 400);
    
    % 无正则项
    [theta, cost] = ...
    	fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);
    
    % 有正则项
    lambda = 1;
    [theta, J, exit_flag] = ...
    	fminunc(@(t)(costFunctionReg(t, X, y, lambda)), initial_theta, options);
    

     

  • 预测(阈值0.5)
    pos = find(sigmoid(X*theta) >= 0.5);
    neg = find(sigmoid(X*theta) < 0.5);
    % p是m*1维向量
    p(pos,1) = 1;
    p(neg,1) = 0;
    % 判断准确度
    fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100);

     

  • 绘图
    • 绘样本图
      % 寻找正负样本
      pos = find(y==1); neg = find(y == 0);
      % 正负样本分别绘制
      plot(X(pos, 1), X(pos, 2), 'k+','LineWidth', 2, 'MarkerSize', 7);
      plot(X(neg, 1), X(neg, 2), 'ko', 'MarkerFaceColor', 'y','MarkerSize', 7);
      
      hold on;
      xlabel('Exam 1 score')
      ylabel('Exam 2 score')
      legend('Admitted', 'Not admitted')
      hold off;

       

    • 绘边界图
      plotData(X(:,2:3), y); % 绘制散点
      hold on
      if size(X, 2) <= 3     % 如果特征数小于等于3,即边界面为直线,只需要两点确定一直线
          plot_x = [min(X(:,2))-2,  max(X(:,2))+2]; % 按特征x(2),选择最大、最小两点
          plot_y = (-1./theta(3)).*(theta(2).*plot_x + theta(1));
                                             % 根据theta(1)+theta(2)x(1)+theta(3)x(2)=0,计算x(3)
          plot(plot_x, plot_y) % 绘制曲线
          legend('Admitted', 'Not admitted', 'Decision Boundary')
          axis([30, 100, 30, 100])
      else                   % 如果特征数大于3,即边界面为曲线
          u = linspace(-1, 1.5, 50);
          v = linspace(-1, 1.5, 50);
          z = zeros(length(u), length(v));
          for i = 1:length(u)
              for j = 1:length(v)
                  z(i,j) = mapFeature(u(i), v(j))*theta;
              end
          end
          z = z';
          contour(u, v, z, [0, 0], 'LineWidth', 2) % z=0 刚好是分界面
      end
      hold off

       

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本文将演示如何使用sigmoid函数完成一个简单的学生成绩预测模型,模型的目标是根据学生的两门成绩预测该学生是否被录取。我们将使用逻辑回归算法来训练模型,并使用Python的NumPy库和matplotlib库进行数据处理和可视化。 首先,我们需要导入相应的库和数据集。数据集包含了两门考试的成绩和每个学生是否被录取的信息。 ```python import numpy as np import matplotlib.pyplot as plt # 导入数据集 data = np.loadtxt('ex2data1.txt', delimiter=',') X = data[:, :-1] # 特征矩阵 y = data[:, -1] # 目标矩阵 # 将y转换为行向量 y = y.reshape((len(y), 1)) ``` 接下来,我们需要对数据进行可视化,看看这些数据的分布情况。我们将根据目标矩阵y的值,将数据点的颜色区分为蓝色和红色,其中蓝色表示未被录取,红色表示已被录取。 ```python # 数据可视化 def plot_data(X, y): # 将数据按照分类分别画出 pos = (y == 1).reshape(len(y)) neg = (y == 0).reshape(len(y)) plt.scatter(X[pos, 0], X[pos, 1], marker='+', c='r') plt.scatter(X[neg, 0], X[neg, 1], marker='o', c='b') plt.xlabel('Exam 1 score') plt.ylabel('Exam 2 score') plt.legend(['Admitted', 'Not admitted']) plt.show() plot_data(X, y) ``` 在数据可视化完成后,我们可以看到两门成绩的分布情况,以及哪些学生被录取,哪些学生没有被录取。 ![image-20211019152047226](https://i.loli.net/2021/10/19/8WAguvIrtwMfJbY.png) 可以看到,这些数据是线性可分的,我们可以使用逻辑回归算法来训练模型。 逻辑回归算法的核心在于使用sigmoid函数作为模型的预测函数。sigmoid函数可以将任意实数映射到0到1之间的一个值,因此它非常适合用于二分类问题。sigmoid函数的公式为: $$ g(z) = \frac{1}{1+e^{-z}} $$ 其中$z=w^Tx$,$w$表示权重向量,$x$表示特征向量。 我们可以将逻辑回归算法表示为: $$ h_\theta (x) = g(\theta^Tx) = \frac{1}{1+e^{-\theta^Tx}} $$ 其中$h_\theta (x)$表示模型的预测值,$\theta$表示模型的参数,具体地,$\theta$是一个列向量,其长度等于特征向量$x$的长度加1,因为我们要让模型可以学习到一个截距参数。 接下来,我们需要定义sigmoid函数和代价函数。代价函数的公式为: $$ J(\theta) = -\frac{1}{m}\sum_{i=1}^{m}[y^{(i)}log(h_{\theta} (x^{(i)})) + (1-y^{(i)})log(1-h_{\theta} (x^{(i)}))] $$ 其中$m$表示样本数。 ```python # 定义sigmoid函数 def sigmoid(z): return 1 / (1 + np.exp(-z)) # 定义代价函数 def cost_function(theta, X, y): m = len(y) h = sigmoid(X @ theta) J = 1 / m * np.sum(-y * np.log(h) - (1 - y) * np.log(1 - h)) return J ``` 接下来,我们需要初始化模型的参数,然后使用梯度下降算法来最小化代价函数。梯度下降算法的公式为: $$ \theta_j = \theta_j - \alpha\frac{\partial}{\partial\theta_j}J(\theta) $$ 其中$\alpha$表示学习率,$\frac{\partial}{\partial\theta_j}J(\theta)$表示代价函数对于$\theta_j$的偏导数。 ```python # 初始化参数 m, n = X.shape X = np.hstack((np.ones((m, 1)), X)) # 增加一列新特征x0,其值恒为1 initial_theta = np.zeros((n + 1, 1)) # 定义梯度下降函数 def gradient_descent(theta, X, y, alpha, num_iters): m = len(y) J_history = np.zeros((num_iters, 1)) for i in range(num_iters): h = sigmoid(X @ theta) theta -= alpha / m * X.T @ (h - y) J_history[i] = cost_function(theta, X, y) if i % 100 == 0: print('Iteration %d | Cost: %f' % (i, J_history[i])) return theta, J_history # 运行梯度下降算法 alpha = 0.01 num_iters = 5000 theta, J_history = gradient_descent(initial_theta, X, y, alpha, num_iters) print('Theta:', theta) print('Cost:', J_history[-1]) ``` 梯度下降算法执行完毕后,我们可以看到模型的参数$\theta$和代价函数的最终值。 接下来,我们需要绘制代价函数的变化图表,以便我们观察模型的训练过程。 ```python # 绘制代价函数图表 def plot_cost_function(J_history): plt.plot(J_history) plt.xlabel('Iterations') plt.ylabel('Cost') plt.title('Cost Function') plt.show() plot_cost_function(J_history) ``` 代价函数随着训练迭代次数的增加而降低,说明模型的训练效果不错。 ![image-20211019153020888](https://i.loli.net/2021/10/19/wfyrjJV7e92P6xG.png) 最后,我们需要绘制决策边界,即将模型的预测结果可视化展示。由于我们训练的模型是一个二分类模型,因此决策边界是一个直线。我们可以通过找到sigmoid函数原点的位置来计算决策边界的斜率和截距。 ```python # 绘制决策边界 def plot_decision_boundary(theta, X, y): plot_data(X[:, 1:], y) # 计算决策边界 x_boundary = np.array([np.min(X[:, 1]), np.max(X[:, 1])]) y_boundary = -(theta[0] + theta[1] * x_boundary) / theta[2] plt.plot(x_boundary, y_boundary) plt.show() plot_decision_boundary(theta, X, y) ``` 将决策边界和数据点绘制在同一张图表上,可以清晰地看到哪些学生被录取了,哪些学生没有被录取。 ![image-20211019153703768](https://i.loli.net/2021/10/19/2zokxISnN7QYdHu.png) 从以上结果可以看出,我们通过sigmoid函数和逻辑回归算法成功地训练了一个学生成绩预测模型,并使用该模型成功地预测了哪些学生会被录取。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值