Changeset 10362:539f49e3586d in orange
 Timestamp:
 02/24/12 13:12:28 (2 years ago)
 Branch:
 default
 rebase_source:
 b107b292c78ab9b716058336d460ba28782be01a
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

Orange/evaluation/scoring.py
r10343 r10362 1 import math, functools 1 import math 2 import functools 2 3 from operator import add 4 3 5 import numpy 4 6 … … 20 22 def log2(x): 21 23 """Calculate logarithm in base 2.""" 22 return math.log(x) /math.log(2)24 return math.log(x) / math.log(2) 23 25 24 26 def check_non_zero(x): 25 """Throw Value Error when x = 0. 0."""26 if x ==0.0:27 raise ValueError, "Cannot compute the score: no examples or sum of weights is 0. 0."27 """Throw Value Error when x = 0.""" 28 if x == 0.: 29 raise ValueError, "Cannot compute the score: no examples or sum of weights is 0." 28 30 29 31 def gettotweight(res): 30 32 """Sum all the weights""" 31 totweight = reduce(lambda x, y: x +y.weight, res.results, 0)32 if totweight ==0.0:33 raise ValueError, "Cannot compute the score: sum of weights is 0. 0."33 totweight = reduce(lambda x, y: x + y.weight, res.results, 0) 34 if totweight == 0.: 35 raise ValueError, "Cannot compute the score: sum of weights is 0." 34 36 return totweight 35 37 … … 68 70 weights=res.weights, baseClass=res.baseClass, 69 71 classifiers=[res.classifiers[i]] if res.classifiers else [], 70 test_type = res.test_type, labels =res.labels)72 test_type=res.test_type, labels=res.labels) 71 73 r.results = [] 72 74 for te in res.results: … … 81 83 def class_probabilities_from_res(res, **argkw): 82 84 """Calculate class probabilities""" 83 probs = [0. 0] * len(res.class_values)85 probs = [0.] * len(res.class_values) 84 86 if argkw.get("unweighted", 0) or not res.weights: 85 87 for tex in res.results: 86 probs[int(tex.actual_class)] += 1. 088 probs[int(tex.actual_class)] += 1. 87 89 totweight = gettotsize(res) 88 90 else: 89 totweight = 0. 091 totweight = 0. 90 92 for tex in res.results: 91 93 probs[tex.actual_class] += tex.weight … … 103 105 if iteration_is_outer: 104 106 if not stats: 105 raise ValueError, "Cannot compute the score: no examples or sum of weights is 0. 0."107 raise ValueError, "Cannot compute the score: no examples or sum of weights is 0." 106 108 number_of_learners = len(stats[0]) 107 stats = filter(lambda (x, fN): fN>0.0, zip(stats,fold_n)) 108 stats = [ [x[lrn]/fN for x, fN in stats] for lrn in range(number_of_learners)] 109 stats = filter(lambda (x, fN): fN > 0, zip(stats, fold_n)) 110 stats = [[x[lrn] / fN for x, fN in stats] 111 for lrn in range(number_of_learners)] 109 112 else: 110 stats = [ [x/Fn for x, Fn in filter(lambda (x, Fn): Fn > 0.0, zip(lrnD, fold_n))] for lrnD in stats] 113 stats = [[x / Fn for x, Fn in filter(lambda (x, Fn): Fn > 0, 114 zip(lrnD, fold_n))] for lrnD in stats] 111 115 112 116 if not stats: 113 117 raise ValueError, "Cannot compute the score: no classifiers" 114 118 if not stats[0]: 115 raise ValueError, "Cannot compute the score: no examples or sum of weights is 0. 0."119 raise ValueError, "Cannot compute the score: no examples or sum of weights is 0." 116 120 117 121 if report_se: … … 121 125 122 126 def ME(res, **argkw): 123 MEs = [0. 0]*res.number_of_learners127 MEs = [0.] * res.number_of_learners 124 128 125 129 if argkw.get("unweighted", 0) or not res.weights: … … 130 134 else: 131 135 for tex in res.results: 132 MEs = map(lambda res, cls, ac = float(tex.actual_class), tw =tex.weight:133 res + tw *abs(float(cls)  ac), MEs, tex.classes)136 MEs = map(lambda res, cls, ac=float(tex.actual_class), tw=tex.weight: 137 res + tw * abs(float(cls)  ac), MEs, tex.classes) 134 138 totweight = gettotweight(res) 135 139 136 return [x /totweight for x in MEs]140 return [x / totweight for x in MEs] 137 141 138 142 MAE = ME … … 154 158 @deprecated_keywords({"predictedPositive": "predicted_positive", 155 159 "isPositive": "is_positive"}) 156 def addTFPosNeg(self, predicted_positive, is_positive, weight =1.0):160 def addTFPosNeg(self, predicted_positive, is_positive, weight=1.0): 157 161 """ 158 162 Update confusion matrix with result of a single classification … … 181 185 def check_argkw(dct, lst): 182 186 """check_argkw(dct, lst) > returns true if any items have nonzero value in dct""" 183 return reduce(lambda x, y: x or y, [dct.get(k, 0) for k in lst])187 return reduce(lambda x, y: x or y, [dct.get(k, 0) for k in lst]) 184 188 185 189 def regression_error(res, **argkw): … … 187 191 if argkw.get("SE", 0) and res.number_of_iterations > 1: 188 192 # computes the scores for each iteration, then averages 189 scores = [[0.0] * res.number_of_iterations for _ in range(res.number_of_learners)] 190 norm=None 193 scores = [[0.] * res.number_of_iterations 194 for _ in range(res.number_of_learners)] 195 norm = None 191 196 if argkw.get("normabs", 0) or argkw.get("normsqr", 0): 192 norm = [0.0] * res.number_of_iterations 193 194 nIter = [0]*res.number_of_iterations # counts examples in each iteration 195 a = [0]*res.number_of_iterations # average class in each iteration 197 norm = [0.] * res.number_of_iterations 198 199 # counts examples in each iteration 200 nIter = [0] * res.number_of_iterations 201 # average class in each iteration 202 a = [0] * res.number_of_iterations 196 203 for tex in res.results: 197 204 nIter[tex.iteration_number] += 1 198 205 a[tex.iteration_number] += float(tex.actual_class) 199 a = [a[i] /nIter[i] for i in range(res.number_of_iterations)]206 a = [a[i] / nIter[i] for i in range(res.number_of_iterations)] 200 207 201 208 if argkw.get("unweighted", 0) or not res.weights: … … 217 224 else: 218 225 scores[i][tex.iteration_number] += (float(cls)  ai)**2 219 else: # unweighted <>0226 else: # unweighted != 0 220 227 raise NotImplementedError, "weighted error scores with SE not implemented yet" 221 228 222 229 if argkw.get("normabs") or argkw.get("normsqr"): 223 scores = [[x /n for x, n in zip(y, norm)] for y in scores]224 else: 225 scores = [[x /ni for x, ni in zip(y, nIter)] for y in scores]230 scores = [[x / n for x, n in zip(y, norm)] for y in scores] 231 else: 232 scores = [[x / ni for x, ni in zip(y, nIter)] for y in scores] 226 233 227 234 if argkw.get("R2"): … … 234 241 235 242 else: # single iteration (testing on a single test set) 236 scores = [0. 0] * res.number_of_learners237 norm = 0. 0243 scores = [0.] * res.number_of_learners 244 norm = 0. 238 245 239 246 if argkw.get("unweighted", 0) or not res.weights: … … 242 249 for tex in res.results: 243 250 if argkw.get("abs", 0): 244 scores = map(lambda res, cls, ac =float(tex.actual_class):251 scores = map(lambda res, cls, ac=float(tex.actual_class): 245 252 res + abs(float(cls)  ac), scores, tex.classes) 246 253 else: 247 scores = map(lambda res, cls, ac =float(tex.actual_class):254 scores = map(lambda res, cls, ac=float(tex.actual_class): 248 255 res + (float(cls)  ac)**2, scores, tex.classes) 249 256 … … 255 262 else: 256 263 # UNFINISHED 257 MSEs = [0.] *res.number_of_learners264 MSEs = [0.] * res.number_of_learners 258 265 for tex in res.results: 259 MSEs = map(lambda res, cls, ac =float(tex.actual_class),260 tw =tex.weight:266 MSEs = map(lambda res, cls, ac=float(tex.actual_class), 267 tw=tex.weight: 261 268 res + tw * (float(cls)  ac)**2, MSEs, tex.classes) 262 269 totweight = gettotweight(res) 263 270 264 271 if argkw.get("normabs", 0) or argkw.get("normsqr", 0): 265 scores = [s /norm for s in scores]272 scores = [s / norm for s in scores] 266 273 else: # normalize by number of instances (or sum of weights) 267 scores = [s /totweight for s in scores]274 scores = [s / totweight for s in scores] 268 275 269 276 if argkw.get("R2"): 270 scores = [1. 0 s for s in scores]277 scores = [1.  s for s in scores] 271 278 272 279 if argkw.get("sqrt", 0): … … 315 322 """MSE(res) > meansquared error""" 316 323 if argkw.get("SE", 0) and res.number_of_iterations > 1: 317 MSEs = [[0.0] * res.number_of_iterations for _ in range(res.number_of_learners)] 318 nIter = [0]*res.number_of_iterations 324 MSEs = [[0.] * res.number_of_iterations 325 for _ in range(res.number_of_learners)] 326 nIter = [0] * res.number_of_iterations 319 327 if argkw.get("unweighted", 0) or not res.weights: 320 328 for tex in res.results: … … 325 333 else: 326 334 raise ValueError, "weighted RMSE with SE not implemented yet" 327 MSEs = [[x /ni for x, ni in zip(y, nIter)] for y in MSEs]335 MSEs = [[x / ni for x, ni in zip(y, nIter)] for y in MSEs] 328 336 if argkw.get("sqrt", 0): 329 337 MSEs = [[math.sqrt(x) for x in y] for y in MSEs] … … 331 339 332 340 else: 333 MSEs = [0. 0]*res.number_of_learners341 MSEs = [0.] * res.number_of_learners 334 342 if argkw.get("unweighted", 0) or not res.weights: 335 343 for tex in res.results: 336 MSEs = map(lambda res, cls, ac =float(tex.actual_class):344 MSEs = map(lambda res, cls, ac=float(tex.actual_class): 337 345 res + (float(cls)  ac)**2, MSEs, tex.classes) 338 346 totweight = gettotsize(res) 339 347 else: 340 348 for tex in res.results: 341 MSEs = map(lambda res, cls, ac = float(tex.actual_class), tw = tex.weight: 342 res + tw * (float(cls)  ac)**2, MSEs, tex.classes) 349 MSEs = map(lambda res, cls, ac=float(tex.actual_class), 350 tw=tex.weight: res + tw * (float(cls)  ac)**2, 351 MSEs, tex.classes) 343 352 totweight = gettotweight(res) 344 353 345 354 if argkw.get("sqrt", 0): 346 355 MSEs = [math.sqrt(x) for x in MSEs] 347 return [x /totweight for x in MSEs]356 return [x / totweight for x in MSEs] 348 357 349 358 def RMSE_old(res, **argkw): … … 384 393 input_type = self.get_input_type(test_results) 385 394 if input_type == self.CONFUSION_MATRIX: 386 self[:] = 395 self[:] = [self.from_confusion_matrix(test_results)] 387 396 elif input_type == self.CONFUSION_MATRIX_LIST: 388 397 self[:] = self.from_confusion_matrix_list(test_results) … … 390 399 self[:] = self.from_classification_results(test_results) 391 400 elif input_type == self.CROSS_VALIDATION: 392 self[:] = 401 self[:] = self.from_crossvalidation_results(test_results) 393 402 394 403 def from_confusion_matrix(self, cm): … … 396 405 correct_predictions = 0. 397 406 if isinstance(cm, ConfusionMatrix): 398 all_predictions += cm.TP +cm.FN+cm.FP+cm.TN399 correct_predictions += cm.TP +cm.TN407 all_predictions += cm.TP + cm.FN + cm.FP + cm.TN 408 correct_predictions += cm.TP + cm.TN 400 409 else: 401 410 for r, row in enumerate(cm): … … 406 415 407 416 check_non_zero(all_predictions) 408 ca = correct_predictions /all_predictions417 ca = correct_predictions / all_predictions 409 418 410 419 if self.report_se: 411 return ca, ca *(1ca)/math.sqrt(all_predictions)420 return ca, ca * (1  ca) / math.sqrt(all_predictions) 412 421 else: 413 422 return ca … … 417 426 418 427 def from_classification_results(self, test_results): 419 CAs = [0. 0]*test_results.number_of_learners428 CAs = [0.] * test_results.number_of_learners 420 429 totweight = 0. 421 430 for tex in test_results.results: 422 431 w = 1. if self.ignore_weights else tex.weight 423 CAs = map(lambda res, cls: res+(cls==tex.actual_class and w), CAs, tex.classes) 432 CAs = map(lambda res, cls: res + (cls == tex.actual_class and w), 433 CAs, tex.classes) 424 434 totweight += w 425 435 check_non_zero(totweight) 426 ca = [x /totweight for x in CAs]436 ca = [x / totweight for x in CAs] 427 437 428 438 if self.report_se: 429 return [(x, x *(1x)/math.sqrt(totweight)) for x in ca]439 return [(x, x * (1  x) / math.sqrt(totweight)) for x in ca] 430 440 else: 431 441 return ca 432 442 433 443 def from_crossvalidation_results(self, test_results): 434 CAsByFold = [[0.0]*test_results.number_of_iterations for _ in range(test_results.number_of_learners)] 435 foldN = [0.0]*test_results.number_of_iterations 444 CAsByFold = [[0.] * test_results.number_of_iterations 445 for _ in range(test_results.number_of_learners)] 446 foldN = [0.] * test_results.number_of_iterations 436 447 437 448 for tex in test_results.results: 438 449 w = 1. if self.ignore_weights else tex.weight 439 450 for lrn in range(test_results.number_of_learners): 440 CAsByFold[lrn][tex.iteration_number] += (tex.classes[lrn]==tex.actual_class) and w 451 CAsByFold[lrn][tex.iteration_number] += (tex.classes[lrn] == 452 tex.actual_class) and w 441 453 foldN[tex.iteration_number] += w 442 454 … … 457 469 @deprecated_keywords({"reportSE": "report_se", 458 470 "unweighted": "ignore_weights"}) 459 def AP(res, report_se =False, ignore_weights=False, **argkw):471 def AP(res, report_se=False, ignore_weights=False, **argkw): 460 472 """ Computes the average probability assigned to the correct class. """ 461 473 if res.number_of_iterations == 1: 462 APs=[0. 0]*res.number_of_learners474 APs=[0.] * res.number_of_learners 463 475 if ignore_weights or not res.weights: 464 476 for tex in res.results: 465 APs = map(lambda res, probs: res + probs[tex.actual_class], APs, tex.probabilities) 477 APs = map(lambda res, probs: res + probs[tex.actual_class], 478 APs, tex.probabilities) 466 479 totweight = gettotsize(res) 467 480 else: 468 481 totweight = 0. 469 482 for tex in res.results: 470 APs = map(lambda res, probs: res + probs[tex.actual_class]*tex.weight, APs, tex.probabilities) 483 APs = map(lambda res, probs: res + probs[tex.actual_class] * 484 tex.weight, APs, tex.probabilities) 471 485 totweight += tex.weight 472 486 check_non_zero(totweight) 473 return [AP/totweight for AP in APs] 474 475 APsByFold = [[0.0]*res.number_of_learners for _ in range(res.number_of_iterations)] 476 foldN = [0.0] * res.number_of_iterations 487 return [AP / totweight for AP in APs] 488 489 APsByFold = [[0.] * res.number_of_learners 490 for _ in range(res.number_of_iterations)] 491 foldN = [0.] * res.number_of_iterations 477 492 if ignore_weights or not res.weights: 478 493 for tex in res.results: 479 APsByFold[tex.iteration_number] = map(lambda res, probs: res + probs[tex.actual_class], APsByFold[tex.iteration_number], tex.probabilities) 494 APsByFold[tex.iteration_number] = map(lambda res, probs: 495 res + probs[tex.actual_class], 496 APsByFold[tex.iteration_number], tex.probabilities) 480 497 foldN[tex.iteration_number] += 1 481 498 else: 482 499 for tex in res.results: 483 APsByFold[tex.iteration_number] = map(lambda res, probs: res + probs[tex.actual_class] * tex.weight, APsByFold[tex.iteration_number], tex.probabilities) 500 APsByFold[tex.iteration_number] = map(lambda res, probs: 501 res + probs[tex.actual_class] * tex.weight, 502 APsByFold[tex.iteration_number], tex.probabilities) 484 503 foldN[tex.iteration_number] += tex.weight 485 504 … … 489 508 @deprecated_keywords({"reportSE": "report_se", 490 509 "unweighted": "ignore_weights"}) 491 def Brier_score(res, report_se =False, ignore_weights=False, **argkw):510 def Brier_score(res, report_se=False, ignore_weights=False, **argkw): 492 511 """ Computes the Brier's score, defined as the average (over test examples) 493 512 of sumx(t(x)p(x))2, where x is a class, t(x) is 1 for the correct class … … 506 525 507 526 if res.number_of_iterations == 1: 508 MSEs=[0. 0]*res.number_of_learners527 MSEs=[0.] * res.number_of_learners 509 528 if ignore_weights or not res.weights: 510 totweight = 0. 0529 totweight = 0. 511 530 for tex in res.results: 512 MSEs = map(lambda res, probs: 513 res + reduce(lambda s, pi: s+pi**2, probs, 0)  2*probs[tex.actual_class], MSEs, tex.probabilities) 531 MSEs = map(lambda res, probs: res + reduce( 532 lambda s, pi: s + pi**2, probs, 0)  533 2 * probs[tex.actual_class], MSEs, tex.probabilities) 514 534 totweight += tex.weight 515 535 else: 516 536 for tex in res.results: 517 MSEs = map(lambda res, probs: 518 res + tex.weight*reduce(lambda s, pi: s+pi**2, probs, 0)  2*probs[tex.actual_class], MSEs, tex.probabilities) 537 MSEs = map(lambda res, probs: res + tex.weight * reduce( 538 lambda s, pi: s + pi**2, probs, 0)  539 2 * probs[tex.actual_class], MSEs, tex.probabilities) 519 540 totweight = gettotweight(res) 520 541 check_non_zero(totweight) 521 542 if report_se: 522 return [(max(x/totweight+1.0, 0), 0) for x in MSEs] ## change this, not zero!!! 523 else: 524 return [max(x/totweight+1.0, 0) for x in MSEs] 525 526 BSs = [[0.0]*res.number_of_learners for _ in range(res.number_of_iterations)] 543 ## change this, not zero!!! 544 return [(max(x / totweight + 1., 0), 0) for x in MSEs] 545 else: 546 return [max(x / totweight + 1., 0) for x in MSEs] 547 548 BSs = [[0.] * res.number_of_learners 549 for _ in range(res.number_of_iterations)] 527 550 foldN = [0.] * res.number_of_iterations 528 551 529 552 if ignore_weights or not res.weights: 530 553 for tex in res.results: 531 BSs[tex.iteration_number] = map(lambda rr, probs: 532 rr + reduce(lambda s, pi: s+pi**2, probs, 0)  2*probs[tex.actual_class], BSs[tex.iteration_number], tex.probabilities) 554 BSs[tex.iteration_number] = map(lambda rr, probs: rr + reduce( 555 lambda s, pi: s + pi**2, probs, 0)  556 2 * probs[tex.actual_class], BSs[tex.iteration_number], 557 tex.probabilities) 533 558 foldN[tex.iteration_number] += 1 534 559 else: 535 560 for tex in res.results: 536 561 BSs[tex.iteration_number] = map(lambda res, probs: 537 res + tex.weight*reduce(lambda s, pi: s+pi**2, probs, 0)  2*probs[tex.actual_class], BSs[tex.iteration_number], tex.probabilities) 562 res + tex.weight * reduce(lambda s, pi: s + pi**2, probs, 0)  563 2 * probs[tex. actual_class], BSs[tex.iteration_number], 564 tex.probabilities) 538 565 foldN[tex.iteration_number] += tex.weight 539 566 540 567 stats = statistics_by_folds(BSs, foldN, report_se, True) 541 568 if report_se: 542 return [(x +1.0, y) for x, y in stats]569 return [(x + 1., y) for x, y in stats] 543 570 else: 544 return [x +1.0for x in stats]571 return [x + 1. for x in stats] 545 572 546 573 def BSS(res, **argkw): 547 return [1 x/2 for x in apply(Brier_score, (res, ), argkw)]574 return [1  x / 2 for x in apply(Brier_score, (res, ), argkw)] 548 575 549 576 def IS_ex(Pc, P): 550 577 """Pc aposterior probability, P aprior""" 551 if Pc >=P:552 return log2(P) +log2(Pc)578 if Pc >= P: 579 return log2(P) + log2(Pc) 553 580 else: 554 return (log2(1 P)+log2(1Pc))581 return (log2(1  P) + log2(1  Pc)) 555 582 556 583 557 584 @deprecated_keywords({"reportSE": "report_se"}) 558 def IS(res, apriori=None, report_se =False, **argkw):585 def IS(res, apriori=None, report_se=False, **argkw): 559 586 """ Computes the information score as defined by 560 587 `Kononenko and Bratko (1991) \ … … 567 594 apriori = class_probabilities_from_res(res) 568 595 569 if res.number_of_iterations ==1:570 ISs = [0. 0]*res.number_of_learners596 if res.number_of_iterations == 1: 597 ISs = [0.] * res.number_of_learners 571 598 if argkw.get("unweighted", 0) or not res.weights: 572 599 for tex in res.results: … … 579 606 for i in range(len(tex.probabilities)): 580 607 cls = tex.actual_class 581 ISs[i] += IS_ex(tex.probabilities[i][cls], apriori[cls]) * tex.weight 608 ISs[i] += (IS_ex(tex.probabilities[i][cls], apriori[cls]) * 609 tex.weight) 582 610 totweight = gettotweight(res) 583 611 if report_se: 584 return [(IS /totweight,0) for IS in ISs]585 else: 586 return [IS /totweight for IS in ISs]612 return [(IS / totweight, 0) for IS in ISs] 613 else: 614 return [IS / totweight for IS in ISs] 587 615 588 616 589 ISs = [[0.0]*res.number_of_iterations for _ in range(res.number_of_learners)] 617 ISs = [[0.] * res.number_of_iterations 618 for _ in range(res.number_of_learners)] 590 619 foldN = [0.] * res.number_of_iterations 591 620 … … 595 624 for i in range(len(tex.probabilities)): 596 625 cls = tex.actual_class 597 ISs[i][tex.iteration_number] += IS_ex(tex.probabilities[i][cls], apriori[cls]) 626 ISs[i][tex.iteration_number] += IS_ex(tex.probabilities[i][cls], 627 apriori[cls]) 598 628 foldN[tex.iteration_number] += 1 599 629 else: … … 601 631 for i in range(len(tex.probabilities)): 602 632 cls = tex.actual_class 603 ISs[i][tex.iteration_number] += IS_ex(tex.probabilities[i][cls], apriori[cls]) * tex.weight 633 ISs[i][tex.iteration_number] += IS_ex(tex.probabilities[i][cls], 634 apriori[cls]) * tex.weight 604 635 foldN[tex.iteration_number] += tex.weight 605 636 … … 622 653 623 654 k = len(res.results[0].classes) 624 if k <2:655 if k < 2: 625 656 raise TypeError, "nothing to compare (less than two classifiers given)" 626 if k ==2:657 if k == 2: 627 658 return apply(Wilcoxon, (res, statistics), argkw) 628 659 else: … … 648 679 tfpns = [ConfusionMatrix() for _ in range(test_results.number_of_learners)] 649 680 650 if class_index <0:681 if class_index < 0: 651 682 numberOfClasses = len(test_results.class_values) 652 683 if class_index < 1 or numberOfClasses > 2: 653 cm = [[[0.0] * numberOfClasses for _ in range(numberOfClasses)] for _ in range(test_results.number_of_learners)] 684 cm = [[[0.] * numberOfClasses for _ in range(numberOfClasses)] 685 for _ in range(test_results.number_of_learners)] 654 686 if ignore_weights or not test_results.weights: 655 687 for tex in test_results.results: … … 668 700 return cm 669 701 670 elif test_results.baseClass >=0:702 elif test_results.baseClass >= 0: 671 703 class_index = test_results.baseClass 672 704 else: … … 678 710 isPositive=(lr.actual_class==class_index) 679 711 for i in range(test_results.number_of_learners): 680 tfpns[i].addTFPosNeg(lr.probabilities[i][class_index]>cutoff, isPositive) 712 tfpns[i].addTFPosNeg(lr.probabilities[i][class_index] > 713 cutoff, isPositive) 681 714 else: 682 715 for lr in test_results.results: 683 isPositive=(lr.actual_class ==class_index)716 isPositive=(lr.actual_class == class_index) 684 717 for i in range(test_results.number_of_learners): 685 tfpns[i].addTFPosNeg(lr.probabilities[i][class_index]>cutoff, isPositive, lr.weight) 718 tfpns[i].addTFPosNeg(lr.probabilities[i][class_index] > 719 cutoff, isPositive, lr.weight) 686 720 else: 687 721 if ignore_weights or not test_results.weights: 688 722 for lr in test_results.results: 689 isPositive =(lr.actual_class==class_index)723 isPositive = (lr.actual_class == class_index) 690 724 for i in range(test_results.number_of_learners): 691 tfpns[i].addTFPosNeg(lr.classes[i]==class_index, isPositive) 725 tfpns[i].addTFPosNeg(lr.classes[i] == class_index, 726 isPositive) 692 727 else: 693 728 for lr in test_results.results: 694 isPositive =(lr.actual_class==class_index)729 isPositive = (lr.actual_class == class_index) 695 730 for i in range(test_results.number_of_learners): 696 tfpns[i].addTFPosNeg(lr.classes[i]==class_index, isPositive, lr.weight) 731 tfpns[i].addTFPosNeg(lr.classes[i] == class_index, 732 isPositive, lr.weight) 697 733 return tfpns 698 734 … … 722 758 colPriors = [sum(r[i] for r in confusion_matrix) for i in range(dim)] 723 759 total = sum(rowPriors) 724 rowPriors = [r /total for r in rowPriors]725 colPriors = [r /total for r in colPriors]760 rowPriors = [r / total for r in rowPriors] 761 colPriors = [r / total for r in colPriors] 726 762 ss = 0 727 763 for ri, row in enumerate(confusion_matrix): … … 730 766 if not e: 731 767 return 1, 1, 1 732 ss += (o e)**2 / e733 df = (dim 1)**2768 ss += (o  e)**2 / e 769 df = (dim  1)**2 734 770 return ss, df, statc.chisqprob(ss, df) 735 771 … … 749 785 return 1 750 786 751 return confusion_matrix.TP /tot787 return confusion_matrix.TP / tot 752 788 753 789 … … 775 811 warnings.warn("Can't compute specificity: one or both classes have no instances") 776 812 return 1 777 return confusion_matrix.TN /tot813 return confusion_matrix.TN / tot 778 814 779 815 … … 786 822 return [PPV(cm) for cm in confusion_matrix] 787 823 else: 788 tot = confusion_matrix.TP +confusion_matrix.FP824 tot = confusion_matrix.TP + confusion_matrix.FP 789 825 if tot < 1e6: 790 826 import warnings … … 811 847 return [NPV(cm) for cm in confusion_matrix] 812 848 else: 813 tot = confusion_matrix.FN +confusion_matrix.TN849 tot = confusion_matrix.FN + confusion_matrix.TN 814 850 if tot < 1e6: 815 851 import warnings 816 852 warnings.warn("Can't compute NPV: one or both classes have no instances") 817 853 return 1 818 return confusion_matrix.TN /tot854 return confusion_matrix.TN / tot 819 855 820 856 @deprecated_keywords({"confm": "confusion_matrix"}) … … 862 898 863 899 try: 864 r = (((truePositive * trueNegative)  (falsePositive * falseNegative))/865 math.sqrt( (truePositive + falsePositive) *866 ( truePositive + falseNegative ) *867 ( trueNegative + falsePositive) *868 ( trueNegative + falseNegative ) )869 )900 r = (((truePositive * trueNegative)  901 (falsePositive * falseNegative)) / 902 math.sqrt((truePositive + falsePositive) * 903 (truePositive + falseNegative) * 904 (trueNegative + falsePositive) * 905 (trueNegative + falseNegative))) 870 906 except ZeroDivisionError: 871 907 # Zero difision occurs when there is either no true positives … … 900 936 if b_is_list_of_matrices: 901 937 try: 902 return [scotts_pi(cm, b_is_list_of_matrices=False) for cm in confusion_matrix] 938 return [scotts_pi(cm, b_is_list_of_matrices=False) 939 for cm in confusion_matrix] 903 940 except TypeError: 904 941 # Nevermind the parameter, maybe this is a "conventional" binary
Note: See TracChangeset
for help on using the changeset viewer.