naive-bayes
naive-bayes copied to clipboard
TypeError: first argument must be a positive number
When attempting to run with the following data-sets:
const cases = [ [ 200, 100, 1500, 500, 2700 ],
[ 300, 25, 1555, 750, 2800 ],
[ 150, 200, 2000, 50, 2150 ],
[ 400, 15, 1250, 450, 3000 ],
[ 202, 45, 1555, 400, 2500 ],
[ 251, 87, 1575, 325, 2000 ],
[ 175, 30, 1475, 300, 2222 ],
[ 225, 100, 1444, 500, 2300 ],
[ 300, 15, 1543, 555, 2500 ],
[ 222, 10, 1345, 520, 2345 ] ]
const predictions = [ 2.5555555555555554,
2.817857142857143,
4,
2.1149999999999998,
2.6424000000000003,
4,
2.6732673267326734,
2.959565217391304,
2.8956,
2.6827292110874197 ]
I am getting the following stsack:
TypeError: First argument must be a positive number or an array
at Matrix (/Users/ZYG9085/sandbox/geek-out/machine-learn-test/node_modules/ml-matrix/matrix.js:3006:19)
at NaiveBayesEx.separateClasses (/Users/ZYG9085/sandbox/geek-out/machine-learn-test/src/app/components/naive-bayes.js:89:29)
at new NaiveBayesEx (/Users/ZYG9085/sandbox/geek-out/machine-learn-test/src/app/components/naive-bayes.js:40:10)
I believe this is from the implementation of seperateClasses, but have yet to dig too deep
Are you doing some kind of regression? because predictions should be integers @goldsziggy
In fact when we use classification the result is a defined class. So the result can't be continuous. You will probably have to define classes (e.g : class "0" corresponds to float < 2, class "1" to float between 2 and 2.1, class "2" to float between 2.1 and 2.2, etc.). I believe that what you want to do is a regression, not a classification.
I was looking thoght this issue and I looked this method separateClasses and it is doing wrong, becose it went creating an array and incrementing every index corresponding the classes of y, then when it interates with 'classes' variable certatly it will find an undefined value and will throws an Exception. I will try to fix this as soon as posible, I will be glad if the repository admin looked at this too
I will look at it, thanks for reporting it @rzorzal
I have run into the same issue, the reason is that the classes need to be a continuous sequence of integers, starting with 0. So, [ 0, 1, 2, 3] is valid, while invalid are all of [ 1, 2, 3 ] [ 0, 1, 3 ] [ 'a', 'b', 'c' ]
I'm solving it by
let classIndices = stringPredictions.reduce((o, key) => { o[key] = 0; return o; }, {});
Object.keys(classIndices).forEach((key, idx) => { classIndices[key] = idx; });
var predictions = stringPredictions.map(r => classIndices[r]);
but this won't work if I train on several datasets and some of them just don't contain some of the classes.
I encountered this issue as well and when debugging I found exactly what @rzorzal was talking about. my "classes" were two integers: 1 and -1 and it went to the undefined
case already mentioned. When I changed the classes to 0 and 1 it was OK, still it means we need to have some dictionaries in our code when dealing with certain examples whose classes are not consecutive integers.
We would gladly accept a pull request to fix this :)
I think I made a fix for it locally, but it's pretty ugly right now. I'll clean it up and push a branch tomorrow if I get some time in the afternoon.
@targos check out this branch and how it diffs with the current master https://github.com/victorbadila/naive-bayes/tree/fix/type-error-first-argument
It's work in progress but hopefully it reveals details about the problem. I added some tests for the extra cases, however there is a recurring problem with separateClasses
returning an array whose indexes would be the predictions values (0, 1, etc.). If we want to support chars or strings for example as prediction values they would still be assignable as array indexes (you can do myArray["a"]
), however if you want to loop through it later you would have to get it's actual keys and not use the usual iteration, and finally getting the keys via Object.keys(myArray)
would lead to possible type changes for prediction values which are numbers, as Object.keys..
returns an array of strings. This can be seen in how I modified the tests. But this breaks the API. I would propose having separateClasses
return a dictionary instead of an array and have some extra info for each entry in order to know if the key should be a string, number, etc. aka the original prediction value.
@targos please check this PR: https://github.com/mljs/naive-bayes/pull/12/files
It works so far for GaussianNB, if you or anyone maintining this are OK with the changes over there I will update the things for MultinomialNB as well.
Can this please be merged yet? I experienced the same issue, 3 years later.