HNHacker News
TopNewBestAskShowJobs

mjw

597 karma · joined August 23, 2008

submissionscomments
mjw··on The main trick in machine learning
Good to see Bayesian model selection get a mention. Bayesian model averaging is pretty interesting, too, in that it comes, in a sense, with built-in protection against overfitting.

I still think there is something quite fundamental, though, about validation sets and other related resampling-based methods for estimating generalisation performance (cross-validation, bootstrap, jackknife and so on).

The built-in picture you get about predictive performance from Bayesian methods comes with strong caveats -- "IF you believe in your model and your priors over its parameters, THEN this is what you should expect". Adding extra layers of hyperparameters and doing model selection or averaging over them might sometimes make things less sensitive to your assumptions, but it doesn't make this problem go away; anything the method tells you is dependent on its strong assumptions about the generative mechanism.

Most sensible people don't believe their models are true ("all models are false, some models are useful"), and don't really fully trust a method, fancy Bayesian methods included, until they've seen how well it does on held-out data. So then it comes back to the fundamentals -- non-parametric methods for estimating generalisation performance which make as few assumptions as possible about the data and the model they're evaluating.

Cross-validation isn't the only one of these, and perhaps not the best, but it's certainly one of the simplest. One thing people do forget about it is that it does make at least one basic assumption about your data -- independence -- which is often not true and can be pretty disastrous if you're dealing with (e.g.) time-series data.

mjw··on Cheaper to rent in Barcelona and commute to London
Yes the London market is a bit nuts, but if you're paying anything close to 25k/year (that's 480/week!) for a 2 bed in a "not great" part of London then either you have very high standards or you're being seriously ripped off.

For example see what this gets you N1, a pretty central and desirable postcode: http://www.nestoria.co.uk/n1/property/rent/bedrooms-2/maxpri...

mjw··on D3 visualization of San Francisco BART employees' salaries and union membership
The coloured dots are cute and all, but if the goal is to make visually apparent the relationship between salary and union membership, some more traditional visualisations might have made this clearer. For example boxplots broken down by union.
mjw··on What's the Most Concave State in the U.S.? Using R to Solve a Geography Puzzle
For that suggestion I was just considering it a two-dimensional problem with a "sea or not sea" distinction, not using heights above sea level.
mjw··on What's the Most Concave State in the U.S.? Using R to Solve a Geography Puzzle
So with a few minor complications convexity generalises to Riemannian manifolds like the earth. You need to replace "straight line" with "minimising geodesic" i.e. shortest path, which don't depend on the choice of coordinate chart, just on the Riemannian manifold structure (which includes an inner product hence a metric).

This is complicated slightly when there isn't a unique shortest path between any given two points (e.g. the earth's north and south poles), leading to definitions of strongly convex, convex and weakly convex. See http://en.wikipedia.org/wiki/Geodesic_convexity and the debate at http://en.wikipedia.org/wiki/Talk:Geodesic_convexity#Dispute...

mjw··on What's the Most Concave State in the U.S.? Using R to Solve a Geography Puzzle
Maths challenge:

I wonder if you could prove this "probability of a random line segment violating convexity" definition equivalent to something given in terms of a ratio of different areas like the area to convex hull area suggestion below.

mjw··on What's the Most Concave State in the U.S.? Using R to Solve a Geography Puzzle
Yeah that was what I was expecting they'd do also.

Maybe you'd want to compute the convex hull on a per-connected-component basis, though, to avoid allowing small islands to have undue influence.

Either that, or say that any area of sea within its convex hull gets treated as part of the state's area. This approach differs in that it special-cases sea over other kinds of land.

mjw··on Probabilistic Scraping of Plain Text Tables
Entirely anecdotal.
mjw··on How To Deconstruct Almost Anything (1993)
An aside, but:

> A Novel Method for Applying a Trivial Modification of an Already-Known Algorithm to Some Type of Specific Data

Papers sharing empirical findings on applications of existing research can be very useful to those of us also, you know, looking to apply said research. Don't underestimate the amount of value (and legwork!) involved in figuring out how to adapt and apply theoretical work to real problems in some CS-related fields.

Obviously that kind of thing isn't accepted at the top conferences, so you know where not to look if you're not interested in it.

mjw··on Probabilistic Scraping of Plain Text Tables
On the subject of scraping data from OCR'd tables:

I heard from a colleague who moved into finance, that there's a mini arms race going on between some funds(?) who are subject to regulatory requirements to release financial performance metrics but for a variety of reasons would rather not (and certainly would rather not make the data machine readable), and other hedge funds who want to run automated trading strategies off said released figures.

They keep obfuscating the tables to make them harder and harder to parse algorithmically while still remaining theoretically human-readable.

Great fun no doubt for everyone involved.

