質問編集履歴

4

2019/10/04 05:42

投稿

pontyo
pontyo

スコア13

test CHANGED
File without changes
test CHANGED
@@ -1,599 +1 @@
1
- ```C++
2
-
3
- #include <iostream>
4
-
5
- #include<fstream>
6
-
7
- #include<sstream>
8
-
9
- #include<cmath>
10
-
11
- #include<stdio.h>
12
-
13
- #include<stdlib.h>
14
-
15
- //データ数
16
-
17
- #define N 61
18
-
19
- //次元数
20
-
21
- #define N_d 2
22
-
23
- //クラス数
24
-
25
- #define N_c 3
26
-
27
- //個体群サイズ(ルール数)
28
-
29
- #define N_rp 16
30
-
31
- using namespace std;
32
-
33
- class Fuzzy {
34
-
35
- public:
36
-
37
- //コンストラクタ
38
-
39
- Fuzzy() {
40
-
41
- //ファジィルール初期化
42
-
43
- int i = 0;
44
-
45
- int j = 0;
46
-
47
- rule[0][0] = 1;
48
-
49
- rule[1][0] = 1;
50
-
51
- rule[2][0] = 1;
52
-
53
- rule[3][0] = 1;
54
-
55
- rule[4][0] = 2;
56
-
57
- rule[5][0] = 2;
58
-
59
- rule[6][0] = 2;
60
-
61
- rule[7][0] = 2;
62
-
63
- rule[8][0] = 3;
64
-
65
- rule[9][0] = 3;
66
-
67
- rule[10][0] = 3;
68
-
69
- rule[11][0] = 3;
70
-
71
- rule[12][0] = 0;
72
-
73
- rule[13][0] = 0;
74
-
75
- rule[14][0] = 0;
76
-
77
- rule[15][0] = 0;
78
-
79
- rule[0][1] = 1;
80
-
81
- rule[1][1] = 2;
82
-
83
- rule[2][1] = 3;
84
-
85
- rule[3][1] = 0;
86
-
87
- rule[4][1] = 1;
88
-
89
- rule[5][1] = 2;
90
-
91
- rule[6][1] = 3;
92
-
93
- rule[7][1] = 0;
94
-
95
- rule[8][1] = 1;
96
-
97
- rule[9][1] = 2;
98
-
99
- rule[10][1] = 3;
100
-
101
- rule[11][1] = 0;
102
-
103
- rule[12][1] = 1;
104
-
105
- rule[13][1] = 2;
106
-
107
- rule[14][1] = 3;
108
-
109
- rule[15][1] = 0;
110
-
111
- //ルール選択配列初期化
112
-
113
- for (int i = 0; i<N_rp; i++) {
114
-
115
- rule_select[i] = 1;
116
-
117
- rule_select_2[i] = 1;
118
-
119
- }
120
-
121
- fitness = 0;
122
-
123
- }
124
-
125
- //学習用データの読み込み
126
-
127
- void read_data() {
128
-
129
-
130
-
131
- double data1x[N][N_d];
132
-
133
- double x1[N]; //臨時配列(パターン1)
134
-
135
- double x2[N]; //臨時配列(パターン1)
136
-
137
- int c11[N]; //臨時配列(パターン1)
138
-
139
- int i = 0;
140
-
141
- FILE *fp1;
142
-
143
- errno_t error1;
144
-
145
- if ((error1 = fopen_s(&fp1, "kadai3_pattern1.txt", "r")) != 0) {
146
-
147
- printf("cannot open the file\n");
148
-
149
- }
150
-
151
- else {
152
-
153
- while (fscanf_s(fp1, "%lf,%lf,%d", &x1[i], &x2[i], &c11[i]) != EOF) {
154
-
155
- data[i][0] = x1[i];
156
-
157
- data[i][1] = x2[i];
158
-
159
- data[i][2] = (double)c11[i];
160
-
161
- i++;
162
-
163
- }
164
-
165
- }
166
-
167
- fclose(fp1);
168
-
169
- //データの格納終了
170
-
171
- }
172
-
173
- //適合度計算
174
-
175
- void calc_fit() {
176
-
177
- double a, tmp, fit;
178
-
179
- for (int h = 0; h < N_rp; h++) {
180
-
181
- for (int i = 1; i <= N; i++) {
182
-
183
- fit = 1;
184
-
185
- //各ルールでの各データパターンでの適合度計算
186
-
187
- for (int j = 0; j < N_d; j++) {
188
-
189
- //don't care ならメンバシップ値は1
190
-
191
- if ((int)rule[h][j] == 0)continue;
192
-
193
- a = (double)(rule[h][j] - 1) / 2;
194
-
195
- tmp = 1 - 2 * abs(a - data[i][j]);
196
-
197
- if (tmp > 0) {
198
-
199
- fit *= tmp;
200
-
201
- }
202
-
203
- else {
204
-
205
- fit = 0;
206
-
207
- break;
208
-
209
- }
210
-
211
- }
212
-
213
- rule_fit[h][i - 1] = fit;
214
-
215
- }
216
-
217
- }
218
-
219
- }
220
-
221
- //信頼度計算
222
-
223
- void calc_trust() {
224
-
225
- //適合度の和を入れる tmp2はクラスhを指すデータの適合度の和
226
-
227
- double tmp, tmp2;
228
-
229
- for (int k = 0; k < N_rp; k++) {
230
-
231
- //クラスは3種
232
-
233
- for (int i = 0; i < 3; i++) {
234
-
235
- tmp = 0;
236
-
237
- tmp2 = 0;
238
-
239
- for (int j = 1; j <= N; j++) {
240
-
241
- if ((int)data[j][2] == i) {
242
-
243
- tmp2 += rule_fit[k][j - 1];
244
-
245
- }
246
-
247
- tmp += rule_fit[k][j - 1];
248
-
249
- }
250
-
251
- rule_class[k][i] = tmp2 / tmp;
252
-
253
- }
254
-
255
- }
256
-
257
- }
258
-
259
- //各ルール結論クラス決定
260
-
261
- void calc_class() {
262
-
263
- double tmp;
264
-
265
- int tmp_class;
266
-
267
- for (int i = 0; i <N_rp; i++) {
268
-
269
- tmp = rule_class[i][0];
270
-
271
- tmp_class = 0;
272
-
273
- //最も信頼度の高いクラスに決定
274
-
275
- for (int j = 1; j <3; j++) {
276
-
277
- if (tmp < rule_class[i][j]) {
278
-
279
- tmp = rule_class[i][j];
280
-
281
- tmp_class = j;
282
-
283
- }
284
-
285
- }
286
-
287
- //結論部クラス決定
288
-
289
- rule[i][2] = tmp_class;
290
-
291
- //ルール重み計算
292
-
293
- for (int j = 0; j <3; j++) {
294
-
295
- if (j != tmp_class) {
296
-
297
- tmp -= rule_class[i][j];
298
-
299
- }
300
-
301
- //ルール重みが0以下ならそのルールは不要
302
-
303
- if (tmp <= 0) {
304
-
305
- rule[i][4] = 0;
306
-
307
- break;
308
-
309
- }
310
-
311
- rule[i][3] = tmp;
312
-
313
- }
314
-
315
- }
316
-
317
- }
318
-
319
- //総ルール長とルール数の計算
320
-
321
- void count_rule() {
322
-
323
- rule_len = 0;
324
-
325
- rule_num = 0;
326
-
327
- for (int i = 0; i<N_rp; i++) {
328
-
329
- if ((int)rule[i][4] == 1 && rule_select[i] == 1) {
330
-
331
- if ((int)rule[i][0] != 0)rule_len++;
332
-
333
- rule_num++;
334
-
335
- if ((int)rule[i][1] != 0)rule_len++;
336
-
337
- }
338
-
339
- }
340
-
341
- }
342
-
343
- //識別率計算
344
-
345
- void calc_ans() {
346
-
347
- double tmp;
348
-
349
- //異なる結論クラスを持つが適合度とルール重みの和が等しくなった時にチェック
350
-
351
- bool check = false;
352
-
353
- //それぞれ正解した数、合計数
354
-
355
- int collect_num = 0;
356
-
357
- int sum = 0;
358
-
359
- double win_tmp = 0;
360
-
361
- int win_num = 0;
362
-
363
- for (int j = 1; j <= 60; j++) {
364
-
365
- win_tmp = 0;
366
-
367
- win_num = 0;
368
-
369
- check = false;
370
-
371
- for (int i = 0; i < N_rp; i++) {
372
-
373
- //勝者ルールの決定
374
-
375
- //不使用ルール
376
-
377
- if ((int)rule[i][4] == 0 || rule_select[i] == 0)continue;
378
-
379
- tmp = rule[i][3] * rule_fit[i][j - 1];
380
-
381
- if (win_tmp < tmp) {
382
-
383
- win_tmp = tmp;
384
-
385
- win_num = i;
386
-
387
- check = false;
388
-
389
- }
390
-
391
- else if (tmp == 0)continue;
392
-
393
- else if ((win_tmp == tmp) && (rule[win_num][2] != rule[i][2])) check = true;
394
-
395
- }
396
-
397
- //勝者ルールでの識別
398
-
399
- if (check == true)continue;
400
-
401
- else if (data[j][2] == rule[win_num][2])collect_num++;
402
-
403
- sum++;
404
-
405
- }
406
-
407
- ans_rate = collect_num / (double)sum;
408
-
409
- }
410
-
411
- //識別率、総ルール数、ルール長の表示
412
-
413
- void show1() {
414
-
415
- cout << "calc:" << ans_rate << endl;
416
-
417
- cout << "rule_num:" << rule_num << endl;
418
-
419
- cout << "rule_len:" << rule_len << endl;
420
-
421
- }
422
-
423
- //識別率、総ルール数、ルール長の表示
424
-
425
- void show2() {
426
-
427
- cout << "calc:" << ans_rate_2 << endl;
428
-
429
- cout << "rule_num:" << rule_num_2 << endl;
430
-
431
- cout << "rule_len:" << rule_len_2 << endl;
432
-
433
- }
434
-
435
- //ファジィルール集合選択
436
-
437
- void create_rule(int num) {
438
-
439
- if (num == 0) {
440
-
441
- for (int i = 0; i < 2; i++) {
442
-
443
- rule_select[num] = i;
444
-
445
- //識別率の計算
446
-
447
- calc_ans();
448
-
449
- //ルール数と相ルール長の計算
450
-
451
- count_rule();
452
-
453
- //加重和適応度の計算
454
-
455
- if ((1000 * ans_rate - rule_num - rule_len) > fitness) {
456
-
457
- fitness = 1000 * ans_rate - rule_num - rule_len;
458
-
459
- ans_rate_2 = ans_rate;
460
-
461
- rule_len_2 = rule_len;
462
-
463
- rule_num_2 = rule_num;
464
-
465
- for (int j = 0; j<N_rp; j++) {
466
-
467
- rule_select_2[j] = rule_select[j];
468
-
469
- }
470
-
471
- }
472
-
473
- }
474
-
475
- }
476
-
477
- else {
478
-
479
- for (int i = 0; i<2; i++) {
480
-
481
- rule_select[num] = i;
482
-
483
- create_rule(num - 1);
484
-
485
- }
486
-
487
- }
488
-
489
- }
490
-
491
- protected:
492
-
493
- ///////////////////データ読み込みに関するメンバ
494
-
495
- //学習データ格納 要素,クラスの順 0行目は入力データの情報 1行目からデータ
496
-
497
- double data[N][N_d + 1];
498
-
499
- //ルール配列 条件ファジイ集合,結論クラス,ルール重み、利用bitの順 利用bitが1ならそのルールは使用しない
500
-
501
- double rule[N_rp][5];
502
-
503
- //各ルールの適合度計算
504
-
505
- double rule_fit[N_rp][N];
506
-
507
- //各ルールの信頼度計算
508
-
509
- double rule_class[N_rp][3];
510
-
511
- //ルール数
512
-
513
- int rule_num;
514
-
515
- //総ルール長
516
-
517
- int rule_len;
518
-
519
- //識別率
520
-
521
- double ans_rate;
522
-
523
- //ルール集合選択配列
524
-
525
- int rule_select[N_rp];
526
-
527
- //加重和適応度
528
-
529
- double fitness;
530
-
531
- //ルール集合選択後の結果
532
-
533
- //ルール数
534
-
535
- int rule_num_2;
536
-
537
- //総ルール長
538
-
539
- int rule_len_2;
540
-
541
- //識別率
542
-
543
- double ans_rate_2;
544
-
545
- //ルール集合選択配列
546
-
547
- int rule_select_2[N_rp];
548
-
549
- };
550
-
551
- int main() {
552
-
553
- ////////////////準備///////////////////////
554
-
555
- //オブジェクト生成
556
-
557
- Fuzzy fuzzy;
558
-
559
- //学習データ読み込み
560
-
561
- fuzzy.read_data();
562
-
563
- /////////////////////学習開始/////////////////////////
564
-
565
- ////適合度計算
566
-
567
- fuzzy.calc_fit();
568
-
569
- ////信頼度計算
570
-
571
- fuzzy.calc_trust();
572
-
573
- ////結論部クラス決定、ルール重み計算
574
-
575
- fuzzy.calc_class();
576
-
577
- fuzzy.count_rule();
578
-
579
- ////////////未知パターン識別////////////////
580
-
581
- ////識別率計算
582
-
583
- fuzzy.calc_ans();
584
-
585
- fuzzy.show1();
586
-
587
- ////ファジィルール選択
588
-
589
- fuzzy.create_rule(15);
590
-
591
- fuzzy.show2();
592
-
593
- return 0;
594
-
595
- }
596
-
597
- ```
598
-
599
1
  識別器をC++で作成しています。show1,show2関数で識別率、ルール数、総ルール長を表示するようにしています。実行結果は、show1では、順に91.667,0,0となり、show2では93.0,0,0となりました。識別率に関しては正解データと一致しました。

