/// <summary>
        /// NeuralNetTeacherクラスを使って、既に生成されている特徴ベクトルをまとめたファイルを読み込ませて学習を行う part2
        /// </summary>
        public static void Iris_learning2()
        {
            var minPara = new MinParameter(13, 1, 0.1);
            var NNteacher = new Teacher(minPara);                               // ニューラルネットの教師クラスのインスタンスを生成
            NNteacher.Setup("教師データの例 Iris");

            int timeOfLearning = 10000;
            for (int i = 1; i <= 2; i++)                                        // 2回ループさせる
            {
                NNteacher.Learn(timeOfLearning);
                NNteacher.SaveDecisionChart("decision chart " + (i * timeOfLearning).ToString() + ".csv");
            }
            NNteacher.SaveLearnigOutcome();                                     // 学習した結合係数などをファイルに保存

            // これ以降は識別テスト
            var feature = new Feature("5.4	3.4	1.7	0.2");                      // セトナのデータ

            // 学習済みのニューラルネットワーククラスオブジェクトを渡して学習器を構成
            var discriminator = new Discriminator(NNteacher.GetNeuralNetwork(), NNteacher.ModelIDs);// これ以降、学習成果を利用して識別を行うことができる。
            var test = discriminator.Discriminate(feature, 2);                  // 結果を降順で2つもらう
            string outputstr = "";
            for (int i = 0; i < test.Length; i++)
                outputstr += test[i].ID + ", " + test[i].Likelihood.ToString("0.00") + "\n";
            Console.WriteLine(outputstr, "識別テストその1の結果");

            // ファイルから結合係数を読み込ませても同じ結果が出ることを確認する
            var discriminator2 = new Discriminator();
            discriminator2.Setup();
            var test2 = discriminator.Discriminate(feature);                    // テストを実施し、表示する
            Console.WriteLine("識別結果: " + test2.ID + ", " + test2.Likelihood.ToString("0.00"), "識別テストその2の結果");
            return;
        }
        /// <summary>
        /// 音声ファイルを開き、生成された特徴ベクトルのリストを返す
        /// </summary>
        /// <param name="waveFilePath">WAVEファイルのフルパス</param>
        /// <param name="discriminator">識別器<para>識別させない場合は省略して下さい。</para></param>
        /// <param name="threshold">棄却レベル<para>識別のさせる場合、この値を下回ると識別結果をUnknownと判定します。</para></param>
        /// <returns>
        /// 生成された特徴ベクトルのリスト
        /// <para>識別器を指定している場合は、識別結果を添付します。</para>
        /// </returns>
        public List<Result> GenerateFeatureList(string waveFilePath, Discriminator discriminator = null, double threshold = 0.0)
        {
            var ans = new List<Result>(0);                                                          // 結果を格納する

            if (System.IO.File.Exists(waveFilePath))
            {
                WaveReader wave_file = new WaveReader();
                wave_file.Open(waveFilePath);                                                       // waveファイルを開く
                if (wave_file.IsOpen)
                {
                    try
                    {
                        this.Lock = true;
                        this.SetGenerator(wave_file);
                        this._generator.Log = this.Log;
                        DFT fft = new DFT(this.ReadAmount, Window.WindowKind.Hanning);              // FFTを実施する準備
                        while (wave_file.IsOpen && wave_file.ReadLimit == false)                    // 読めるなら、全て読むまでループ
                        {
                            MusicData data = wave_file.Read(this.ReadAmount);                       // ファイルからread_size_sec秒間読み込み。
                            double[] sound;
                            if (data.UsableCH == MusicData.UsableChannel.Left)                      // データの入っている方を格納する
                                sound = data.GetData(MusicData.Channel.Left);                       //
                            else
                                sound = data.GetData(MusicData.Channel.Right);
                            FFTresult result = fft.FFT(sound, (double)wave_file.SamplingRate);      // FFTを実行. FFTサイズが音声データよりも小さい場合、始めの方しか処理されないので注意.
                            this._generator.Add(result);
                            if (this._generator.Ready)
                            {
                                //Console.WriteLine("検出したようです。");                          // デバッグモードで動かしながら確認するためのコンソール出力
                                Result feature = this._generator.GetFeature();                      // 特徴ベクトル生成
                                if (discriminator == null)
                                    ans.Add(feature);                                               // 答えを格納
                                else
                                {
                                    Discriminator.IDandLikelihood id = discriminator.Discriminate(feature.FeatureVector);
                                    string name = id.ID;
                                    if (id.Likelihood < threshold) name = "Unknown";
                                    feature.DiscriminationResult = name;
                                    if (!(this.MatchOnlyAtDiscrimination == true && name != feature.FilterName)) ans.Add(feature);
                                }
                            }
                        }
                    }
                    catch (SystemException e)
                    {
                        throw new Exception(e.Message);
                    }
                }
                else
                    throw new Exception("Waveファイルを開くことができませんでした。\nWaveReaderクラスエラーメッセージ:" + wave_file.ErrorMessage);
                wave_file.Close();                                                              // waveファイルを閉じる
            }
            this.Lock = false;
            return ans;
        }