public override void Update(Population Pop, double P, StdList Sigma) { double SumNumerosity = 0; foreach (Classifier C in this.CList) { SumNumerosity += C.N; } foreach (Classifier C in this.CList) { C.Exp++; if (C.Exp < 1 / Configuration.Beta) { C.P += (P - C.P) / C.Exp; C.As += (SumNumerosity - C.As) / C.Exp; } else { C.P += Configuration.Beta * (P - C.P); C.As += Configuration.Beta * (SumNumerosity - C.As); } // 標準偏差計算 C.St++; double X = P - C.M; C.M += X / C.St; C.S += (C.St - 1) * X * X / C.St; //あっている?? if (double.IsNaN(C.S)) { Console.ReadLine(); } if (C.GetType().Name == "SigmaNormalClassifier") { // このIterationまでのepsilonを記録ずらし SigmaNormalClassifier SNC = ( SigmaNormalClassifier )C; for (int index = SNC.EpsilonList.Count() - 1; index > 0; index--) { SNC.EpsilonList[index] = SNC.EpsilonList[index - 1]; } SNC.EpsilonList[0] = Math.Sqrt(C.S / (C.St - 1)); #region 分類子が照合する全状態のVTの分散と平均を使って e0 を推測 chou 160107 //分類子が照合する全状態のVTの分散と平均を使って e0 を推測 chou 160107 if (Configuration.IsConvergenceVT) { if (C.Exp > 2) //0120 cho { if (SNC.IsConvergenceEpsilon()) //分類子のstd が収束するときepsilon を更新 { C.Epsilon = SNC.EpsilonList[0]; } else//epsilon収束しない場合 強化学習 { if (C.Exp < Configuration.Beta) { C.Epsilon += (Math.Abs(P - C.P) - C.Epsilon) / C.Exp; } else { C.Epsilon += Configuration.Beta * (Math.Abs(P - C.P) - C.Epsilon); } } } Classifier cl0 = new NormalClassifier(); cl0.S = 0; cl0.M = 0; cl0.St = 0; List <StdList> cpStdLists = new List <StdList>(); foreach (var std in Configuration.ConvergentedVT) { if (std.IsIncluded(C.C.state)) { cpStdLists.Add(std.Clone()); //クローンメソット } } if (cpStdLists.Count == 1) { C.Epsilon_0 = cpStdLists[0].S + Configuration.Epsilon_0; } else { foreach (var std in cpStdLists) { //St 出現回数 cl0.St += std.T; cl0.M += std.M * std.T; } //ここst= 0 , cl0.M がNULLになる cl0.M = cl0.M / cl0.St; foreach (var std in cpStdLists) { cl0.S += std.T * Math.Pow(std.S, 2) + std.T * Math.Pow((cl0.M - std.M), 2); } cl0.S = Math.Sqrt(cl0.S / cl0.St); C.Epsilon_0 = cl0.S + Configuration.Epsilon_0; } } #endregion #region tatumi 160106 XCS-SAC VTが全部収束したら 加重平均でe0更新 //if (Configuration.IsConvergenceVT) //{ // //tatumi 160106 XCS-SAC VTが全部収束したら 加重平均でe0更新 // if (C.Exp > 2 && SNC.IsConvergenceEpsilon())//0120 cho // { // C.Epsilon = SNC.EpsilonList[0]; // } // double WeightedSum = 0; // int WeightedCount = 0; // foreach (StdList SL in Configuration.Stdlist) // { // if (SL.IsIncluded(C.C.state)) // { // if (!double.IsNaN(SL.S)) // { // WeightedSum += (SL.T - 1) * Math.Pow(SL.S, 2); // WeightedCount += SL.T; // } // } // } // // 下駄適応済み // if (WeightedCount > 1) // { // WeightedSum = Math.Sqrt(WeightedSum / (WeightedCount - 1)) + Configuration.Epsilon_0; // } // else // { // WeightedSum = Configuration.Epsilon_0; // } // C.Epsilon_0 = WeightedSum; //} //else //{ // if (C.Exp < Configuration.Beta) // { // C.Epsilon += (Math.Abs(P - C.P) - C.Epsilon) / C.Exp; // } // else // { // C.Epsilon += Configuration.Beta * (Math.Abs(P - C.P) - C.Epsilon); // } //} #endregion } else //SigmaNormalClassifier ではない場合 { //if( C.Exp < Configuration.Beta )//9-23 張 ここscript は exp<Beta if (C.Exp < Configuration.Beta) { C.Epsilon += (Math.Abs(P - C.P) - C.Epsilon) / C.Exp; } else { C.Epsilon += Configuration.Beta * (Math.Abs(P - C.P) - C.Epsilon); } } } this.UpdateFitness(); if (Configuration.DoActionSetSubsumption) { this.Subsumption(Pop); } }
//学習終了後に圧縮にする public override void Compact() { List <Classifier> copyActionSet = new List <Classifier>(); foreach (Classifier classifier in CList) { copyActionSet.Add(classifier); } int N = copyActionSet.Count; for (int i = 0; i < N; i++) { #region subsume Classifier Cl = null; //なかに最も一般的な分類子をClにする foreach (Classifier C in copyActionSet) { if (C.CouldSubsume()) { if ((Cl == null) || (C.C.NumberOfSharp > Cl.C.NumberOfSharp) || ((C.C.NumberOfSharp == Cl.C.NumberOfSharp) && (Configuration.MT.NextDouble() < 0.5))) { Cl = C; } } } //Cl が包摂できる分類子を吸収する if (Cl != null) { // 削除中にforeachできない List <Classifier> CL = new List <Classifier>(); foreach (Classifier C in copyActionSet) { if (Cl.IsMoreGeneral(C)) { SigmaNormalClassifier Snc_ko = (SigmaNormalClassifier)C; SigmaNormalClassifier Snc_oya = (SigmaNormalClassifier)Cl; //10の数字は適当 可変にするか? 1/10にする 10-7 あんまり変わらない //分散が同じの判断基準 他に??t test を使う 予定 特殊化がでない // //double t = (Snc_oya.M - Snc_ko.M)/Math.Sqrt(Snc_oya.S/30 + Snc_ko.S/30); //double studentT = StudentT.InvCDF(0, 1, 60, 0.005); //if (t < studentT || t > Math.Abs(studentT))//t test で有意差がある 包摂しない //{ //} // else//有意差がない 統合しでもよい ただ 特殊化ルールどう識別するか //{ if (/*Math.Abs(Cl.M - C.M) < 10 &&*/ // Math.Abs(Cl.Epsilon_0 - C.Epsilon_0)< 10&& // Cl.Kappa == 1 //&& Snc_oya.Epsilon < Snc_ko.Epsilon (Cl.Epsilon_0 < C.Epsilon_0 || Math.Abs(Cl.Epsilon_0 - C.Epsilon_0) < Cl.Epsilon_0 / 10) //&& Math.Abs(Cl.Epsilon_0 - C.Epsilon_0) < 10//case 1 +- 10 // Cl.Epsilon < C.Epsilon && Snc_ko.IsConvergenceEpsilon() && Snc_oya.IsConvergenceEpsilon() ) // { Cl.N += C.N; // 包摂された、削除したいClassifier C をCLに登録 CL.Add(C); } // } } } foreach (Classifier C in CL) { this.Remove(C);//包摂された分類子 C を pop からCを削除 } } //最も一般化されるもの copyActionSetからを削除 copyActionSet.Remove(Cl); #endregion } }
// 包摂 protected override void Subsumption(Population Pop) { List <Classifier> copyActionSet = new List <Classifier>(); foreach (Classifier classifier in CList) { copyActionSet.Add(classifier); } int N = copyActionSet.Count; //最大N回実行する //for (int i = 0; i < N; i++) //{ #region subsume Classifier Cl = null; //actionsetなかに最も一般的な分類子をClにする foreach (Classifier C in copyActionSet) { if (C.CouldSubsume()) { if ((Cl == null) || (C.C.NumberOfSharp > Cl.C.NumberOfSharp) || ((C.C.NumberOfSharp == Cl.C.NumberOfSharp) && (Configuration.MT.NextDouble() < 0.5))) { Cl = C; } } } if (Cl != null) { // 削除中にforeachできない List <Classifier> CL = new List <Classifier>(); // 包摂された、削除したいClassifier C をCLに登録 foreach (Classifier C in copyActionSet) { if (Cl.IsMoreGeneral(C)) { SigmaNormalClassifier Snc_ko = (SigmaNormalClassifier)C; SigmaNormalClassifier Snc_oya = (SigmaNormalClassifier)Cl; // e0 の値を3位まで見る、近いものは差がないとみなす var subsumer = Math.Round(Cl.Epsilon_0, 3); var subsumed = Math.Round(C.Epsilon_0, 3); if ((subsumer <= (subsumed + subsumer / 10)) && Snc_ko.IsConvergenceEpsilon() && Snc_oya.IsConvergenceEpsilon() ) { Cl.N += C.N; CL.Add(C); } } } foreach (Classifier C in CL) { SigmaNormalClassifier SNC = (SigmaNormalClassifier)Cl; if (C.C.state[4] == '0' & C.C.state[7] == '1') //"bath0 rehabi1" { Configuration.Problem.WriteLine(C.C.state + "," + Configuration.T + "," + C.P + "," + C.M + "," + C.Epsilon + "," + C.F + "," + C.N + "," + C.Exp + "," + C.Ts + "," + C.As + "," + C.Kappa + "," + C.Epsilon_0 + "," + C.St + "," + C.GenerateTime + ", in AS"); } this.Remove(C); //as から削除 Pop.Remove(C); //pop から削除 } //いまの最も一般化されたものを削除する //copyActionSet.Remove(Cl); } #endregion //} }