Skip to content

Commit

Permalink
Add chart back
Browse files Browse the repository at this point in the history
commit 1f29d66ed5998b603784fefd6cee8cb63a186070
Author: Nathan Galt <[email protected]>
Date:   Sun Apr 21 18:38:13 2019 -0700

    Update Chart.min.js to 2.8.0

commit 8f2586ee9da7cfea7969f1f1fb46e63c45bdee05
Author: Nathan Galt <[email protected]>
Date:   Fri Apr 12 04:12:33 2019 -0700

    Almost works but doesn’t

commit d8d160da7a99e34a6c209447edab1f8d70409d33
Author: Nathan Galt <[email protected]>
Date:   Fri Apr 12 03:13:07 2019 -0700

    Programmatically update to dark

commit a5f47764263d3bdab0833fd2d5e0b5515306a0bf
Author: Nathan Galt <[email protected]>
Date:   Fri Apr 12 02:52:47 2019 -0700

    Semi-dynamic colors now

commit fafc7efaa028a0606b1c99184b5fa018503c454b
Author: Nathan Galt <[email protected]>
Date:   Fri Apr 12 02:25:29 2019 -0700

    Add elements.point.*Color…

commit 67935635c7490616c3cfb54189c5414808649735
Author: Nathan Galt <[email protected]>
Date:   Fri Apr 12 00:56:24 2019 -0700

    Get chart working perfectly enough in dark mode

commit cd1e3524cd710748a3b24d5355a8d13f7a8c8c25
Author: Nathan Galt <[email protected]>
Date:   Thu Apr 11 22:58:58 2019 -0700

    Has confidences, but way too many of them

commit 25e6ebcf73860114a5a3278739159f44af9d46ef
Author: Nathan Galt <[email protected]>
Date:   Thu Apr 11 22:29:45 2019 -0700

    analyze.go: Reorder structs

commit 922299deb1f4725bf42e7bea6021034bcd333599
Author: Nathan Galt <[email protected]>
Date:   Thu Apr 11 21:30:35 2019 -0700

    Add line of perfect calibration

commit fb448cf7be8c30b7270fe8a48aaf85dc3da96e24
Author: Nathan Galt <[email protected]>
Date:   Thu Apr 11 12:55:11 2019 -0700

    Use scatterplot, get all axes back
  • Loading branch information
