NDSM wharf, Amsterdam
dvdgrs [graus.nu] posted a photo:
dvdgrs [graus.nu] posted a photo:
graus.nu posted a photo:
graus.nu posted a photo:
dvdgrs posted a photo:
Samyang 8mm @ Openbare Bibliotheek Amsterdam
As I am starting to gather testing data, I figured it’d be a good time to determine how to measure the performance of the different results of my 24 text representation algorithms. What I want to measure per algorithm: how many keywords are predicted the same as the experts, and how many aren’t. After some research and valuable advice, I came across confusion matrices, which seemed appropriate. For each algorithm I measure the amount of:
Predicted | |||
Negative | Positive | ||
Actual | Negative | A | B |
A. True Negatives (excluded by algorithm & excluded by experts)
B. False Positives (included by algorithm & excluded by experts)
C. False Negatives (excluded by algorithm & included by experts)
D. True Positives (included by algorithm & included by experts)
I found this page from the University of Regina explaining confusion matrices, and decided to implement it. My implementation in pseudocode:
For each text: fill expertList with expertResults #list of URIs fill algoList with algorithmResults #list of URIs algoPOS = algoList[text] #URIs included by algorithm algoNEG = [item for item in NCIthesaurus if item not in algoPOS] #URIs excluded by algorithm (ontology-algoPOS) expertPOS = expertList[text] #all URIs included by experts expertNEG = [item for item in NCIthesaurus if item not in expertPOS] #all URIs excluded by experts (ontology-expertPOS) A += len(set(algoNEG).intersection(expertNEG)) #True Negatives (number of URIs that overlap in algoNEG and expertNEG) B += len(set(algoPOS).intersection(expertNEG)) #False Positives (number of URIs that overlap of algoPOS and expertNEG) C += len(set(algoNEG).intersection(expertPOS)) #False Negatives (number of URIs that overlap in algoNEG and expertPOS) D += len(set(algoPOS).intersection(expertPOS)) #True Positives (number of URIs that overlap in algoPOS and expertPOS) matrix.append([[A,B],[C,D]]) #Put numbers in a matrix
With this information I can calculate a set of standard terms:
Accuracy (AC), Recall or True Positive Rate (TP), False Positive Rate (FP), True Negative Rate (TN), False Negative Rate (FN), Precision (P).
AC = ((A+D) / (A+B+C+D)) TP = ((D) / (C+D)) FP = ((B) / (A+B)) TN = ((A) / (A+B)) FN = ((C) / (C+D)) P = ((D) / (B+D))
The only thing with the rates are that proportions are heavily skewed because of the size of the ontology (90.000 URIs), which means the negative cases will always be much more frequent than the positives. This means that accuracy is always around 99.9%, and so is the TN. I still have to figure out exactly what information I want to use and how (visualize?).
dvdgrs posted a photo:
Update: Newer example of Force-Directed d3.js Graph here: Measure and Visualize Semantic Similarity Between Subgraphs
I recently replaced python-graph in my code with NetworkX, a slightly more sophisticated graph library for Python. Besides some more advanced algorithms for graph analysis (comparison, unison etc.) which can prove useful when analyzing data (comparing human data with mine, for example), I can also easily export my graphs to all kinds of formats. For example, to JSON. As I was getting a bit tired of GraphViz’ stubborn methods, and it’s far from dynamic approach, I decided to start playing around with the excellent Data Driven Documents JavaScript library, better known as D3.js, the successor to Protovis. Actually I had planned this quite a while ago, simply because I was impressed with the Force-directed Graph example on their website. I figured for coolness sake, I should implement them, instead of using the crummy GraphViz graphs.
So after a night and day of tinkering with the D3 code (starting from the Graph example included in the release, modifying stuff as I went) I came to this:
The red nodes are the concepts taken from the texts (either literal: filled red circles, or resulting from text classification: red donuts). The orange nodes are LCS-nodes (Lowest Common Subsumers), aka ‘parent’ nodes, and all the grey ones are simply in-between nodes (either for shortest paths between nodes, or parent nodes).
I added the labels, and also implemented zoom and panning functionality (mousewheel to zoom, click and drag to pan), included some metadata (hover with mouse over nodes to see their URI, over edges to see the relation). I am really impressed with the flexibility of D3, it’s amazing that I can now load up any random graph produced from my script, and instantly see results.
The bigger plan is to make a fully interactive Graph, by starting with the ‘semantic similarity’ graph (where only the red nodes are displayed), and where clicking on edges expands the graph, by showing the relationship between two connected nodes. Semantic expansion at the click of a mouse ;)!
I’ve got a date for my graduation! If everything goes right, March 23rd is the day I’ll present my finished project. I’ll let you know once it’s final.
dvdgrs posted a photo:
dvdgrs posted a photo:
Peddie gappin’ @SkateparkAmsterdam
Samyang 8mm @ F/11
Metz 48 AF-1
dvdgrs posted a photo:
Samyang 8mm fisheye @ F/11
dvdgrs posted a photo:
Peddie 5-0 @ SkateparkAmsterdam
Samyang 8mm @ F/11 + oncam Metz 48 AF-1
dvdgrs posted a photo:
Metz Mecablitz 48 AF-1, with full iTTL/CLS/Commander mode support! (photo taken with D90 + mounted SB-26 with omnibounce :P)
Now I will stop buying gear for the coming years ;-)!
While I haven’t been as active and hard working on my graduation project as I would have liked to be, I am not dead (nor the project). Earlier this week I presented my project to the Bio-imaging group of Leiden University, which helped me a lot. I was able to present my project pretty much as-is, since I’m mostly done with the technical parts. I received valuable feedback and got good insights into what I should explain more thoroughly in the presentation. Continue reading “Not dead (yet)”
dvdgrs posted a photo:
Samyang 8mm @ f/11
dvdgrs posted a photo:
Samyang 8mm @ f/11
dvdgrs posted a photo:
Samyang 8mm @ f/11