3

2019/10/04 05:42

投稿

pontyo
pontyo

スコア13

test CHANGED
@@ -1 +1 @@
1
- ファジィ識別器について
1
+ 識別器について、精度向上
test CHANGED
@@ -596,4 +596,4 @@
596
596
 
597
597
  ```
598
598
 
599
- ファジィ識別器をC++で作成しています。show1,show2関数で識別率、ルール数、総ルール長を表示するようにしています。実行結果は、show1では、順に91.667,0,0となり、show2では93.0,0,0となりました。識別率に関しては正解データと一致しました。ただ、ルール数と総ルール長はshow1に関しては13,22で、show2に関しては5,8が正解となります。どこで間違っているのかがよく分からないのでよろしければ教えてください。
599
+ 識別器をC++で作成しています。show1,show2関数で識別率、ルール数、総ルール長を表示するようにしています。実行結果は、show1では、順に91.667,0,0となり、show2では93.0,0,0となりました。識別率に関しては正解データと一致しました。

2

削除された内容の復元を行いました

2019/03/30 18:17

投稿

pontyo
pontyo

スコア13

test CHANGED
File without changes
test CHANGED
@@ -1 +1,599 @@
1
- ファジィ識別器。ファジィ識別器ファジィ識別器ファジィ識別器ファジィ識別器
1
+ ```C++
2
+
3
+ #include <iostream>
4
+
5
+ #include<fstream>
6
+
7
+ #include<sstream>
8
+
9
+ #include<cmath>
10
+
11
+ #include<stdio.h>
12
+
13
+ #include<stdlib.h>
14
+
15
+ //データ数
16
+
17
+ #define N 61
18
+
19
+ //次元数
20
+
21
+ #define N_d 2
22
+
23
+ //クラス数
24
+
25
+ #define N_c 3
26
+
27
+ //個体群サイズ(ルール数)
28
+
29
+ #define N_rp 16
30
+
31
+ using namespace std;
32
+
33
+ class Fuzzy {
34
+
35
+ public:
36
+
37
+ //コンストラクタ
38
+
39
+ Fuzzy() {
40
+
41
+ //ファジィルール初期化
42
+
43
+ int i = 0;
44
+
45
+ int j = 0;
46
+
47
+ rule[0][0] = 1;
48
+
49
+ rule[1][0] = 1;
50
+
51
+ rule[2][0] = 1;
52
+
53
+ rule[3][0] = 1;
54
+
55
+ rule[4][0] = 2;
56
+
57
+ rule[5][0] = 2;
58
+
59
+ rule[6][0] = 2;
60
+
61
+ rule[7][0] = 2;
62
+
63
+ rule[8][0] = 3;
64
+
65
+ rule[9][0] = 3;
66
+
67
+ rule[10][0] = 3;
68
+
69
+ rule[11][0] = 3;
70
+
71
+ rule[12][0] = 0;
72
+
73
+ rule[13][0] = 0;
74
+
75
+ rule[14][0] = 0;
76
+
77
+ rule[15][0] = 0;
78
+
79
+ rule[0][1] = 1;
80
+
81
+ rule[1][1] = 2;
82
+
83
+ rule[2][1] = 3;
84
+
85
+ rule[3][1] = 0;
86
+
87
+ rule[4][1] = 1;
88
+
89
+ rule[5][1] = 2;
90
+
91
+ rule[6][1] = 3;
92
+
93
+ rule[7][1] = 0;
94
+
95
+ rule[8][1] = 1;
96
+
97
+ rule[9][1] = 2;
98
+
99
+ rule[10][1] = 3;
100
+
101
+ rule[11][1] = 0;
102
+
103
+ rule[12][1] = 1;
104
+
105
+ rule[13][1] = 2;
106
+
107
+ rule[14][1] = 3;
108
+
109
+ rule[15][1] = 0;
110
+
111
+ //ルール選択配列初期化
112
+
113
+ for (int i = 0; i<N_rp; i++) {
114
+
115
+ rule_select[i] = 1;
116
+
117
+ rule_select_2[i] = 1;
118
+
119
+ }
120
+
121
+ fitness = 0;
122
+
123
+ }
124
+
125
+ //学習用データの読み込み
126
+
127
+ void read_data() {
128
+
129
+
130
+
131
+ double data1x[N][N_d];
132
+
133
+ double x1[N]; //臨時配列(パターン1)
134
+
135
+ double x2[N]; //臨時配列(パターン1)
136
+
137
+ int c11[N]; //臨時配列(パターン1)
138
+
139
+ int i = 0;
140
+
141
+ FILE *fp1;
142
+
143
+ errno_t error1;
144
+
145
+ if ((error1 = fopen_s(&fp1, "kadai3_pattern1.txt", "r")) != 0) {
146
+
147
+ printf("cannot open the file\n");
148
+
149
+ }
150
+
151
+ else {
152
+
153
+ while (fscanf_s(fp1, "%lf,%lf,%d", &x1[i], &x2[i], &c11[i]) != EOF) {
154
+
155
+ data[i][0] = x1[i];
156
+
157
+ data[i][1] = x2[i];
158
+
159
+ data[i][2] = (double)c11[i];
160
+
161
+ i++;
162
+
163
+ }
164
+
165
+ }
166
+
167
+ fclose(fp1);
168
+
169
+ //データの格納終了
170
+
171
+ }
172
+
173
+ //適合度計算
174
+
175
+ void calc_fit() {
176
+
177
+ double a, tmp, fit;
178
+
179
+ for (int h = 0; h < N_rp; h++) {
180
+
181
+ for (int i = 1; i <= N; i++) {
182
+
183
+ fit = 1;
184
+
185
+ //各ルールでの各データパターンでの適合度計算
186
+
187
+ for (int j = 0; j < N_d; j++) {
188
+
189
+ //don't care ならメンバシップ値は1
190
+
191
+ if ((int)rule[h][j] == 0)continue;
192
+
193
+ a = (double)(rule[h][j] - 1) / 2;
194
+
195
+ tmp = 1 - 2 * abs(a - data[i][j]);
196
+
197
+ if (tmp > 0) {
198
+
199
+ fit *= tmp;
200
+
201
+ }
202
+
203
+ else {
204
+
205
+ fit = 0;
206
+
207
+ break;
208
+
209
+ }
210
+
211
+ }
212
+
213
+ rule_fit[h][i - 1] = fit;
214
+
215
+ }
216
+
217
+ }
218
+
219
+ }
220
+
221
+ //信頼度計算
222
+
223
+ void calc_trust() {
224
+
225
+ //適合度の和を入れる tmp2はクラスhを指すデータの適合度の和
226
+
227
+ double tmp, tmp2;
228
+
229
+ for (int k = 0; k < N_rp; k++) {
230
+
231
+ //クラスは3種
232
+
233
+ for (int i = 0; i < 3; i++) {
234
+
235
+ tmp = 0;
236
+
237
+ tmp2 = 0;
238
+
239
+ for (int j = 1; j <= N; j++) {
240
+
241
+ if ((int)data[j][2] == i) {
242
+
243
+ tmp2 += rule_fit[k][j - 1];
244
+
245
+ }
246
+
247
+ tmp += rule_fit[k][j - 1];
248
+
249
+ }
250
+
251
+ rule_class[k][i] = tmp2 / tmp;
252
+
253
+ }
254
+
255
+ }
256
+
257
+ }
258
+
259
+ //各ルール結論クラス決定
260
+
261
+ void calc_class() {
262
+
263
+ double tmp;
264
+
265
+ int tmp_class;
266
+
267
+ for (int i = 0; i <N_rp; i++) {
268
+
269
+ tmp = rule_class[i][0];
270
+
271
+ tmp_class = 0;
272
+
273
+ //最も信頼度の高いクラスに決定
274
+
275
+ for (int j = 1; j <3; j++) {
276
+
277
+ if (tmp < rule_class[i][j]) {
278
+
279
+ tmp = rule_class[i][j];
280
+
281
+ tmp_class = j;
282
+
283
+ }
284
+
285
+ }
286
+
287
+ //結論部クラス決定
288
+
289
+ rule[i][2] = tmp_class;
290
+
291
+ //ルール重み計算
292
+
293
+ for (int j = 0; j <3; j++) {
294
+
295
+ if (j != tmp_class) {
296
+
297
+ tmp -= rule_class[i][j];
298
+
299
+ }
300
+
301
+ //ルール重みが0以下ならそのルールは不要
302
+
303
+ if (tmp <= 0) {
304
+
305
+ rule[i][4] = 0;
306
+
307
+ break;
308
+
309
+ }
310
+
311
+ rule[i][3] = tmp;
312
+
313
+ }
314
+
315
+ }
316
+
317
+ }
318
+
319
+ //総ルール長とルール数の計算
320
+
321
+ void count_rule() {
322
+
323
+ rule_len = 0;
324
+
325
+ rule_num = 0;
326
+
327
+ for (int i = 0; i<N_rp; i++) {
328
+
329
+ if ((int)rule[i][4] == 1 && rule_select[i] == 1) {
330
+
331
+ if ((int)rule[i][0] != 0)rule_len++;
332
+
333
+ rule_num++;
334
+
335
+ if ((int)rule[i][1] != 0)rule_len++;
336
+
337
+ }
338
+
339
+ }
340
+
341
+ }
342
+
343
+ //識別率計算
344
+
345
+ void calc_ans() {
346
+
347
+ double tmp;
348
+
349
+ //異なる結論クラスを持つが適合度とルール重みの和が等しくなった時にチェック
350
+
351
+ bool check = false;
352
+
353
+ //それぞれ正解した数、合計数
354
+
355
+ int collect_num = 0;
356
+
357
+ int sum = 0;
358
+
359
+ double win_tmp = 0;
360
+
361
+ int win_num = 0;
362
+
363
+ for (int j = 1; j <= 60; j++) {
364
+
365
+ win_tmp = 0;
366
+
367
+ win_num = 0;
368
+
369
+ check = false;
370
+
371
+ for (int i = 0; i < N_rp; i++) {
372
+
373
+ //勝者ルールの決定
374
+
375
+ //不使用ルール
376
+
377
+ if ((int)rule[i][4] == 0 || rule_select[i] == 0)continue;
378
+
379
+ tmp = rule[i][3] * rule_fit[i][j - 1];
380
+
381
+ if (win_tmp < tmp) {
382
+
383
+ win_tmp = tmp;
384
+
385
+ win_num = i;
386
+
387
+ check = false;
388
+
389
+ }
390
+
391
+ else if (tmp == 0)continue;
392
+
393
+ else if ((win_tmp == tmp) && (rule[win_num][2] != rule[i][2])) check = true;
394
+
395
+ }
396
+
397
+ //勝者ルールでの識別
398
+
399
+ if (check == true)continue;
400
+
401
+ else if (data[j][2] == rule[win_num][2])collect_num++;
402
+
403
+ sum++;
404
+
405
+ }
406
+
407
+ ans_rate = collect_num / (double)sum;
408
+
409
+ }
410
+
411
+ //識別率、総ルール数、ルール長の表示
412
+
413
+ void show1() {
414
+
415
+ cout << "calc:" << ans_rate << endl;
416
+
417
+ cout << "rule_num:" << rule_num << endl;
418
+
419
+ cout << "rule_len:" << rule_len << endl;
420
+
421
+ }
422
+
423
+ //識別率、総ルール数、ルール長の表示
424
+
425
+ void show2() {
426
+
427
+ cout << "calc:" << ans_rate_2 << endl;
428
+
429
+ cout << "rule_num:" << rule_num_2 << endl;
430
+
431
+ cout << "rule_len:" << rule_len_2 << endl;
432
+
433
+ }
434
+
435
+ //ファジィルール集合選択
436
+
437
+ void create_rule(int num) {
438
+
439
+ if (num == 0) {
440
+
441
+ for (int i = 0; i < 2; i++) {
442
+
443
+ rule_select[num] = i;
444
+
445
+ //識別率の計算
446
+
447
+ calc_ans();
448
+
449
+ //ルール数と相ルール長の計算
450
+
451
+ count_rule();
452
+
453
+ //加重和適応度の計算
454
+
455
+ if ((1000 * ans_rate - rule_num - rule_len) > fitness) {
456
+
457
+ fitness = 1000 * ans_rate - rule_num - rule_len;
458
+
459
+ ans_rate_2 = ans_rate;
460
+
461
+ rule_len_2 = rule_len;
462
+
463
+ rule_num_2 = rule_num;
464
+
465
+ for (int j = 0; j<N_rp; j++) {
466
+
467
+ rule_select_2[j] = rule_select[j];
468
+
469
+ }
470
+
471
+ }
472
+
473
+ }
474
+
475
+ }
476
+
477
+ else {
478
+
479
+ for (int i = 0; i<2; i++) {
480
+
481
+ rule_select[num] = i;
482
+
483
+ create_rule(num - 1);
484
+
485
+ }
486
+
487
+ }
488
+
489
+ }
490
+
491
+ protected:
492
+
493
+ ///////////////////データ読み込みに関するメンバ
494
+
495
+ //学習データ格納 要素,クラスの順 0行目は入力データの情報 1行目からデータ
496
+
497
+ double data[N][N_d + 1];
498
+
499
+ //ルール配列 条件ファジイ集合,結論クラス,ルール重み、利用bitの順 利用bitが1ならそのルールは使用しない
500
+
501
+ double rule[N_rp][5];
502
+
503
+ //各ルールの適合度計算
504
+
505
+ double rule_fit[N_rp][N];
506
+
507
+ //各ルールの信頼度計算
508
+
509
+ double rule_class[N_rp][3];
510
+
511
+ //ルール数
512
+
513
+ int rule_num;
514
+
515
+ //総ルール長
516
+
517
+ int rule_len;
518
+
519
+ //識別率
520
+
521
+ double ans_rate;
522
+
523
+ //ルール集合選択配列
524
+
525
+ int rule_select[N_rp];
526
+
527
+ //加重和適応度
528
+
529
+ double fitness;
530
+
531
+ //ルール集合選択後の結果
532
+
533
+ //ルール数
534
+
535
+ int rule_num_2;
536
+
537
+ //総ルール長
538
+
539
+ int rule_len_2;
540
+
541
+ //識別率
542
+
543
+ double ans_rate_2;
544
+
545
+ //ルール集合選択配列
546
+
547
+ int rule_select_2[N_rp];
548
+
549
+ };
550
+
551
+ int main() {
552
+
553
+ ////////////////準備///////////////////////
554
+
555
+ //オブジェクト生成
556
+
557
+ Fuzzy fuzzy;
558
+
559
+ //学習データ読み込み
560
+
561
+ fuzzy.read_data();
562
+
563
+ /////////////////////学習開始/////////////////////////
564
+
565
+ ////適合度計算
566
+
567
+ fuzzy.calc_fit();
568
+
569
+ ////信頼度計算
570
+
571
+ fuzzy.calc_trust();
572
+
573
+ ////結論部クラス決定、ルール重み計算
574
+
575
+ fuzzy.calc_class();
576
+
577
+ fuzzy.count_rule();
578
+
579
+ ////////////未知パターン識別////////////////
580
+
581
+ ////識別率計算
582
+
583
+ fuzzy.calc_ans();
584
+
585
+ fuzzy.show1();
586
+
587
+ ////ファジィルール選択
588
+
589
+ fuzzy.create_rule(15);
590
+
591
+ fuzzy.show2();
592
+
593
+ return 0;
594
+
595
+ }
596
+
597
+ ```
598
+
599
+ ファジィ識別器をC++で作成しています。show1,show2関数で識別率、ルール数、総ルール長を表示するようにしています。実行結果は、show1では、順に91.667,0,0となり、show2では93.0,0,0となりました。識別率に関しては正解データと一致しました。ただ、ルール数と総ルール長はshow1に関しては13,22で、show2に関しては5,8が正解となります。どこで間違っているのかがよく分からないのでよろしければ教えてください。

1

2018/01/23 02:13

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,709 +1 @@
1
- ```C++
2
-
3
-
4
-
5
- #include <iostream>
6
-
7
- #include<fstream>
8
-
9
- #include<sstream>
10
-
11
- #include<cmath>
12
-
13
- #include<stdio.h>
14
-
15
- #include<stdlib.h>
16
-
17
-
18
-
19
- //データ数
20
-
21
- #define N 61
22
-
23
- //次元数
24
-
25
- #define N_d 2
26
-
27
- //クラス数
28
-
29
- #define N_c 3
30
-
31
- //個体群サイズ(ルール数)
32
-
33
- #define N_rp 16
34
-
35
-
36
-
37
- using namespace std;
38
-
39
-
40
-
41
-
42
-
43
- class Fuzzy {
44
-
45
- public:
46
-
47
- //コンストラクタ
48
-
49
- Fuzzy() {
50
-
51
-
52
-
53
- //ファジィルール初期化
54
-
55
- int i = 0;
56
-
57
- int j = 0;
58
-
59
- rule[0][0] = 1;
60
-
61
- rule[1][0] = 1;
62
-
63
- rule[2][0] = 1;
64
-
65
- rule[3][0] = 1;
66
-
67
- rule[4][0] = 2;
68
-
69
- rule[5][0] = 2;
70
-
71
- rule[6][0] = 2;
72
-
73
- rule[7][0] = 2;
74
-
75
- rule[8][0] = 3;
76
-
77
- rule[9][0] = 3;
78
-
79
- rule[10][0] = 3;
80
-
81
- rule[11][0] = 3;
82
-
83
- rule[12][0] = 0;
84
-
85
- rule[13][0] = 0;
86
-
87
- rule[14][0] = 0;
88
-
89
- rule[15][0] = 0;
90
-
91
- rule[0][1] = 1;
92
-
93
- rule[1][1] = 2;
94
-
95
- rule[2][1] = 3;
96
-
97
- rule[3][1] = 0;
98
-
99
- rule[4][1] = 1;
100
-
101
- rule[5][1] = 2;
102
-
103
- rule[6][1] = 3;
104
-
105
- rule[7][1] = 0;
106
-
107
- rule[8][1] = 1;
108
-
109
- rule[9][1] = 2;
110
-
111
- rule[10][1] = 3;
112
-
113
- rule[11][1] = 0;
114
-
115
- rule[12][1] = 1;
116
-
117
- rule[13][1] = 2;
118
-
119
- rule[14][1] = 3;
120
-
121
- rule[15][1] = 0;
122
-
123
-
124
-
125
- //ルール選択配列初期化
126
-
127
- for (int i = 0; i<N_rp; i++) {
128
-
129
- rule_select[i] = 1;
130
-
131
- rule_select_2[i] = 1;
132
-
133
- }
134
-
135
- fitness = 0;
136
-
137
- }
138
-
139
-
140
-
141
- //学習用データの読み込み
142
-
143
- void read_data() {
144
-
145
-
146
-
147
- double data1x[N][N_d];
148
-
149
- double x1[N]; //臨時配列(パターン1)
150
-
151
- double x2[N]; //臨時配列(パターン1)
152
-
153
- int c11[N]; //臨時配列(パターン1)
154
-
155
- int i = 0;
156
-
157
-
158
-
159
- FILE *fp1;
160
-
161
- errno_t error1;
162
-
163
-
164
-
165
- if ((error1 = fopen_s(&fp1, "kadai3_pattern1.txt", "r")) != 0) {
166
-
167
- printf("cannot open the file\n");
168
-
169
- }
170
-
171
- else {
172
-
173
- while (fscanf_s(fp1, "%lf,%lf,%d", &x1[i], &x2[i], &c11[i]) != EOF) {
174
-
175
- data[i][0] = x1[i];
176
-
177
- data[i][1] = x2[i];
178
-
179
- data[i][2] = (double)c11[i];
180
-
181
- i++;
182
-
183
- }
184
-
185
- }
186
-
187
-
188
-
189
- fclose(fp1);
190
-
191
- //データの格納終了
192
-
193
-
194
-
195
-
196
-
197
- }
198
-
199
-
200
-
201
- //適合度計算
202
-
203
- void calc_fit() {
204
-
205
- double a, tmp, fit;
206
-
207
- for (int h = 0; h < N_rp; h++) {
208
-
209
- for (int i = 1; i <= N; i++) {
210
-
211
- fit = 1;
212
-
213
- //各ルールでの各データパターンでの適合度計算
214
-
215
- for (int j = 0; j < N_d; j++) {
216
-
217
- //don't care ならメンバシップ値は1
218
-
219
- if ((int)rule[h][j] == 0)continue;
220
-
221
- a = (double)(rule[h][j] - 1) / 2;
222
-
223
- tmp = 1 - 2 * abs(a - data[i][j]);
224
-
225
- if (tmp > 0) {
226
-
227
- fit *= tmp;
228
-
229
- }
230
-
231
- else {
232
-
233
- fit = 0;
234
-
235
- break;
236
-
237
- }
238
-
239
- }
240
-
241
- rule_fit[h][i - 1] = fit;
242
-
243
-
244
-
245
- }
246
-
247
- }
248
-
249
- }
250
-
251
-
252
-
253
- //信頼度計算
254
-
255
- void calc_trust() {
256
-
257
- //適合度の和を入れる tmp2はクラスhを指すデータの適合度の和
258
-
259
- double tmp, tmp2;
260
-
261
- for (int k = 0; k < N_rp; k++) {
262
-
263
- //クラスは3種
264
-
265
- for (int i = 0; i < 3; i++) {
266
-
267
- tmp = 0;
268
-
269
- tmp2 = 0;
270
-
271
- for (int j = 1; j <= N; j++) {
272
-
273
-
274
-
275
- if ((int)data[j][2] == i) {
276
-
277
- tmp2 += rule_fit[k][j - 1];
278
-
279
- }
280
-
281
- tmp += rule_fit[k][j - 1];
282
-
283
- }
284
-
285
- rule_class[k][i] = tmp2 / tmp;
286
-
287
- }
288
-
289
- }
290
-
291
- }
292
-
293
-
294
-
295
- //各ルール結論クラス決定
296
-
297
- void calc_class() {
298
-
299
- double tmp;
300
-
301
- int tmp_class;
302
-
303
- for (int i = 0; i <N_rp; i++) {
304
-
305
- tmp = rule_class[i][0];
306
-
307
- tmp_class = 0;
308
-
309
- //最も信頼度の高いクラスに決定
310
-
311
- for (int j = 1; j <3; j++) {
312
-
313
- if (tmp < rule_class[i][j]) {
314
-
315
- tmp = rule_class[i][j];
316
-
317
- tmp_class = j;
318
-
319
- }
320
-
321
- }
322
-
323
- //結論部クラス決定
324
-
325
- rule[i][2] = tmp_class;
326
-
327
- //ルール重み計算
328
-
329
- for (int j = 0; j <3; j++) {
330
-
331
- if (j != tmp_class) {
332
-
333
- tmp -= rule_class[i][j];
334
-
335
- }
336
-
337
- //ルール重みが0以下ならそのルールは不要
338
-
339
- if (tmp <= 0) {
340
-
341
- rule[i][4] = 0;
342
-
343
- break;
344
-
345
- }
346
-
347
- rule[i][3] = tmp;
348
-
349
- }
350
-
351
- }
352
-
353
- }
354
-
355
-
356
-
357
-
358
-
359
- //総ルール長とルール数の計算
360
-
361
- void count_rule() {
362
-
363
- rule_len = 0;
364
-
365
- rule_num = 0;
366
-
367
- for (int i = 0; i<N_rp; i++) {
368
-
369
- if ((int)rule[i][4] == 1 && rule_select[i] == 1) {
370
-
371
-
372
-
373
- if ((int)rule[i][0] != 0)rule_len++;
374
-
375
- rule_num++;
376
-
377
- if ((int)rule[i][1] != 0)rule_len++;
378
-
379
- }
380
-
381
- }
382
-
383
- }
384
-
385
-
386
-
387
- //識別率計算
388
-
389
- void calc_ans() {
390
-
391
- double tmp;
392
-
393
- //異なる結論クラスを持つが適合度とルール重みの和が等しくなった時にチェック
394
-
395
- bool check = false;
396
-
397
- //それぞれ正解した数、合計数
398
-
399
- int collect_num = 0;
400
-
401
- int sum = 0;
402
-
403
- double win_tmp = 0;
404
-
405
- int win_num = 0;
406
-
407
- for (int j = 1; j <= 60; j++) {
408
-
409
- win_tmp = 0;
410
-
411
- win_num = 0;
412
-
413
- check = false;
414
-
415
- for (int i = 0; i < N_rp; i++) {
416
-
417
-
418
-
419
- //勝者ルールの決定
420
-
421
-
422
-
423
- //不使用ルール
424
-
425
- if ((int)rule[i][4] == 0 || rule_select[i] == 0)continue;
426
-
427
-
428
-
429
-
430
-
431
- tmp = rule[i][3] * rule_fit[i][j - 1];
432
-
433
- if (win_tmp < tmp) {
434
-
435
- win_tmp = tmp;
436
-
437
- win_num = i;
438
-
439
- check = false;
440
-
441
- }
442
-
443
- else if (tmp == 0)continue;
444
-
445
- else if ((win_tmp == tmp) && (rule[win_num][2] != rule[i][2])) check = true;
446
-
447
- }
448
-
449
- //勝者ルールでの識別
450
-
451
- if (check == true)continue;
452
-
453
- else if (data[j][2] == rule[win_num][2])collect_num++;
454
-
455
- sum++;
456
-
457
- }
458
-
459
- ans_rate = collect_num / (double)sum;
460
-
461
-
462
-
463
- }
464
-
465
-
466
-
467
- //識別率、総ルール数、ルール長の表示
468
-
469
- void show1() {
470
-
471
- cout << "calc:" << ans_rate << endl;
472
-
473
- cout << "rule_num:" << rule_num << endl;
474
-
475
- cout << "rule_len:" << rule_len << endl;
476
-
477
- }
478
-
479
-
480
-
481
- //識別率、総ルール数、ルール長の表示
482
-
483
- void show2() {
484
-
485
- cout << "calc:" << ans_rate_2 << endl;
486
-
487
- cout << "rule_num:" << rule_num_2 << endl;
488
-
489
- cout << "rule_len:" << rule_len_2 << endl;
490
-
491
- }
492
-
493
-
494
-
495
- //ファジィルール集合選択
496
-
497
- void create_rule(int num) {
498
-
499
- if (num == 0) {
500
-
501
- for (int i = 0; i < 2; i++) {
502
-
503
- rule_select[num] = i;
504
-
505
- //識別率の計算
506
-
507
- calc_ans();
508
-
509
- //ルール数と相ルール長の計算
510
-
511
- count_rule();
512
-
513
- //加重和適応度の計算
514
-
515
- if ((1000 * ans_rate - rule_num - rule_len) > fitness) {
516
-
517
- fitness = 1000 * ans_rate - rule_num - rule_len;
518
-
519
- ans_rate_2 = ans_rate;
520
-
521
- rule_len_2 = rule_len;
522
-
523
- rule_num_2 = rule_num;
524
-
525
- for (int j = 0; j<N_rp; j++) {
526
-
527
- rule_select_2[j] = rule_select[j];
528
-
529
- }
530
-
531
- }
532
-
533
- }
534
-
535
- }
536
-
537
- else {
538
-
539
- for (int i = 0; i<2; i++) {
540
-
541
- rule_select[num] = i;
542
-
543
- create_rule(num - 1);
544
-
545
- }
546
-
547
-
548
-
549
- }
550
-
551
- }
552
-
553
-
554
-
555
-
556
-
557
- protected:
558
-
559
- ///////////////////データ読み込みに関するメンバ
560
-
561
-
562
-
563
- //学習データ格納 要素,クラスの順 0行目は入力データの情報 1行目からデータ
564
-
565
- double data[N][N_d + 1];
566
-
567
-
568
-
569
-
570
-
571
-
572
-
573
-
574
-
575
- //ルール配列 条件ファジイ集合,結論クラス,ルール重み、利用bitの順 利用bitが1ならそのルールは使用しない
576
-
577
- double rule[N_rp][5];
578
-
579
- //各ルールの適合度計算
580
-
581
- double rule_fit[N_rp][N];
582
-
583
- //各ルールの信頼度計算
584
-
585
- double rule_class[N_rp][3];
586
-
587
- //ルール数
588
-
589
- int rule_num;
590
-
591
- //総ルール長
592
-
593
- int rule_len;
594
-
595
- //識別率
596
-
597
- double ans_rate;
598
-
599
- //ルール集合選択配列
600
-
601
- int rule_select[N_rp];
602
-
603
- //加重和適応度
604
-
605
- double fitness;
606
-
607
-
608
-
609
- //ルール集合選択後の結果
610
-
611
- //ルール数
612
-
613
- int rule_num_2;
614
-
615
- //総ルール長
616
-
617
- int rule_len_2;
618
-
619
- //識別率
620
-
621
- double ans_rate_2;
622
-
623
- //ルール集合選択配列
624
-
625
- int rule_select_2[N_rp];
626
-
627
-
628
-
629
-
630
-
631
-
632
-
633
- };
634
-
635
-
636
-
637
-
638
-
639
- int main() {
640
-
641
-
642
-
643
- ////////////////準備///////////////////////
644
-
645
- //オブジェクト生成
646
-
647
- Fuzzy fuzzy;
648
-
649
-
650
-
651
- //学習データ読み込み
652
-
653
- fuzzy.read_data();
654
-
655
-
656
-
657
- /////////////////////学習開始/////////////////////////
658
-
659
- ////適合度計算
660
-
661
- fuzzy.calc_fit();
662
-
663
- ////信頼度計算
664
-
665
- fuzzy.calc_trust();
666
-
667
- ////結論部クラス決定、ルール重み計算
668
-
669
- fuzzy.calc_class();
670
-
671
- fuzzy.count_rule();
672
-
673
-
674
-
675
-
676
-
677
- ////////////未知パターン識別////////////////
678
-
679
- ////識別率計算
680
-
681
- fuzzy.calc_ans();
682
-
683
-
684
-
685
- fuzzy.show1();
686
-
687
-
688
-
689
-
690
-
691
- ////ファジィルール選択
692
-
693
- fuzzy.create_rule(15);
694
-
695
-
696
-
697
- fuzzy.show2();
698
-
699
-
700
-
701
- return 0;
702
-
703
- }
704
-
705
- ```
706
-
707
-
708
-
709
- ファジィ識別器をC++で作成しています。show1,show2関数で識別率、ルール数、総ルール長を表示するようにしています。実行結果は、show1では、順に91.667,0,0となり、show2では93.0,0,0となりました。識別率に関しては正解データと一致しました。ただ、ルール数と総ルール長はshow1に関しては13,22で、show2に関しては5,8が正解となります。どこで間違っているのかがよく分からないのでよろしければ教えてください。
1
+ ファジィ識別器。ファジィ識別器ファジィ識別器ファジィ識別器ファジィ識別器