Changes in [10810:32d236796d98:10811:d1129738f2ef] in orange
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

Orange/OrangeWidgets/Prototypes/OWPCA.py
r10801 r10809 48 48 x, _ = self.map_from_graph(pos) 49 49 xmin, xmax = self.x_scale() 50 if x >= xmin and x <= xmax: 50 if x >= xmin  0.1 and x <= xmax + 0.1: 51 x = min(max(x, xmin), xmax) 51 52 self.cutoff_curve.set_data([x, x], [0.0, 1.0]) 52 53 self.emit_cutoff_moved(x) … … 58 59 x, _ = self.map_from_graph(pos) 59 60 xmin, xmax = self.x_scale() 60 if x >= xmin and x <= xmax: 61 if x >= xmin  0.5 and x <= xmax + 0.5: 62 x = min(max(x, xmin), xmax) 61 63 self.cutoff_curve.set_data([x, x], [0.0, 1.0]) 62 64 self.emit_cutoff_moved(x) … … 69 71 ax = self.axes[owaxis.xBottom] 70 72 if ax.labels: 71 return 0, len(ax.labels)  0.573 return 0, len(ax.labels)  1 72 74 elif ax.scale: 73 return ax.scale[0], ax.scale[1] + 0.575 return ax.scale[0], ax.scale[1] 74 76 else: 75 77 raise ValueError … … 90 92 class OWPCA(OWWidget): 91 93 settingsList = ["standardize", "max_components", "variance_covered", 92 "use_generalized_eigenvectors" ]94 "use_generalized_eigenvectors", "auto_commit"] 93 95 def __init__(self, parent=None, signalManager=None, title="PCA"): 94 OWWidget.__init__(self, parent, signalManager, title )96 OWWidget.__init__(self, parent, signalManager, title, wantGraph=True) 95 97 96 98 self.inputs = [("Input Data", Orange.data.Table, self.set_data)] … … 102 104 self.variance_covered = 100.0 103 105 self.use_generalized_eigenvectors = False 106 self.auto_commit = False 104 107 105 108 self.loadSettings() 106 109 107 110 self.data = None 111 self.changed_flag = False 108 112 109 113 ##### … … 111 115 ##### 112 116 grid = QGridLayout() 113 box = OWGUI.widgetBox(self.controlArea, " Settings",117 box = OWGUI.widgetBox(self.controlArea, "Components Selection", 114 118 orientation=grid) 115 119 … … 140 144 141 145 OWGUI.rubber(self.controlArea) 146 147 box = OWGUI.widgetBox(self.controlArea, "Commit") 148 cb = OWGUI.checkBox(box, self, "auto_commit", "Commit on any change") 149 b = OWGUI.button(box, self, "Commit", 150 callback=self.update_components) 151 OWGUI.setStopper(self, b, cb, "changed_flag", self.update_components) 142 152 143 153 self.scree_plot = ScreePlot(self) … … 180 190 self.on_cutoff_moved 181 191 ) 192 193 self.connect(self.graphButton, 194 SIGNAL("clicked()"), 195 self.scree_plot.save_to_file) 196 182 197 self.components = None 183 198 self.variances = None 184 199 self.variances_sum = None 185 200 self.projector_full = None 201 self.currently_selected = 0 186 202 187 203 self.resize(800, 400) … … 203 219 self.variances_cumsum = None 204 220 self.projector_full = None 221 self.currently_selected = 0 205 222 206 223 def set_data(self, data=None): … … 211 228 self.data = data 212 229 self.on_change() 230 else: 231 self.send("Transformed Data", None) 232 self.send("Eigen Vectors", None) 213 233 214 234 def on_change(self): 235 """Data has changed and we need to recompute the projection. 236 """ 215 237 if self.data is None: 216 238 return … … 219 241 220 242 def on_update(self): 243 """Component selection was changed by the user. 244 """ 221 245 if self.data is None: 222 246 return 223 247 self.update_cutoff_curve() 224 self.update_components() 248 if self.currently_selected != self.number_of_selected_components(): 249 self.update_components_if() 225 250 226 251 def construct_pca_all_comp(self): … … 243 268 244 269 def apply(self): 245 """Apply PCA in input data, caching the full projection,270 """Apply PCA on input data, caching the full projection, 246 271 then updating the selected components. 247 272 … … 256 281 self.max_components_spin.setRange(1, len(self.variances)) 257 282 self.update_scree_plot() 258 self.update_components() 259 283 self.update_cutoff_curve() 284 self.update_components_if() 285 286 def update_components_if(self): 287 if self.auto_commit: 288 self.update_components() 289 else: 290 self.changed_flag = True 291 260 292 def update_components(self): 293 """Update the output components. 294 """ 295 if self.data is None: 296 return 297 261 298 scale = self.projector_full.scale 262 299 center = self.projector_full.center … … 281 318 eigenvectors = self.eigenvectors_as_table(components) 282 319 320 self.currently_selected = self.number_of_selected_components() 321 283 322 self.send("Transformed Data", projected_data) 284 323 self.send("Eigen Vectors", eigenvectors) 324 325 self.changed_flag = False 285 326 286 327 def eigenvectors_as_table(self, U): … … 291 332 292 333 def update_scree_plot(self): 293 variances = self.projector_full.variances 294 s = np.sum(variances) 295 cv = variances / s 296 cs = np.cumsum(cv) 297 x_space = np.arange(0, len(variances)) 334 x_space = np.arange(0, len(self.variances)) 298 335 self.scree_plot.set_axis_enabled(owaxis.xBottom, True) 299 336 self.scree_plot.set_axis_enabled(owaxis.yLeft, True) … … 301 338 ["PC" + str(i + 1) for i in x_space]) 302 339 303 self.variance_curve.set_data(x_space, cv)304 self.cumulative_variance_curve.set_data(x_space, cs)340 self.variance_curve.set_data(x_space, self.variances) 341 self.cumulative_variance_curve.set_data(x_space, self.variances_cumsum) 305 342 self.variance_curve.setVisible(True) 306 343 self.cumulative_variance_curve.setVisible(True) 307 344 308 345 self.scree_plot.set_cutoff_curve_enabled(True) 346 self.scree_plot.replot() 309 347 310 348 def on_cutoff_moved(self, value): 349 """Cutoff curve was moved by the user. 350 """ 311 351 components = int(np.floor(value)) + 1 312 if components != self.max_components: 313 self.max_components = int(np.floor(value)) + 1 314 self.variance_covered = self.variances_cumsum[self.max_components  1] * 100 315 self.update_components() 352 # Did the number of components actually change 353 self.max_components = components 354 self.variance_covered = self.variances_cumsum[components  1] * 100 355 if self.currently_selected != self.number_of_selected_components(): 356 self.update_components_if() 316 357 317 358 def update_cutoff_curve(self): 318 """Update cutoff line from gui control elements.359 """Update cutoff curve from 'Components Selection' control box. 319 360 """ 320 361 variance = self.variances_cumsum[self.max_components  1] * 100.0 … … 326 367 self.scree_plot.set_cutoff_value(cutoff + 0.5) 327 368 369 def number_of_selected_components(self): 370 """How many components are selected. 371 """ 372 if self.data is None: 373 return 0 374 375 variance_components = np.searchsorted(self.variances_cumsum, 376 self.variance_covered / 100.0) 377 return min(variance_components + 1, self.max_components) 378 379 def sendReport(self): 380 self.reportSettings("PCA Settings", 381 [("Max. components", self.max_components), 382 ("Variance covered", "%i%%" % self.variance_covered), 383 ]) 384 if self.data is not None and self.projector_full: 385 output_domain = self.projector_full.output_domain 386 st_dev = np.sqrt(self.projector_full.variances) 387 summary = [[""] + [a.name for a in output_domain.attributes], 388 ["Std. deviation"] + ["%.3f" % sd for sd in st_dev], 389 ["Proportion Var"] + ["%.3f" % v for v in self.variances * 100.0], 390 ["Cumulative Var"] + ["%.3f" % v for v in self.variances_cumsum * 100.0] 391 ] 392 393 th = "<th>%s</th>".__mod__ 394 header = "".join(map(th, summary[0])) 395 td = "<td>%s</td>".__mod__ 396 summary = ["".join(map(td, row)) for row in summary[1:]] 397 tr = "<tr>%s</tr>".__mod__ 398 summary = "\n".join(map(tr, [header] + summary)) 399 summary = "<table>\n%s\n</table>" % summary 400 401 self.reportSection("Summary") 402 self.reportRaw(summary) 403 404 self.reportSection("Scree Plot") 405 self.reportImage(self.scree_plot.save_to_file_direct) 328 406 329 407 if __name__ == "__main__":
Note: See TracChangeset
for help on using the changeset viewer.