コード例 #1
0
ファイル: DTWClassifier.cs プロジェクト: kayyer/sigstat
        /// <inheridoc/>
        public ISignerModel Train(List <Signature> signatures)
        {
            var genuines = signatures.Where(s => s.Origin == Origin.Genuine)
                           .Select(s => new { s.ID, Features = s.GetAggregateFeature(Features).ToArray() }).ToList();
            var distanceMatrix = new DistanceMatrix <string, string, double>();

            foreach (var i in genuines)
            {
                foreach (var j in genuines)
                {
                    if (distanceMatrix.ContainsKey(j.ID, i.ID))
                    {
                        distanceMatrix[i.ID, j.ID] = distanceMatrix[j.ID, i.ID];
                    }
                    else if (i == j)
                    {
                        distanceMatrix[i.ID, j.ID] = 0;
                    }
                    else
                    {
                        distanceMatrix[i.ID, j.ID] = DtwPy.Dtw(i.Features, j.Features, DistanceFunction);
                    }
                }
            }

            var distances = distanceMatrix.GetValues().Where(v => v != 0);
            var mean      = distances.Average();
            var stdev     = Math.Sqrt(distances.Select(d => (d - mean) * (d - mean)).Sum() / distances.Count());

            double med;
            var    orderedDistances = new List <double>(distances).OrderBy(d => d);

            if (orderedDistances.Count() % 2 == 0)
            {
                int i = orderedDistances.Count() / 2;
                med = (orderedDistances.ElementAt(i - 1) + orderedDistances.ElementAt(i)) / 2.0;
            }
            else
            {
                int i = orderedDistances.Count() / 2;
                med = orderedDistances.ElementAt(i);
            }

            return(new DtwSignerModel
            {
                GenuineSignatures = genuines.Select(g => new KeyValuePair <string, double[][]>(g.ID, g.Features)).ToList(),
                DistanceMatrix = distanceMatrix,
                Threshold = mean + MultiplicationFactor * stdev
                            //Threshold = med + (distances.Max() - med) * 1 / 2
            });
        }
コード例 #2
0
ファイル: DTWClassifier.cs プロジェクト: kayyer/sigstat
        /// <inheridoc/>
        public double Test(ISignerModel model, Signature signature)
        {
            var dtwModel      = (DtwSignerModel)model;
            var testSignature = signature.GetAggregateFeature(Features).ToArray();
            var distances     = new double[dtwModel.GenuineSignatures.Count];

            for (int i = 0; i < dtwModel.GenuineSignatures.Count; i++)
            {
                distances[i] = DtwPy.Dtw(dtwModel.GenuineSignatures[i].Value, testSignature, DistanceFunction);
                dtwModel.DistanceMatrix[signature.ID, dtwModel.GenuineSignatures[i].Key] = distances[i];
            }

            // returns value between 0 and 1, how confident is the decision about genuineness
            // 1 -> conident genuine, 0 -> not confident genuine = confident forged
            return(Math.Max(1 - (distances.Average() / dtwModel.Threshold) / 2, 0));
        }
コード例 #3
0
        public double[,] Calculate()
        {
            var distances = new double[InputSignatures.Count, InputSignatures.Count];

            for (int i = 0; i < InputSignatures.Count; i++)
            {
                for (int j = 0; j < InputSignatures.Count; j++)
                {
                    distances[i, j] =
                        DtwPy.Dtw <double[]>(
                            InputSignatures[i].GetAggregateFeature(InputFeatures),
                            InputSignatures[j].GetAggregateFeature(InputFeatures),
                            InputFunc);
                }
            }
            return(distances);
        }
コード例 #4
0
        private Tuple <int, Stroke, double, int> CalculateIdx(Stroke stroke, List <Vertex> trajectory, int window, int jump = 1)
        {
            int    resIdx = int.MaxValue;
            double resVal = Double.MaxValue;

            for (int i = 0; i < trajectory.Count - window; i += jump)
            {
                double val = DtwPy.Dtw <double[]>(stroke.GetDtwPairingFeature(InputScale),
                                                  trajectory.GetRange(i, window).GetDtwPairingFeature(InputScale),
                                                  DtwPairingDistance);
                if (val < resVal)
                {
                    resVal = val;
                    resIdx = i;
                }
            }
            return(new Tuple <int, Stroke, double, int>(resIdx, stroke, resVal, window));
        }
コード例 #5
0
        public List <Tuple <string, string, double> > Calculate()
        {
            var distances = new double[OfflineSignatures.Count];

            Parallel.For(0, OfflineSignatures.Count,
                         idx =>
            {
                var offlineSig        = OfflineSignatures[idx];
                var offlineTrajectory = offlineSig.GetFeature <List <Vertex> >(InputOfflineTrajectory);
                var onlineSig         = OnlineSignatures.Find(sig => sig.ID == offlineSig.ID && sig.Signer.ID == offlineSig.Signer.ID);
                var onlineTrajectory  = onlineSig.GetFeature <List <Vertex> >(InputOnlineTrajectory);
                distances[idx]        = DtwPy.Dtw(offlineTrajectory.GetOriginalXYs(), onlineTrajectory.GetOriginalXYs(), PenDistance);
            }
                         );
            var res = new List <Tuple <string, string, double> >();

            for (int i = 0; i < OfflineSignatures.Count; i++)
            {
                res.Add(new Tuple <string, string, double>(OfflineSignatures[i].Signer.ID, OfflineSignatures[i].ID, distances[i]));
            }
            return(res);
        }
コード例 #6
0
ファイル: DtwHelper.cs プロジェクト: bmeaut/sigstat
        public static double GetCost(Signature sig1, Signature sig2, DtwType dtwType, List <FeatureDescriptor> features)
        {
            switch (dtwType)
            {
            case DtwType.DtwPy:
                return(DtwPy.Dtw(sig1.GetAggregateFeature(features), sig2.GetAggregateFeature(features), DtwPy.EuclideanDistance));

            case DtwType.NDtw:
                //hatalmas hack, csak egy-egy featurere működik, kombinációra nem
                return(new NDtw.Dtw(sig1.GetFeature <List <double> >(features[0]).ToArray(), sig2.GetFeature <List <double> >(features[0]).ToArray(),
                                    DistanceMeasure.Manhattan).GetCost());

            case DtwType.FrameworkDtw:
                return(new SigStat.Common.Algorithms.Dtw(Accord.Math.Distance.Manhattan)
                       .Compute(sig1.GetAggregateFeature(features).ToArray(), sig2.GetAggregateFeature(features).ToArray()));

            case DtwType.MyDtw:
                return(new Common.Dtw(sig1, sig2, features).CalculateDtwScore());

            default:
                throw new ArgumentException(nameof(dtwType) + typeof(DtwType) + "not exists");
            }
        }