1. 程式人生 > 程式設計 >python 實現邏輯迴歸

python 實現邏輯迴歸

邏輯迴歸

適用型別:解決二分類問題

邏輯迴歸的出現:線性迴歸可以預測連續值,但是不能解決分類問題,我們需要根據預測的結果判定其屬於正類還是負類。所以邏輯迴歸就是將線性迴歸的結果,通過Sigmoid函式對映到(0,1)之間

線性迴歸的決策函式:資料與θ的乘法,資料的矩陣格式(樣本數×列數),θ的矩陣格式(列數×1)

python 實現邏輯迴歸

將其通過Sigmoid函式,獲得邏輯迴歸的決策函式

python 實現邏輯迴歸

使用Sigmoid函式的原因:

可以對(-∞,+∞)的結果,對映到(0,1)之間作為概率

可以將1/2作為決策邊界

python 實現邏輯迴歸

數學特性好,求導容易

python 實現邏輯迴歸

邏輯迴歸的損失函式

線性迴歸的損失函式維平方損失函式,如果將其用於邏輯迴歸的損失函式,則其數學特性不好,有很多區域性極小值,難以用梯度下降法求解最優

這裡使用對數損失函式

python 實現邏輯迴歸

解釋:如果一個樣本為正樣本,那麼我們希望將其預測為正樣本的概率p越大越好,也就是決策函式的值越大越好,則logp越大越好,邏輯迴歸的決策函式值就是樣本為正的概率;如果一個樣本為負樣本,那麼我們希望將其預測為負樣本的概率越大越好,也就是(1-p)越大越好,即log(1-p)越大越好

為什麼使用對數函式:樣本集中有很多樣本,要求其概率連乘,概率為0-1之間的數,連乘越來越小,利用log變換將其變為連加,不會溢位,不會超出計算精度

損失函式:: y(1->m)表示Sigmoid值(樣本數×1),hθx(1->m)表示決策函式值(樣本數×1),所以中括號的值(1×1)

python 實現邏輯迴歸

二分類邏輯迴歸直線編碼實現

import numpy as np
from matplotlib import pyplot as plt
​
from scipy.optimize import minimize
from sklearn.preprocessing import PolynomialFeatures
​
​
class MyLogisticRegression:
  def __init__(self):
    plt.rcParams["font.sans-serif"] = ["SimHei"]
    # 包含資料和標籤的資料集
    self.data = np.loadtxt("./data2.txt",delimiter=",")
    self.data_mat = self.data[:,0:2]
    self.label_mat = self.data[:,2]
    self.thetas = np.zeros((self.data_mat.shape[1]))
​
    # 生成多項式特徵,最高6次項
    self.poly = PolynomialFeatures(6)
    self.p_data_mat = self.poly.fit_transform(self.data_mat)
​
  def cost_func_reg(self,theta,reg):
    """
    損失函式具體實現
    :param theta: 邏輯迴歸係數
    :param data_mat: 帶有截距項的資料集
    :param label_mat: 標籤資料集
    :param reg:
    :return:
    """
    m = self.label_mat.size
    label_mat = self.label_mat.reshape(-1,1)
    h = self.sigmoid(self.p_data_mat.dot(theta))
​
    J = -1 * (1/m)*(np.log(h).T.dot(label_mat) + np.log(1-h).T.dot(1-label_mat))\
      + (reg / (2*m)) * np.sum(np.square(theta[1:]))
    if np.isnan(J[0]):
      return np.inf
    return J[0]
​
  def gradient_reg(self,reg):
    m = self.label_mat.size
    h = self.sigmoid(self.p_data_mat.dot(theta.reshape(-1,1)))
    label_mat = self.label_mat.reshape(-1,1)
​
    grad = (1 / m)*self.p_data_mat.T.dot(h-label_mat) + (reg/m)*np.r_[[[0]],theta[1:].reshape(-1,1)]
    return grad
​
  def gradient_descent_reg(self,alpha=0.01,reg=0,iterations=200):
    """
    邏輯迴歸梯度下降收斂函式
    :param alpha: 學習率
    :param reg:
    :param iterations: 最大迭代次數
    :return: 邏輯迴歸係數組
    """
    m,n = self.p_data_mat.shape
    theta = np.zeros((n,1))
    theta_set = []
​
    for i in range(iterations):
      grad = self.gradient_reg(theta,reg)
      theta = theta - alpha*grad.reshape(-1,1)
      theta_set.append(theta)
    return theta,theta_set
​
  def plot_data_reg(self,x_label=None,y_label=None,neg_text="negative",pos_text="positive",thetas=None):
    neg = self.label_mat == 0
    pos = self.label_mat == 1
    fig1 = plt.figure(figsize=(12,8))
    ax1 = fig1.add_subplot(111)
    ax1.scatter(self.p_data_mat[neg][:,1],self.p_data_mat[neg][:,2],marker="o",s=100,label=neg_text)
    ax1.scatter(self.p_data_mat[pos][:,self.p_data_mat[pos][:,marker="+",label=pos_text)
    ax1.set_xlabel(x_label,fontsize=14)
​
    # 描繪邏輯迴歸直線(曲線)
    if isinstance(thetas,type(np.array([]))):
      x1_min,x1_max = self.p_data_mat[:,1].min(),self.p_data_mat[:,1].max()
      x2_min,x2_max = self.p_data_mat[:,2].min(),2].max()
      xx1,xx2 = np.meshgrid(np.linspace(x1_min,x1_max),np.linspace(x2_min,x2_max))
      h = self.sigmoid(self.poly.fit_transform(np.c_[xx1.ravel(),xx2.ravel()]).dot(thetas))
      h = h.reshape(xx1.shape)
      ax1.contour(xx1,xx2,h,[0.5],linewidths=3)
    ax1.legend(fontsize=14)
    plt.show()
​
  @staticmethod
  def sigmoid(z):
    return 1.0 / (1 + np.exp(-z))
​
​
if __name__ == '__main__':
  my_logistic_regression = MyLogisticRegression()
  # my_logistic_regression.plot_data(x_label="線性不可分資料集")
​
  thetas,theta_set = my_logistic_regression.gradient_descent_reg(alpha=0.5,iterations=500)
  my_logistic_regression.plot_data_reg(thetas=thetas,x_label="$\\lambda$ = {}".format(0))
​
  thetas = np.zeros((my_logistic_regression.p_data_mat.shape[1],1))
  # 未知錯誤,有大佬解決可留言
  result = minimize(my_logistic_regression.cost_func_reg,thetas,args=(0,),method=None,jac=my_logistic_regression.gradient_reg)
  my_logistic_regression.plot_data_reg(thetas=result.x,x_label="$\\lambda$ = {}".format(0))

二分類問題邏輯迴歸曲線編碼實現

import numpy as np
from matplotlib import pyplot as plt
​
from scipy.optimize import minimize
from sklearn.preprocessing import PolynomialFeatures
​
​
class MyLogisticRegression:
  def __init__(self):
    plt.rcParams["font.sans-serif"] = ["SimHei"]
    # 包含資料和標籤的資料集
    self.data = np.loadtxt("./data2.txt",x_label="$\\lambda$ = {}".format(0))

以上就是python 實現邏輯迴歸的詳細內容,更多關於python 實現邏輯迴歸的資料請關注我們其它相關文章!