adiabatic committed Apr 25, 2019
1 parent b47afa9 commit ab210cf
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 82 deletions.
13 changes: 5 additions & 8 deletions Chart.min.js
100755 → 100644

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ go get github.com/davecgh/go-spew/spew
go get github.com/stretchr/testify
go get -u github.com/spf13/cobra/cobra
go get -u gopkg.in/russross/blackfriday.v2
go get github.com/xtgo/set
```

## Prior art
Expand Down
39 changes: 33 additions & 6 deletions analyze/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ type Analysis struct {
EverythingByConfidence []AnalyzedDocuments
}

// An AnalyzedDocuments contains both an AnalysisUnit and a slice of PredictionDocument.
type AnalyzedDocuments struct {
AnalysisUnit AnalysisUnit
Documents []streams.PredictionDocument
}

// AnalysisUnit provides information on a subset of an Analysis.
type AnalysisUnit struct {
Title string
Expand All @@ -47,12 +53,6 @@ type AnalysisUnit struct {
Unscorable int // lacks claim, lacks confidence, or both
}

// An AnalyzedDocuments contains both an AnalysisUnit and a slice of PredictionDocument.
type AnalyzedDocuments struct {
AnalysisUnit AnalysisUnit
Documents []streams.PredictionDocument
}

// Total returns the sum of the scored items, the unscored items, and the unscorable items.
func (au *AnalysisUnit) Total() int { return au.Scored() + au.Unscored() + au.Unscorable }

Expand Down Expand Up @@ -135,6 +135,26 @@ func (au *AnalysisUnit) BrierScore() float64 {
return sum / float64(len(au.SquaredDifferences))
}

// Confidence returns the confidence level of an AnalyzedDocuments if they all have the same confidence level, or nil otherwise.
func (ads *AnalyzedDocuments) Confidence() *float64 {
const ε = 0.0001
var ret *float64
for _, d := range ads.Documents {
if d.Confidence != nil {
if ret == nil {
ret = d.Confidence
} else {
if math.Abs(*ret-*d.Confidence) > ε {
// preexisting saved value is too different from current value, so this bunch must be confidence-ly heterogenous
return nil
}
}

}
}
return ret
}

// Analyze calculates Brier scores for the given streams.
func Analyze(sts []streams.Stream) Analysis {
ret := Analysis{}
Expand All @@ -157,6 +177,13 @@ func Analyze(sts []streams.Stream) Analysis {
ret.EverythingByKey = append(ret.EverythingByKey, ds)
}

confidencesUsed := streams.ConfidencesUsed(sts)
for _, confidence := range confidencesUsed {
ds := Only(sts, streams.MatchingConfidence(confidence))
ds.AnalysisUnit.Title = fmt.Sprintf("At the %.0f%% confidence level", confidence)
ret.EverythingByConfidence = append(ret.EverythingByConfidence, ds)
}

return ret
}

Expand Down
56 changes: 55 additions & 1 deletion formatters/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"html/template"
"io"
"io/ioutil"
"os"
"strings"

"github.com/adiabatic/predictions/analyze"
Expand All @@ -33,7 +34,23 @@ type payload struct {
Streams []streams.Stream
Analysis analyze.Analysis

ChartJS template.JS
ChartJS template.JS
PerfectData []Point
GuessData []Point
}

// A Point struct contains an x and y point. Used for Chart.js.
type Point struct {
X float64 `json:"x"`
Y float64 `json:"y"`
}

// MarshalJSON suppresses excess precision in float64’s default marshaling behavior.
//
// Do you want to see tooltips for points on a chart that say (0.7000000000000001, 0.7000000000000001)? Me neither.
func (p Point) MarshalJSON() ([]byte, error) {
s := fmt.Sprintf(`{"x":%.2f, "y":%.2f}`, p.X, p.Y)
return []byte(s), nil
}

func documentResult(d streams.PredictionDocument) (class, message string) {
Expand Down Expand Up @@ -122,6 +139,9 @@ func HTMLFromStreams(w io.Writer, sts []streams.Stream) error {

p.Analysis = analyze.Analyze(sts)

addPerfectData(&p)
addGuessData(&p)

t := template.Must(template.New("template").Funcs(funcs).ParseFiles("template.html"))
return t.Execute(w, p)
}
Expand All @@ -148,3 +168,37 @@ func combineTitleAndScope(title, scope string) string {
}
return r
}

func addPerfectData(pp *payload) {
numbers := make([]float64, 0)

var num float64
for ; num <= 1.03; num += 0.05 {
numbers = append(numbers, num)
}
numbers[0] = 0.01 // 0 is a bad idea
numbers[len(numbers)-1] = 0.99 // 1 is a bad idea

for _, n := range numbers {
p := Point{n, n}
pp.PerfectData = append(pp.PerfectData, p)
}
}

func addGuessData(pp *payload) {
confidenceGroupings := pp.Analysis.EverythingByConfidence
for _, grouping := range confidenceGroupings {
conf := grouping.Confidence()
if conf == nil {
fmt.Fprintln(os.Stderr, "Odd. I didn’t expect a nil confidence in addGuessData().")
continue
}

p := Point{
*conf / 100,
grouping.AnalysisUnit.OfTotalCalled() / 100,
}

pp.GuessData = append(pp.GuessData, p)
}
}
14 changes: 14 additions & 0 deletions streams/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

package streams

import "math"

// A Filter removes predictions from consideration if the predicate returns false.
type Filter func(PredictionDocument) bool

Expand Down Expand Up @@ -46,6 +48,18 @@ func MatchingKey(key string) Filter {
}
}

// MatchingConfidence returns a Filter that returns true if the prediction’s confidence level matches (to within a fudge factor) the given confidence level.
func MatchingConfidence(conf float64) Filter {
const ε = 0.0001
return func(d PredictionDocument) bool {
if d.Confidence != nil && math.Abs(*d.Confidence-conf) < ε {
return true
}

return false
}
}

// DocumentsMatching returns PredictionDocuments from streams that pass the given Filter.
func DocumentsMatching(sts []Stream, f Filter) []PredictionDocument {
ret := make([]PredictionDocument, 0)
Expand Down
14 changes: 14 additions & 0 deletions streams/streams.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"os"

"github.com/pkg/errors"
"github.com/xtgo/set"
yaml "gopkg.in/yaml.v2"
)

Expand Down Expand Up @@ -323,3 +324,16 @@ func KeysUsed(sts []Stream) []string {
return deduplicateStrings(ret)

}

// ConfidencesUsed returns a list of all confidence intervals used in the given Streams.
func ConfidencesUsed(sts []Stream) []float64 {
ret := make([]float64, 0)
for _, s := range sts {
for _, pred := range s.Predictions {
if !pred.ShouldExclude() {
ret = append(ret, *pred.Confidence)
}
}
}
return set.Float64s(ret)
}
Loading

0 comments on commit ab210cf

Please sign in to comment.