机器学习入门笔记06:逻辑回归

逻辑回归

  • 学习逻辑回归原理

  • 实现代码

      import numpy as np
      import matplotlib.pyplot as plt
      from sklearn import datasets
      from sklearn.model_selection import train_test_split
      # 因为逻辑回归是分类问题,因此需要对评价指标进行更改
      #from .metrics import accuracy_score
      
      
      class LogisticRegression:
      
      def __init__(self):
      """初始化Logistic Regression模型"""
      self.coef_ = None
      self.intercept_ = None
      self._theta = None
      
      """
      定义sigmoid方法
      参数:线性模型t
      输出:sigmoid表达式
      """
      
      def _sigmoid(self, t):
      return 1. / (1. + np.exp(-t))
      
      """
      fit方法,内部使用梯度下降法训练Logistic Regression模型
      参数:训练数据集X_train, y_train, 学习率, 迭代次数
      输出:训练好的模型
      """
      
      def fit(self, X_train, y_train, eta=0.01, n_iters=1e4):
      
      assert X_train.shape[0] == y_train.shape[0], \
      "the size of X_train must be equal to the size of y_train"
      
      """
      定义逻辑回归的损失函数
      参数:参数theta、构造好的矩阵X_b、标签y
      输出:损失函数表达式
      """
      
      def J(theta, X_b, y):
      # 定义逻辑回归的模型:y_hat
      y_hat = self._sigmoid(X_b.dot(theta))
      try:
      # 返回损失函数的表达式
      return - np.sum(y * np.log(y_hat) + (1 - y) * np.log(1 - y_hat)) / len(y)
      except:
      return float('inf')
      
      """
      损失函数的导数计算
      参数:参数theta、构造好的矩阵X_b、标签y
      输出:计算的表达式
      """
      
      def dJ(theta, X_b, y):
      return X_b.T.dot(self._sigmoid(X_b.dot(theta)) - y) / len(y)
      
      """
      梯度下降的过程
      """
      
      def gradient_descent(X_b, y, initial_theta, eta, n_iters=1e4, epsilon=1e-8):
      theta = initial_theta
      cur_iter = 0
      while cur_iter < n_iters:
      gradient = dJ(theta, X_b, y)
      last_theta = theta
      theta = theta - eta * gradient
      if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
      break
      cur_iter += 1
      return theta
      
      X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
      initial_theta = np.zeros(X_b.shape[1])
      # 梯度下降的结果求出参数heta
      self._theta = gradient_descent(X_b, y_train, initial_theta, eta, n_iters)
      # 第一个参数为截距
      self.intercept_ = self._theta[0]
      # 其他参数为各特征的系数
      self.coef_ = self._theta[1:]
      return self
      
      """
      逻辑回归是根据概率进行分类的,因此先预测概率
      参数:输入空间X_predict
      输出:结果概率向量
      """
      
      def predict_proba(self, X_predict):
      """给定待预测数据集X_predict,返回表示X_predict的结果概率向量"""
      assert self.intercept_ is not None and self.coef_ is not None, \
      "must fit before predict!"
      assert X_predict.shape[1] == len(self.coef_), \
      "the feature number of X_predict must be equal to X_train"
      
      X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
      # 将梯度下降得到的参数theta带入逻辑回归的表达式中
      return self._sigmoid(X_b.dot(self._theta))
      
      """
      使用X_predict的结果概率向量,将其转换为分类
      参数:输入空间X_predict
      输出:分类结果
      """
      
      def predict(self, X_predict):
      """给定待预测数据集X_predict,返回表示X_predict的结果向量"""
      assert self.intercept_ is not None and self.coef_ is not None, \
      "must fit before predict!"
      assert X_predict.shape[1] == len(self.coef_), \
      "the feature number of X_predict must be equal to X_train"
      # 得到概率
      proba = self.predict_proba(X_predict)
      # 判断概率是否大于0.5,然后将布尔表达式得到的向量,强转为int类型,即为0-1向量
      return np.array(proba >= 0.5, dtype='int')
      
      def score(self, X_test, y_test):
      """根据测试数据集 X_test 和 y_test 确定当前模型的准确度"""
      
      y_predict = self.predict(X_test)
      return accuracy_score(y_test, y_predict)
      
      def __repr__(self):
      return "LogisticRegression()"
      
      iris = datasets.load_iris()
      X = iris.data
      y = iris.target
      X = X[y<2,:2]
      y = y[y<2]
      plt.scatter(X[y==0,0], X[y==0,1], color="red")
      plt.scatter(X[y==1,0], X[y==1,1], color="blue")
      plt.show()
      
      X_train, X_test, y_train, y_test = train_test_split(X, y, seed=666)
      log_reg = LogisticRegression()
      log_reg.fit(X_train, y_train)
      # 查看训练数据集分类准确度
      log_reg.score(X_test, y_test)
      """
      输出:1.0
      """
      
      # 查看逻辑回归得到的概率
      log_reg.predict_proba(X_test)
      """
      输出:
      array([ 0.92972035,  0.98664939,  0.14852024,  0.17601199,  0.0369836 ,
      0.0186637 ,  0.04936918,  0.99669244,  0.97993941,  0.74524655,
      0.04473194,  0.00339285,  0.26131273,  0.0369836 ,  0.84192923,
      0.79892262,  0.82890209,  0.32358166,  0.06535323,  0.20735334])
      """
      
      # 得到逻辑回归分类结果
      log_reg.predict(X_test)
      """
      输出:
      array([1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0])
      """

你可能感兴趣的:(机器学习入门笔记06:逻辑回归)