mjw··on Kal – a clean JavaScript alternative without callbacks
Try http://www.neilmix.com/narrativejs/doc/ -- "a small extension to the JavaScript language that enables blocking capabilities for asynchronous event callbacks".
mjw··on Introducing HipHip (Array): Fast and flexible numerical computation in Clojure
Did you guys look at the core.matrix API?

https://github.com/mikera/matrix-api

mjw··on What Is the Most Surprising Result in Mathematics?
As a programming analogy: imagine mathematics is a big codebase and "prime" is a commonly-used function defined within that codebase.

You could refactor "prime" to allow 1, provided you refactor all the call sites to work with that new definition too. Consensus seems to be that this refactoring would add LOC and reduce code readability, probably leading to someone submitting a patch soon after with a "prime-but-not-one" function and using that everywhere.

mjw··on What Is the Most Surprising Result in Mathematics?
This isn't a surprising result though, it's a surprising (to you) definition.

You could redefine "prime" to include 1 if you wanted to without changing the fundamental truth of important results about the natural numbers. It would just mean you'd have to phrase many of them in a slightly more roundabout way, e.g. with "suppose x is a prime number not equal to 1" needing to appear in key theorems where before "suppose x is prime" sufficed. (Perhaps some other theorems might be more concise, although I'd be surprised if there were a net benefit -- the community has probably had this debate a bunch of times before settling on the current consensus.)

Definitions are chosen to be convenient for the purposes of communication, there's nothing inherently true or false about them. An argument for one definition being better than another might involve demonstrating that mathematical results people care about can be stated more clearly, concisely and efficiently using your alternative definition. The recent tau vs pi controversy providing an amusing example :)

mjw··on Clojure core.async and Go: A Code Comparison
Yep I figured this would probably not be very efficient.

About lazy sequences: sometimes you want to avoid the allocation of lots of intermediate cons cells when mapping/filtering/etc. The reducers framework for example manages to avoid this sort of cost when the data structure supports something faster than first/rest recursion. I'm interested in extending reducers to work nicely over large files and other sequences which don't fit in memory, and some kind of iterable or generator-like abstraction could play a useful role in this.

(Actual coroutine-based generators might not be necessary, but would allow for a neat outward-facing API)

mjw··on Clojure core.async and Go: A Code Comparison
Aha, thanks for the pointers, that helps. I suspected something simpler might be possible using these ioc macros but was frankly a bit scared off by them at first :)

It'd be nice if the coroutine/inversion-of-control stuff was given a stable public API at some point, because those macros seem very powerful and neat in themselves and might have other interesting uses aside from channels.

mjw··on Clojure core.async and Go: A Code Comparison
Oh for sure, more as an exercise in curiosity than anything else. (Although I am also playing with generator- and iterator-like abstractions as part of a resource-scoped foldable stream abstraction to help process big files.)

Looks like I managed to answer the 'is it possible?' part of the question anyway -- something like this:

    (defn range
      [n]
      (let [c (chan)]
        (go
         (loop [i 0]
           (>! c i)
           (if (< i n)
             (recur (inc i))
             (close! c))))
        (fn [] (<!! c))))
mjw··on Clojure core.async and Go: A Code Comparison
Quick question for anyone here familiar with core.async:

