python 實(shí)現(xiàn)邏輯回歸
邏輯回歸
適用類(lèi)型:解決二分類(lèi)問(wèn)題
邏輯回歸的出現(xiàn):線性回歸可以預(yù)測(cè)連續(xù)值,但是不能解決分類(lèi)問(wèn)題,我們需要根據(jù)預(yù)測(cè)的結(jié)果判定其屬于正類(lèi)還是負(fù)類(lèi)。所以邏輯回歸就是將線性回歸的結(jié)果,通過(guò)Sigmoid函數(shù)映射到(0,1)之間
線性回歸的決策函數(shù):數(shù)據(jù)與θ的乘法,數(shù)據(jù)的矩陣格式(樣本數(shù)×列數(shù)),θ的矩陣格式(列數(shù)×1)
將其通過(guò)Sigmoid函數(shù),獲得邏輯回歸的決策函數(shù)
使用Sigmoid函數(shù)的原因:
可以對(duì)(-∞, +∞)的結(jié)果,映射到(0, 1)之間作為概率
可以將1/2作為決策邊界
數(shù)學(xué)特性好,求導(dǎo)容易
邏輯回歸的損失函數(shù)
線性回歸的損失函數(shù)維平方損失函數(shù),如果將其用于邏輯回歸的損失函數(shù),則其數(shù)學(xué)特性不好,有很多局部極小值,難以用梯度下降法求解最優(yōu)
這里使用對(duì)數(shù)損失函數(shù)
解釋:如果一個(gè)樣本為正樣本,那么我們希望將其預(yù)測(cè)為正樣本的概率p越大越好,也就是決策函數(shù)的值越大越好,則logp越大越好,邏輯回歸的決策函數(shù)值就是樣本為正的概率;如果一個(gè)樣本為負(fù)樣本,那么我們希望將其預(yù)測(cè)為負(fù)樣本的概率越大越好,也就是(1-p)越大越好,即log(1-p)越大越好
為什么使用對(duì)數(shù)函數(shù):樣本集中有很多樣本,要求其概率連乘,概率為0-1之間的數(shù),連乘越來(lái)越小,利用log變換將其變?yōu)檫B加,不會(huì)溢出,不會(huì)超出計(jì)算精度
損失函數(shù):: y(1->m)表示Sigmoid值(樣本數(shù)×1),hθx(1->m)表示決策函數(shù)值(樣本數(shù)×1),所以中括號(hào)的值(1×1)
二分類(lèi)邏輯回歸直線編碼實(shí)現(xiàn)
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"] # 包含數(shù)據(jù)和標(biāo)簽的數(shù)據(jù)集 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])) # 生成多項(xiàng)式特征,最高6次項(xiàng) self.poly = PolynomialFeatures(6) self.p_data_mat = self.poly.fit_transform(self.data_mat) def cost_func_reg(self, theta, reg): """ 損失函數(shù)具體實(shí)現(xiàn) :param theta: 邏輯回歸系數(shù) :param data_mat: 帶有截距項(xiàng)的數(shù)據(jù)集 :param label_mat: 標(biāo)簽數(shù)據(jù)集 :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, theta, 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): """ 邏輯回歸梯度下降收斂函數(shù) :param alpha: 學(xué)習(xí)率 :param reg: :param iterations: 最大迭代次數(shù) :return: 邏輯回歸系數(shù)組 """ 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][:, 1], self.p_data_mat[pos][:, 2], marker="+", s=100, 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(), self.p_data_mat[:, 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="線性不可分?jǐn)?shù)據(jù)集") thetas, theta_set = my_logistic_regression.gradient_descent_reg(alpha=0.5, reg=0, 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)) # 未知錯(cuò)誤,有大佬解決可留言 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))
二分類(lèi)問(wèn)題邏輯回歸曲線編碼實(shí)現(xiàn)
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"] # 包含數(shù)據(jù)和標(biāo)簽的數(shù)據(jù)集 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])) # 生成多項(xiàng)式特征,最高6次項(xiàng) self.poly = PolynomialFeatures(6) self.p_data_mat = self.poly.fit_transform(self.data_mat) def cost_func_reg(self, theta, reg): """ 損失函數(shù)具體實(shí)現(xiàn) :param theta: 邏輯回歸系數(shù) :param data_mat: 帶有截距項(xiàng)的數(shù)據(jù)集 :param label_mat: 標(biāo)簽數(shù)據(jù)集 :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, theta, 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): """ 邏輯回歸梯度下降收斂函數(shù) :param alpha: 學(xué)習(xí)率 :param reg: :param iterations: 最大迭代次數(shù) :return: 邏輯回歸系數(shù)組 """ 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][:, 1], self.p_data_mat[pos][:, 2], marker="+", s=100, 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(), self.p_data_mat[:, 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="線性不可分?jǐn)?shù)據(jù)集") thetas, theta_set = my_logistic_regression.gradient_descent_reg(alpha=0.5, reg=0, 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)) # 未知錯(cuò)誤,有大佬解決可留言 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))
以上就是python 實(shí)現(xiàn)邏輯回歸的詳細(xì)內(nèi)容,更多關(guān)于python 實(shí)現(xiàn)邏輯回歸的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Python 關(guān)聯(lián)規(guī)則分析
這篇文章主要介紹了Python 關(guān)聯(lián)規(guī)則分析的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-03-03node命令行服務(wù)器(http-server)和跨域的實(shí)現(xiàn)
本文主要介紹了node命令行服務(wù)器(http-server)和跨域的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02解析Python中的eval()、exec()及其相關(guān)函數(shù)
本篇文章主要介紹了解析Python中的eval()、exec()及其相關(guān)函數(shù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12python執(zhí)行系統(tǒng)命令4種方法與比較
這篇文章主要介紹了python執(zhí)行系統(tǒng)命令4種方法與比較,需要的朋友可以參考下2021-04-04Python將Office文檔(Word、Excel、PDF、PPT)轉(zhuǎn)為OFD格式的實(shí)現(xiàn)方法
OFD(Open Fixed-layout Document )是我國(guó)自主制定的一種開(kāi)放版式文件格式標(biāo)準(zhǔn),如果想要通過(guò)Python將Office文檔(如Word、Excel或PowerPoint)及PDF文檔轉(zhuǎn)換為OFD格式,可以參考本文中提供的實(shí)現(xiàn)方法,需要的朋友可以參考下2024-06-06PyCharm搭建一勞永逸的開(kāi)發(fā)環(huán)境
這篇文章主要介紹了PyCharm搭建一勞永逸的開(kāi)發(fā)環(huán)境,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04python多繼承(鉆石繼承)問(wèn)題和解決方法簡(jiǎn)單示例
這篇文章主要介紹了python多繼承(鉆石繼承)問(wèn)題和解決方法,結(jié)合實(shí)例形式分析了Python多繼承調(diào)用父類(lèi)初始化方法相關(guān)操作技巧,需要的朋友可以參考下2019-10-10