def mk_cost_lines(self, firsttime=False): ''' makes vertical cost lines''' if not firsttime: for artist in self.cost_items: artist.remove() self.cost_items = [] cstr = f"cost = (1/{self.m})*(" ctot = 0 label = 'cost for point' addedbreak = False for p in zip(self.x_train, self.y_train): f_wb_p = sigmoid(self.w * p[0] + self.b) c_p = compute_cost_matrix(p[0].reshape(-1, 1), p[1], np.array(self.w), self.b, logistic=True, lambda_=0, safe=True) c_p_txt = c_p a = self.ax.vlines(p[0], p[1], f_wb_p, lw=3, color=dlc["dlpurple"], ls='dotted', label=label) label = '' #just one cxy = [p[0], p[1] + (f_wb_p - p[1]) / 2] b = self.ax.annotate(f'{c_p_txt:0.1f}', xy=cxy, xycoords='data', color=dlc["dlpurple"], xytext=(5, 0), textcoords='offset points') cstr += f"{c_p_txt:0.1f} +" if len(cstr) > 38 and addedbreak is False: cstr += "\n" addedbreak = True ctot += c_p self.cost_items.extend((a, b)) ctot = ctot / (len(self.x_train)) cstr = cstr[:-1] + f") = {ctot:0.2f}" ## todo.. figure out how to get this textbox to extend to the width of the subplot c = self.ax.text(0.05, 0.02, cstr, transform=self.ax.transAxes, color=dlc["dlpurple"]) self.cost_items.append(c)
def compute_cost_logistic_sq_err(X, y, w, b): """ compute sq error cost on logicist data (for negative example only, not used in practice) Args: X (ndarray): Shape (m,n) matrix of examples with multiple features w (ndarray): Shape (n) parameters for prediction b (scalar): parameter for prediction Returns: cost (scalar): cost """ m = X.shape[0] cost = 0.0 for i in range(m): z_i = np.dot(X[i], w) + b f_wb_i = sigmoid( z_i) #add sigmoid to normal sq error cost for linear regression cost = cost + (f_wb_i - y[i])**2 cost = cost / (2 * m) return np.squeeze(cost)
def draw_logistic_lines(self, firsttime=False): if not firsttime: self.aline[0].remove() self.bline[0].remove() self.alegend.remove() xlim = self.ax.get_xlim() x_hat = np.linspace(*xlim, 30) y_hat = sigmoid(np.dot(x_hat.reshape(-1, 1), self.w) + self.b) self.aline = self.ax.plot(x_hat, y_hat, color=dlc["dlblue"], label="y = sigmoid(z)") f_wb = np.dot(x_hat.reshape(-1, 1), self.w) + self.b self.bline = self.ax.plot( x_hat, f_wb, color=dlc["dlorange"], lw=1, label=f"z = {np.squeeze(self.w):0.2f}x+({self.b:0.2f})") self.alegend = self.ax.legend(loc='upper left')
def plt_prob(ax, w_out, b_out): """ plots a decision boundary but include shading to indicate the probability """ #setup useful ranges and common linspaces x0_space = np.linspace(0, 4, 100) x1_space = np.linspace(0, 4, 100) # get probability for x0,x1 ranges tmp_x0, tmp_x1 = np.meshgrid(x0_space, x1_space) z = np.zeros_like(tmp_x0) for i in range(tmp_x0.shape[0]): for j in range(tmp_x1.shape[1]): z[i, j] = sigmoid( np.dot(w_out, np.array([tmp_x0[i, j], tmp_x1[i, j]])) + b_out) cmap = plt.get_cmap('Blues') new_cmap = truncate_colormap(cmap, 0.0, 0.5) pcm = ax.pcolormesh(tmp_x0, tmp_x1, z, norm=cm.colors.Normalize(vmin=0, vmax=1), cmap=new_cmap, shading='nearest', alpha=0.9) ax.figure.colorbar(pcm, ax=ax)
def calc_logistic(self, event): if self.bthresh.get_status()[0]: self.remove_thresh() for it in [1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096]: self.w, self.b, _ = gradient_descent(self.x.reshape(-1, 1), self.y.reshape(-1, 1), self.w.reshape(-1, 1), self.b, 0.1, it, logistic=True, lambda_=0, verbose=False) self.aline[0].remove() self.bline[0].remove() self.alegend.remove() xlim = self.ax[0].get_xlim() x_hat = np.linspace(*xlim, 30) y_hat = sigmoid(np.matmul(x_hat.reshape(-1, 1), self.w) + self.b) self.aline = self.ax[0].plot(x_hat, y_hat, color=dlblue, label="y = sigmoid(z)") f_wb = np.matmul(x_hat.reshape(-1, 1), self.w) + self.b self.bline = self.ax[0].plot( x_hat, f_wb, color=dlorange, lw=1, label=f"z = {np.squeeze(self.w):0.2f}x+({self.b:0.2f})") self.alegend = self.ax[0].legend(loc='lower right') time.sleep(0.3) self.fig.canvas.draw() if self.bthresh.get_status()[0]: self.draw_thresh() self.fig.canvas.draw()
def __init__(self, x, y, w, b, logistic=True): self.logistic = logistic pos = y == 1 neg = y == 0 fig, ax = plt.subplots(1, 1, figsize=(8, 4)) fig.canvas.toolbar_visible = False fig.canvas.header_visible = False fig.canvas.footer_visible = False plt.subplots_adjust(bottom=0.25) ax.scatter(x[pos], y[pos], marker='x', s=80, c='red', label="malignant") ax.scatter(x[neg], y[neg], marker='o', s=100, label="benign", facecolors='none', edgecolors=dlblue, lw=3) ax.set_ylim(-0.05, 1.1) xlim = ax.get_xlim() ax.set_xlim(xlim[0], xlim[1] * 2) ax.set_ylabel('y') ax.set_xlabel('Tumor Size') self.alegend = ax.legend(loc='lower right') if self.logistic: ax.set_title("Example of Logistic Regression on Categorical Data") else: ax.set_title("Example of Linear Regression on Categorical Data") ax.text(0.65, 0.8, "[Click to add data points]", size=10, transform=ax.transAxes) axcalc = plt.axes([0.1, 0.05, 0.38, 0.075]) #l,b,w,h axthresh = plt.axes([0.5, 0.05, 0.38, 0.075]) #l,b,w,h self.tlist = [] self.fig = fig self.ax = [ax, axcalc, axthresh] self.x = x self.y = y self.w = copy.deepcopy(w) self.b = b f_wb = np.matmul(self.x.reshape(-1, 1), self.w) + self.b if self.logistic: self.aline = self.ax[0].plot(self.x, sigmoid(f_wb), color=dlblue) self.bline = self.ax[0].plot(self.x, f_wb, color=dlorange, lw=1) else: self.aline = self.ax[0].plot(self.x, sigmoid(f_wb), color=dlblue) self.cid = fig.canvas.mpl_connect('button_press_event', self.add_data) if self.logistic: self.bcalc = Button(axcalc, 'Run Logistic Regression (click)', color=dlblue) self.bcalc.on_clicked(self.calc_logistic) else: self.bcalc = Button(axcalc, 'Run Linear Regression (click)', color=dlblue) self.bcalc.on_clicked(self.calc_linear) self.bthresh = CheckButtons( axthresh, ('Toggle 0.5 threshold (after regression)', )) self.bthresh.on_clicked(self.thresh) self.resize_sq(self.bthresh)