Skip to content
This repository has been archived by the owner on Nov 19, 2020. It is now read-only.

KNearestNeighbors Constructor (Int32, Int32, Double[][], Int32[], IMetric(Double[])) #386

Closed
Lyubna opened this issue Jan 18, 2017 · 5 comments

Comments

@Lyubna
Copy link

Lyubna commented Jan 18, 2017

How to generate the IMetric(Double[]) parameter? I need to calculate the Cosine distance

My input is double[][]
output is int []

it works fine when I use
KNearestNeighbors knn = new KNearestNeighbors(k: 10, classes: 3, inputs: inputs, outputs: outputs);

but when I want to change the distance as you showed in the example like that
KNearestNeighbors knn = new KNearestNeighbors(k: 10, classes: 3, inputs: inputs, outputs: outputs,distance: Distance.Cosine);

it shows me the following error:
Error 1 The best overloaded method match for 'Accord.MachineLearning.KNearestNeighbors.KNearestNeighbors(int, int, double[][], int[], Accord.Math.Distances.IMetric<double[]>)' has some invalid arguments

Error 2 Argument 5: cannot convert from 'method group' to 'Accord.Math.Distances.IMetric<double[]>'

What can I do to solve this and change the default Euclidean distance to Cosine?
p.s. I also tried the example you used with classifying the strings, it also showed error

@Lyubna Lyubna closed this as completed Jan 18, 2017
@Lyubna Lyubna reopened this Jan 18, 2017
@Lyubna Lyubna changed the title Add an Example for KNearestNeighbors Constructor (Int32, Int32, Double[][], Int32[], IMetric(Double[])) KNearestNeighbors Constructor (Int32, Int32, Double[][], Int32[], IMetric(Double[])) Jan 18, 2017
@cesarsouza
Copy link
Member

cesarsouza commented Jan 18, 2017

Hi there,

Please, can you try creating a new Cosine distance using the new operator? For example:

var knn = new KNearestNeighbors(k: 10, classes: 3, inputs: inputs, outputs: outputs, distance: new Cosine());

The Cosine class resides in the Accord.Math.Distances namespace.

Hope it helps!

Best regards,
Cesar

@Lyubna
Copy link
Author

Lyubna commented Jan 19, 2017

Tried that too but it didn't work
var knn = new KNearestNeighbors(k: 10, classes: 3, inputs: inputs, outputs: outputs, distance: new Accord.Math.Distances.Euclidean());
but
var knn = new KNearestNeighbors(k: 10, classes: 3, inputs: inputs, outputs: outputs, distance: new Accord.Math.Distances.Cosine());
Doesn't work

@cesarsouza
Copy link
Member

Oh yeah, it's because K-Nearest Neighbors is expecting a proper distance metric, while the Cosine gives only a similarity distance.

While I work in the issue, a quick solution is to implement a class that implements the IMetric interface and implement the "Distance" method using the definition for the Cosine distance you would like to use.

Is there any particular paper or model you would like to implement? If yes then I can prepare the proper metric for the model you need.

Regards,
Cesar

@cesarsouza
Copy link
Member

cesarsouza commented Jan 24, 2017

Hi there,

Thanks!

Though I have to say there were some problems in the code you posted in your Similarity method.

In a nutshell, you might be able to address the problem you were currently facing by implementing the following class:

[Serializable]
public CosineMetric : IMetric<double[]>
{
    public double Similarity(double[] x, double[] y)
    {
        double sum = 0;
        double p = 0;
        double q = 0;

        for (int i = 0; i < x.Length; i++)
        {
                sum += x[i] * y[i];
                p += x[i] * x[i];
                q += y[i] * y[i];
        }    

        double den = Math.Sqrt(p) * Math.Sqrt(q);
        return (sum == 0) ? 0 : sum / den;
    }

    public double Distance(double[] x, double[] y)
    {
        return (Math.Acos(Similarity(x, y)) / Math.PI);
    }
}

And then passing an instance of this class to the kNN constructor you initially referenced.

Hope it helps!

Best regards,
Cesar

cesarsouza added a commit that referenced this issue Jan 27, 2017
…2[], IMetric(Double[]))

Adding Angular distance metric (proper distance metric based on the Cosine similarity)
@cesarsouza
Copy link
Member

Fixed in 3.5.0.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants