Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

this is my solution to Exercise 5 of http://work.caltech.edu/homework/hw2.pdf Please help me make this more elegant.

The exercise is about classifying random Points by a (randomly generated) target function to 2 classes (-1 and +1), build a new target function by linear Regression and compare where they don't classify to the same value.

first I generate two Random Points to build the target function

funktionsPunkte = RandomReal[{-1, 1}, {2, 2}]

then generate the target function from it (to classify the data points)

targetFct[{x1_, x2_}] := 
With[{targetFunction = LinearModelFit[funktionsPunkte, {1, t}, t]}, 
x2 - targetFunction[x1]];

then I generate 100 data Points and classify them to either +1 or -1 ,depending if they are above or below the target function

data = With[{points = RandomReal[{-1, 1}, {100, 2}]}, 
Map[{Prepend[#, 1], If[targetFct[#] < 0, -1, 1]} &, points]];

one data Point is of the form {{1,x1,x2},y} where y is either +1 or -1.

now Comes the ugly part. I Need the weight vector w = PseudoInverse[{1,x1,x2}].y

w = (PseudoInverse[#[[1]] & /@ data]).(#[[2]] & /@ data)

only {1,x1,x2} :

xlist = (#[[1]] &) /@ data;

the sign of each element w.x (-1 or 1 depending on which class we classify it)

 sig = Sign /@ (w.# &) /@ xlist ;

only the y of our data Points

datasig = #[[2]] & /@ data;

now we Count the "misclassified" elements

Length[Select[
 Table[sig[[i]] != datasig[[i]], {i, 100}], # == True &]]

now I Need to repeat this Experiment a 1000 times and take the mean. But how do I do that. I'm coming from an imperative Point of view and this would be trivial there.

I'm also welcoming more elegant Solutions that more use functional and mathematica specific elements.

edit:

thanks to the comments, I made this

f := Module[{}, funktionsPunkte = RandomReal[{-1, 1}, {2, 2}];
 targetFct[{x1_, x2_}] := 
 With[{targetFunction = LinearModelFit[funktionsPunkte, {1, t}, t]},
 x2 - targetFunction[x1]];
 data = With[{points = RandomReal[{-1, 1}, {100, 2}]}, 
 Map[{Prepend[#, 1], If[targetFct[#] < 0, -1, 1]} &, points]];
 w = (PseudoInverse[#[[1]] & /@ data]).(#[[2]] & /@ data);
 xlist = (#[[1]] &) /@ data;
 sig = Sign /@ (w.# &) /@ xlist;
 datasig = #[[2]] & /@ data;
 Length[Select[
 Table[sig[[i]] != datasig[[i]], {i, 100}], # == True &]]]

and then

f & /@ Range[1000]

it's awfully slow but it works (have not implemented the other suggestions yet)

share|improve this question
1  
Pack your steps into one function and repeat $n$ times. Module or similar are useful for that. You can merge separate cells, but make sure you use the right amount of ;. –  Yves Klett Nov 19 '13 at 15:17
1  
I should mention that this is an ungraded homework from a mooc course of caltech –  spore234 Nov 19 '13 at 15:35
    
funktionsPunkte, some Denglish there :D –  Yves Klett Nov 19 '13 at 15:39
    
Why don't you wait after it is graded? –  Rolf Mertig Nov 19 '13 at 15:44
    
@RolfMertig he said ungraded, right? Also from the homework: "You are also encouraged to take part in the forum [other forum] where there are lots of threads about each homework" –  Jacob Akkerboom Nov 19 '13 at 15:50

2 Answers 2

up vote 6 down vote accepted

One part of your question is about iteration. Building on Yves comment, one good way is to pack everything inside a function. To simplify your problem, say the function is:

f := RandomReal[{0, 1}];

Each time f is called, you get a new random number. (This greatly simplifies your problem, but the same idea holds.) Now to iterate 1000 times, you can use Map

f & /@ Range[1000]

and you get a list of the function, evaluated 1000 times.

In your case, you have a more complex function... Module will let you nicely place lots of commands together:

f := Module[{}, statement1; statement2; Sign[RandomReal[{-1, 1}]]]

Again, f & /@ Range[1000] will iterate this 1000 times.

share|improve this answer
    
thanks. This really works –  spore234 Nov 19 '13 at 16:00

You use #[[i]]&/@somelist a lot when instead you can use a part specification like: somelist[[All, i]] to get the i-th column.

To count miss-classified you can look at the difference of the lists and count all non-zero elements like:

Length[Select[Table[sig[[i]] != datasig[[i]], {i, 100}], # == True &]]

(* Same as: *)
Total@Unitize[sig - datasig]

The function Sign is Listable which means you don't have to use Map:

Sign[{-1, 2, 1}]
(* {-1, 1, 1} *)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.