def __init__(self): self.plot = SingleClassPlot() self.container = ParametricPlotContainer(self.plot) self.container.slider(value=0.5, start=0.1, end=5, step=0.1, title="Kernel Width") self.container.slider(value=1, start=0.1, end=5, step=0.1, title="Kernel Amplitude") self.container.slider(value=0.1, start=0.01, end=1, step=0.01, title="Prior Variance") self.point_estimate = self.plot.figure.line(x=[], y=[]) self.uncertainty_range = self.plot.figure.patch(x=[], y=[], fill_alpha=0.5) self.plot.add_change_listener(self.update_plot) self.plot.enable_interaction()
class InteractiveBayesianPolynomialRegression(SingleClassPlot): PLOT_POINTS = 150 def __init__(self): self.plot = SingleClassPlot() self.container = ParametricPlotContainer(self.plot) self.container.slider(value=1, start=0, end=15, step=1, title="Polynomial Degree") self.container.slider(value=0.4, start=0.01, end=5, step=0.01, title="Prior Variance") self.container.slider(value=0.1, start=0.01, end=5, step=0.01, title="Noise Variance") self.point_estimate = self.plot.figure.line(x=[], y=[]) self.uncertainty_range = self.plot.figure.patch(x=[], y=[], fill_alpha=0.5) self.plot.enable_interaction() self.plot.add_change_listener(self.update_plot) def update_plot(self, plot_state): inputs = np.linspace(*X_RANGE, self.PLOT_POINTS) basis = ScalarBasisFunctions.Polynomial(plot_state['Polynomial Degree']) X_predict = basis(inputs) regressor = BayesianLinearRegression( prior_mean = np.zeros((plot_state['Polynomial Degree'] + 1,)), prior_covariance = plot_state['Prior Variance'] * np.identity(plot_state['Polynomial Degree'] + 1), s2y = plot_state['Noise Variance'] ) data = plot_state['inputs'] regressor.fit(basis(np.array(data['x'])), np.array(data['y'])) means, vars = regressor.predictive_params(X_predict) # Point estimate x_fit, y_fit = inputs, means self.point_estimate.data_source.data = dict(x=x_fit, y=y_fit) # Uncertainty range x_range, y_range = [], [] x_range.extend(inputs) y_range.extend(means + vars) x_range.extend(reversed(inputs)) y_range.extend(reversed(means - vars)) self.uncertainty_range.data_source.data = dict(x=x_range, y=y_range) def render(self, doc): doc.add_root(self.container.drawable())
class InteractiveGaussianProcess(object): PLOT_POINTS = 150 def __init__(self): self.plot = SingleClassPlot() self.container = ParametricPlotContainer(self.plot) self.container.slider(value=0.5, start=0.1, end=5, step=0.1, title="Kernel Width") self.container.slider(value=1, start=0.1, end=5, step=0.1, title="Kernel Amplitude") self.container.slider(value=0.1, start=0.01, end=1, step=0.01, title="Prior Variance") self.point_estimate = self.plot.figure.line(x=[], y=[]) self.uncertainty_range = self.plot.figure.patch(x=[], y=[], fill_alpha=0.5) self.plot.add_change_listener(self.update_plot) self.plot.enable_interaction() def update_plot(self, plot_state): inputs = np.linspace(*X_RANGE, self.PLOT_POINTS) X_predict = inputs.reshape(-1, 1) data = plot_state['inputs'] X_train = np.array(data['x']).reshape(-1, 1) y_train = np.array(data['y']) regressor = GaussianProcessRegression(kernel=Kernels.GaussianKernel( plot_state['Kernel Amplitude'], np.array([plot_state['Kernel Width']])), s2y=plot_state['Prior Variance']) regressor.fit(X_train, y_train) mean, cov = regressor.predictive_params(X_predict) # Point estimate x_fit, y_fit = inputs, mean self.point_estimate.data_source.data = dict(x=x_fit, y=y_fit) # Uncertainty range x_range, y_range = [], [] x_range.extend(inputs) y_range.extend(mean + cov) x_range.extend(reversed(inputs)) y_range.extend(reversed(mean - cov)) self.uncertainty_range.data_source.data = dict(x=x_range, y=y_range) def render(self, doc): doc.add_root(self.container.drawable())
def __init__(self): self.plot = SingleClassPlot() self.container = ParametricPlotContainer(self.plot) self.container.slider(value=1, start=0, end=15, step=1, title="Polynomial Degree") self.container.slider(value=0, start=0, end=10, step=0.1, title="L2 Weight Penalty") self.fit_line = self.plot.figure.line(x=[], y=[]) self.plot.enable_interaction() self.plot.add_change_listener(self.update_plot)
class InteractivePolynomialRegression(object): PLOT_POINTS = 150 def __init__(self): self.plot = SingleClassPlot() self.container = ParametricPlotContainer(self.plot) self.container.slider(value=1, start=0, end=15, step=1, title="Polynomial Degree") self.container.slider(value=0, start=0, end=10, step=0.1, title="L2 Weight Penalty") self.fit_line = self.plot.figure.line(x=[], y=[]) self.plot.enable_interaction() self.plot.add_change_listener(self.update_plot) def update_plot(self, plot_state): data = plot_state['inputs'] X, y = np.array(data['x']), np.array(data['y']) regressor = LinearRegression( basis_function=ScalarBasisFunctions.Polynomial( plot_state['Polynomial Degree']), l2_cost=plot_state['L2 Weight Penalty']) regressor.fit(X, y) inputs = np.linspace(*X_RANGE, self.PLOT_POINTS) self.fit_line.data_source.data = dict(x=inputs, y=regressor.predict(inputs)) def render(self, doc): doc.add_root(self.container.drawable())
def __init__(self): self.plot = MultiClassPlot() self.main_container = ParametricPlotContainer(self.plot) self.plot.add_scatter("red", x=[], y=[], color="#FF0000") self.plot.add_scatter("blue", x=[], y=[], color="#0000FF") self.main_container.slider(title="Line x Position", value=sum(X_RANGE) / 2, start=X_RANGE[0], end=X_RANGE[1], step=0.1) self.main_container.slider(title="Line Angle", value=0, start=0, end=360, step=1) self.main_container.slider(title="Confidence Interval", value=1, start=0, end=20, step=0.1) COST_RANGE = (0, 20) self.explore_figures = { "Line x Position": figure(x_range=X_RANGE, y_range=COST_RANGE, tools="", toolbar_location=None), "Line Angle": figure(x_range=(0, 360), y_range=COST_RANGE, tools="", toolbar_location=None), "Confidence Interval": figure(x_range=(0, 20), y_range=COST_RANGE, tools="", toolbar_location=None) } self.explore_plots = { key: (fig.line(x=[], y=[]), fig.line(x=[], y=[])) for key, fig in self.explore_figures.items() } self.decision_boundary = self.plot.figure.line(x=[], y=[]) self.red_side = self.plot.figure.line(x=[], y=[], color="#FF0000", line_dash="dashed") self.blue_side = self.plot.figure.line(x=[], y=[], color="#0000FF", line_dash="dashed") self.cache = { "Line x Position": None, "Line Angle": None, "Confidence Interval": None } self.plot.enable_interaction() self.plot.add_change_listener(self.update_plot)
class LogisticRegressionCostPlot(object): EXPLORE_PLOT_KEYS = [ "Line x Position", "Line Angle", "Confidence Interval" ] PLOT_POINTS = 75 CONFIDENCE_INTERVAL = 0.95 ALPHA = -math.log(1 / CONFIDENCE_INTERVAL - 1, 2) basis = staticmethod(BasisFunctions.Affine()) def __init__(self): self.plot = MultiClassPlot() self.main_container = ParametricPlotContainer(self.plot) self.plot.add_scatter("red", x=[], y=[], color="#FF0000") self.plot.add_scatter("blue", x=[], y=[], color="#0000FF") self.main_container.slider(title="Line x Position", value=sum(X_RANGE) / 2, start=X_RANGE[0], end=X_RANGE[1], step=0.1) self.main_container.slider(title="Line Angle", value=0, start=0, end=360, step=1) self.main_container.slider(title="Confidence Interval", value=1, start=0, end=20, step=0.1) COST_RANGE = (0, 20) self.explore_figures = { "Line x Position": figure(x_range=X_RANGE, y_range=COST_RANGE, tools="", toolbar_location=None), "Line Angle": figure(x_range=(0, 360), y_range=COST_RANGE, tools="", toolbar_location=None), "Confidence Interval": figure(x_range=(0, 20), y_range=COST_RANGE, tools="", toolbar_location=None) } self.explore_plots = { key: (fig.line(x=[], y=[]), fig.line(x=[], y=[])) for key, fig in self.explore_figures.items() } self.decision_boundary = self.plot.figure.line(x=[], y=[]) self.red_side = self.plot.figure.line(x=[], y=[], color="#FF0000", line_dash="dashed") self.blue_side = self.plot.figure.line(x=[], y=[], color="#0000FF", line_dash="dashed") self.cache = { "Line x Position": None, "Line Angle": None, "Confidence Interval": None } self.plot.enable_interaction() self.plot.add_change_listener(self.update_plot) def deg_to_rad(self, x): return np.pi * x / 180 def explore_weights_over_range(self, x_range, inputs): out = np.ndarray((len(inputs), x_range.shape[0])) w1 = out[1, :] = np.array(self.ALPHA / inputs["Confidence Interval"]) out[0, :] = np.array(-w1 * inputs["Line x Position"]) out[2, :] = np.array(-w1 / np.sin(self.deg_to_rad(inputs["Line Angle"]))) return out def cost(self, X, y, W): affine = X.dot(W) z = 2 * y - 1 return -np.sum(np.log(1 / (1 + np.exp(z * affine))), axis=0) def update_explore_plot(self, key, plot_state): X, y = plot_state_to_model_data(plot_state) X = self.basis(X) inputs = { const: plot_state[const] for const in self.EXPLORE_PLOT_KEYS if const != key } plot = self.explore_plots[key][0] x_range = self.explore_figures[key].x_range x_plot = np.linspace(x_range.start, x_range.end, self.PLOT_POINTS) inputs[key] = x_plot W = self.explore_weights_over_range(x_plot, inputs) y_plot = self.cost(X, y, W) plot.data_source.data = dict(x=x_plot, y=y_plot) def update_plot(self, plot_state): for key in self.EXPLORE_PLOT_KEYS: self.explore_plots[key][1].data_source.data = dict( x=[plot_state[key], plot_state[key]], y=[*Y_RANGE]) if self.cache[key] == plot_state[key]: self.update_explore_plot(key, plot_state) self.cache = {key: plot_state[key] for key in self.EXPLORE_PLOT_KEYS} # w2 = math.sqrt(self.ALPHA / (plot_state["Confidence Interval"] * (1 + math.tan(theta)))) x0 = plot_state["Line x Position"] decision_origin = np.array([x0, 0]) theta = self.deg_to_rad(plot_state["Line Angle"]) offset = np.array([-math.sin(theta), math.cos(theta) ]) * plot_state["Confidence Interval"] for plot, origin in [(self.blue_side, decision_origin - offset), (self.decision_boundary, decision_origin), (self.red_side, decision_origin + offset)]: x, y = calculate_line_endpoints(plot_state["Line Angle"], origin) plot.data_source.data = dict(x=x, y=y) def render(self, doc): doc.add_root( column(self.main_container.drawable(), *self.explore_figures.values()))