Would it be possible (and if so what would be the simplest way) to implement something like Python's generators and `yield` statement in Clojure using core.async? I'm thinking something like:

    (defn range [n]
      (generator
        (loop [i 0]
          (yield i)
          (when (< i n)
            (recur (inc i)))

    (let [generator (range 5)]
      (generator) ;; => 0
      (generator) ;; => 1
      ;; etc
      )
mjw··on Are coders worth it?
> One trap that people fall into is equating what people say they want with what they actually want - at least as expressed by what they are willing to pay for

Another trap people fall into is equating what people are willing to pay for something, with the amount of value that's actually able to be captured in the market for that item.

The finance industry, say, is able to capture a lot of the value they create (some might say more than they create). Some other industries, less so.

mjw··on Google Boss: We Follow The Law On Tax
Firstly, if google sees its only responsibilities as "maximize shareholder value" and "obey the letter of the law" then perhaps they should officially give up on the "don't be evil" thing.

Secondly, it's disingenuous of them to ask the taxpayer to "just change the rules" if we don't like their avoidance, when they're funding the very regulatory capture which makes it hard for us to do that, via their investment in these schemes.

mjw··on Google Boss: We Follow The Law On Tax
Fair point, although it's rather disingenuous for multinationals (not singling out Google) to say to taxpayers: "don't like our tax avoidance? well just change the rules then!"

Arguably one of the main reason we're not able to change (or at least, enforce) the rules easily is because of regulatory capture of tax agencies around the world, and multinationals are (directly or indirectly) funding this regulatory capture via their investment in complex tax avoidance schemes and the whole industry around them which is in constantly in and out of the "revolving door" between regulators and accountancy firms.

So, likely there's always going to be opportunities out there for aggressive tax avoidance, because of exactly these kind of agency problems. And so a multinational is always going to have a decision to make about exactly how aggressive they choose to be. And they are going to be judged morally by the taxpayer for the decisions they make, whether they like it or not.

If they are judged badly as a result of their choices, they should have the good grace to just admit that they're being selfish because they can get away with it and that's the way things are, and not come up with disingenuous self-serving rationalisations.

mjw··on Callbacks are imperative, promises are functional
Have to admit that has also been my reaction to some of these javascript async frameworks based on promises or deferreds. Congratulations, you've reimplemented a quirky ad-hoc variant on the continuation and error monads.

Perhaps people don't spot the link as easily because monads are usually explained in terms of a type system, and javascript is untyped? (Or perhaps just because Monad is a very abstract abstraction :)

mjw··on Clojure: All grown up
I'll have a crack at some suggestions, as a Clojure user (nice work on core.logic!) with some Haskell familiarity.

For logic programming: you might find Control.Unification [1] interesting -- and of course if you don't need unification then you can go pretty far with the plain old List monad.

Protocols/multimethods: Haskell typeclasses are really really powerful. Probably my favourite of all the approaches to polymorphism I've seen anywhere, although YMMV (they do lean heavily on the type system.)

Macros: there is Template Haskell [2], which is pretty interesting although I can't claim to've used it myself. It doesn't quite share the simplicity of macros in a homoiconic dynamic language, but at the same time in Haskell it feels like you don't need to lean on compile-time metaprogramming as much as you do in a Lisp to achieve power. (Can't quite put my finger on why).

[1] http://hackage.haskell.org/packages/archive/unification-fd/0... [2] http://www.haskell.org/haskellwiki/Template_Haskell

mjw··on Clojure's Default Reader is Unsafe
> It reads raw input and tries to evaluate it

Not quite. It reads raw input and tries to build a syntax tree from it. Unfortunately reader macros in clojure allow all sorts of objects to form part of said syntax tree and arbitrary-ish code to run at parse time to instantiate them. But the main job of the reader isn't to evaluate code.

mjw··on Clojure's Default Reader is Unsafe
I was wondering this too, and deliberately tried to break something using the clojure 1.5 reader with read-eval false. (Makes a change from building things all day!).

Result:

    user=> (binding [*read-eval* false] (read-string "``````````x"))
    OutOfMemoryError Java heap space  clojure.lang.RT.cons (RT.java:570)
mjw··on Trapping a Transcendental: There are reals that are not roots of polynomials
This is a really nice proof, and I love this kind of "you could have discovered X if you'd just had this core idea!" kind of exposition.

Perhaps a hard ask, but do you know of any similarly explicable proofs for transcendental-ness of "well known" numbers?

mjw··on Why there is no Hitchhiker’s Guide to Mathematics for Programmers
In the sense of http://en.wikipedia.org/wiki/Curry–Howard_correspondence, the theorems are the type signatures of the API, and the proofs are the implementations!
mjw··on Getting Started With Clojure
Not quite, I'm talking about replacing the various important java interfaces in clojure.lang (IFn, ISeq, IPersistentMap etc) with protocols, so you can implement them yourself without using any Java-specific language features.

Dunno how feasible this is, but if a language is going to define its own abstraction features (here, protocols) on top of the underlying platform, it would seem cleaner to eat ones own dogfood in using these abstraction facilities for the core abstractions which the language and its core library are based on.

mjw··on Getting Started With Clojure
You have to use the java interop facilities if you want your own types to implement these abstractions though right?

I recall some debate about changing this so you can implement them using the native abstraction facilities in clojure (protocols), at which point I'd probably withdraw my point.

But yeah elegance is subjective. I use Clojure and broadly like it, JVM interop is really useful, but the lack of a crisp separation between clojure semantics and JVM semantics does still irk the purist in me a bit.

I guess I'd see Clojure and ClojureScript not as one language on two host platforms, but as one JVM language and another similar but not really source-compatible language on another platform which is influenced by it. Part of the philosophy seems to be to make pragmatic decisions which blur the boundary with the host platform, rather than try to abstract over the differences in APIs and runtime semantics.

mjw··on Getting Started With Clojure
The keyword syntax is transformed into a keyword instance by the reader, and keyword instances implement IFn as objects on the JVM, hence can be used as functions under clojure's evaluation rules.

As I understand it, the roles which things like lists and functions play in a traditional lisp are replaced in Clojure by abstract datatypes corresponding to Java interfaces. Which on one hand is kinda neat because the core lisp datatypes aren't tied to specific concrete implementations and other datatypes (including user-defined ones) can participate in the same abstractions.

On the other hand it means the semantics become quite tied up in underlying JVM-related details and don't seem as clean/elegant as (say) Scheme.

← PreviousPage 3 of 9Next →