Skip to content

Commit 36f966d

Browse files
authored
Merge pull request #2403 from entrylabs/develop
Master
2 parents b91d2ff + 81d35ba commit 36f966d

33 files changed

+5727
-3912
lines changed

.github/workflows/deploy.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v2
17-
- name: Use Node.js 12.x
17+
- name: Use Node.js 14.x
1818
uses: actions/setup-node@v1
1919
env:
2020
NODE_OPTIONS: '--max-old-space-size=4096'
2121
TOOL_NODE_FLAGS: '--max-old-space-size=4096'
2222
with:
23-
node-version: '12.x'
23+
node-version: 14
2424
- uses: bahmutov/npm-install@v1
2525
- name: entry build
2626
env:

extern/lang/ko.js

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6383,6 +6383,49 @@ Lang.Helper = {
63836383
get_regression_predict_5: '입력한 특성값으로 모델이 예측한 값을 반환합니다.',
63846384
get_regression_predict_6: '입력한 특성값으로 모델이 예측한 값을 반환합니다.',
63856385
get_regression_accuracy: '모델의 결정계수를 값으로 반환합니다.',
6386+
set_logistic_regression_option:
6387+
"모델의 학습 조건을 변경합니다. 변경한 학습 조건은 '모델 다시 학습하기' 블록으로 모델을 다시 학습할 때부터 적용됩니다.",
6388+
set_logistic_regression_optimizer:
6389+
"모델의 최적화 알고리즘을 변경합니다. 변경한 최적화 알고리즘은 '모델 다시 학습하기' 블록으로 모델을 다시 학습할 때부터 적용됩니다.",
6390+
get_logistic_regression_probability_1:
6391+
'입력한 데이터의 선택한 클래스에 대한 확률 값입니다. 값은 숫자로 표현됩니다.',
6392+
get_logistic_regression_probability_2:
6393+
'입력한 데이터의 선택한 클래스에 대한 확률 값입니다. 값은 숫자로 표현됩니다.',
6394+
get_logistic_regression_probability_3:
6395+
'입력한 데이터의 선택한 클래스에 대한 확률 값입니다. 값은 숫자로 표현됩니다.',
6396+
get_logistic_regression_probability_4:
6397+
'입력한 데이터의 선택한 클래스에 대한 확률 값입니다. 값은 숫자로 표현됩니다.',
6398+
get_logistic_regression_probability_5:
6399+
'입력한 데이터의 선택한 클래스에 대한 확률 값입니다. 값은 숫자로 표현됩니다.',
6400+
get_logistic_regression_probability_6:
6401+
'입력한 데이터의 선택한 클래스에 대한 확률 값입니다. 값은 숫자로 표현됩니다.',
6402+
set_decisiontree_option:
6403+
"모델의 학습 조건을 변경합니다. 변경한 학습 조건은 '모델 다시 학습하기' 블록으로 모델을 다시 학습할 때부터 적용됩니다.",
6404+
set_decisiontree_tree: "학습한 결정 트리를 나타낸 창을 열거나 닫습니다.",
6405+
set_svm_option: "모델의 학습 조건을 변경합니다. 변경한 학습 조건은 '모델 다시 학습하기' 블록으로 모델을 다시 학습할 때부터 적용됩니다.",
6406+
set_kernel_linear:
6407+
"학습 조건 중 커널을 선형으로 변경합니다. 변경한 학습 조건은 '모델 다시 학습하기' 블록으로 모델을 다시 학습할 때부터 적용됩니다.",
6408+
set_kernel_option:
6409+
"학습 조건 중 커널을 다항식 또는 RBF로 변경합니다. 변경한 학습 조건은 '모델 다시 학습하기' 블록으로 모델을 다시 학습할 때부터 적용됩니다.",
6410+
is_result_1: "입력한 데이터의 분류 결과가 선택한 클래스인 경우 '참'으로 판단합니다.",
6411+
is_result_2: "입력한 데이터의 분류 결과가 선택한 클래스인 경우 '참'으로 판단합니다.",
6412+
is_result_3: "입력한 데이터의 분류 결과가 선택한 클래스인 경우 '참'으로 판단합니다.",
6413+
is_result_4: "입력한 데이터의 분류 결과가 선택한 클래스인 경우 '참'으로 판단합니다.",
6414+
is_result_5: "입력한 데이터의 분류 결과가 선택한 클래스인 경우 '참'으로 판단합니다.",
6415+
is_result_6: "입력한 데이터의 분류 결과가 선택한 클래스인 경우 '참'으로 판단합니다.",
6416+
get_predict_1:
6417+
'입력한 데이터를 모델에서 분류한 값입니다. 값은 클래스 이름(텍스트)으로 표현됩니다.',
6418+
get_predict_2:
6419+
'입력한 데이터를 모델에서 분류한 값입니다. 값은 클래스 이름(텍스트)으로 표현됩니다.',
6420+
get_predict_3:
6421+
'입력한 데이터를 모델에서 분류한 값입니다. 값은 클래스 이름(텍스트)으로 표현됩니다.',
6422+
get_predict_4:
6423+
'입력한 데이터를 모델에서 분류한 값입니다. 값은 클래스 이름(텍스트)으로 표현됩니다.',
6424+
get_predict_5:
6425+
'입력한 데이터를 모델에서 분류한 값입니다. 값은 클래스 이름(텍스트)으로 표현됩니다.',
6426+
get_predict_6:
6427+
'입력한 데이터를 모델에서 분류한 값입니다. 값은 클래스 이름(텍스트)으로 표현됩니다.',
6428+
get_result_info: '모델의 성능 평가 지표를 값으로 반환합니다.',
63866429
set_cluster_option_k:
63876430
"군집의 개수를 입력한 값으로 바꾸어 설정합니다. 변경한 군집 개수는 '모델 다시 학습하기' 블록으로 모델을 다시 학습할 때부터 적용됩니다.",
63886431
set_cluster_option_centroids:
@@ -6979,7 +7022,10 @@ Lang.template = {
69797022
learning_title_text: '%1',
69807023
learning_title_number: '%1',
69817024
learning_title_regression: '%1',
7025+
learning_title_logistic_regression: '%1',
69827026
learning_title_cluster: '%1',
7027+
learning_title_decisiontree: '%1',
7028+
learning_title_svm: '%1',
69837029
insert_data_for_test: '학습한 모델로 인식하기 %1',
69847030
insert_text_block_for_test: '%1 을(를) 학습한 모델로 인식하기 %2',
69857031
test_result: '인식 결과',
@@ -6997,6 +7043,36 @@ Lang.template = {
69977043
get_regression_predict_5: '%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 의 예측값',
69987044
get_regression_predict_6: '%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 의 예측값',
69997045
get_regression_accuracy: '결정계수',
7046+
set_logistic_regression_option: '학습 조건 %1 을(를) %2 (으)로 바꾸기 %3',
7047+
set_logistic_regression_optimizer: '최적화 알고리즘을 %1 (으)로 바꾸기 %2',
7048+
get_logistic_regression_probability_1: '%1 %2 의 %3 에 대한 확률',
7049+
get_logistic_regression_probability_2: '%1 %2 %3 %4 의 %5 에 대한 확률',
7050+
get_logistic_regression_probability_3: '%1 %2 %3 %4 %5 %6 의 %7 에 대한 확률',
7051+
get_logistic_regression_probability_4: '%1 %2 %3 %4 %5 %6 %7 %8 의 %9 에 대한 확률',
7052+
get_logistic_regression_probability_5: '%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 의 %11 에 대한 확률',
7053+
get_logistic_regression_probability_6: '%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 의 %13 에 대한 확률',
7054+
set_decisiontree_option: '학습 조건 %1 을 %2 으로 바꾸기 %3',
7055+
set_decisiontree_tree: '학습한 트리 %1 %2',
7056+
set_svm_option: '학습 조건 %1 을 %2 으로 바꾸기 %3',
7057+
set_kernel_linear: '커널을 선형으로 바꾸기 %1',
7058+
set_kernel_option: '커널을 %1 (으)로 바꾸고 %2 를 %3 (으)로 정하기 %4',
7059+
train_param_kernel_polynomial: '다항식',
7060+
train_param_kernel_rbf: 'RBF',
7061+
train_param_degree: '차수',
7062+
train_param_gamma: '감마',
7063+
is_result_1: '%1 %2 의 분류 결과가 %3 인가?',
7064+
is_result_2: '%1 %2 %3 %4 의 분류 결과가 %5 인가?',
7065+
is_result_3: '%1 %2 %3 %4 %5 %6 의 분류 결과가 %7 인가?',
7066+
is_result_4: '%1 %2 %3 %4 %5 %6 %7 %8 의 분류 결과가 %9 인가?',
7067+
is_result_5: '%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 의 분류 결과가 %11 인가?',
7068+
is_result_6: '%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 의 분류 결과가 %13 인가?',
7069+
get_predict_1: '%1 %2 의 분류 결과',
7070+
get_predict_2: '%1 %2 %3 %4 의 분류 결과',
7071+
get_predict_3: '%1 %2 %3 %4 %5 %6 의 분류 결과',
7072+
get_predict_4: '%1 %2 %3 %4 %5 %6 %7 %8 의 분류 결과',
7073+
get_predict_5: '%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 의 분류 결과',
7074+
get_predict_6: '%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 의 분류 결과',
7075+
get_result_info: '모델의 %1',
70007076
set_cluster_option_k: '군집을 %1 개로 바꾸기 %2',
70017077
set_cluster_option_centroids: '중심점 기준을 %1 로 바꾸기 %2',
70027078
get_cluster_centriod_count: '군집 개수',
@@ -7683,6 +7759,9 @@ Lang.template = {
76837759
learning_title_number_str: '분류: 숫자 모델',
76847760
learning_title_regression_str: '예측: 숫자 모델',
76857761
learning_title_cluster_str: '군집: 숫자 모델',
7762+
learning_title_logistic_regression_str: '분류: 숫자 (로지스틱 회귀) 모델',
7763+
learning_title_decisiontree_str: '분류: 숫자 (결정 트리) 모델',
7764+
learning_title_svm_str: '분류: 숫자 (SVM) 모델',
76867765
};
76877766
Lang.TextCoding = {
76887767
block_name: '블록명',
@@ -8825,7 +8904,13 @@ Lang.AiLearning = {
88258904
hide: '숨기기',
88268905
open: '열기',
88278906
close: '닫기',
8828-
probability: '정확도',
8907+
probability: '신뢰도',
8908+
accuracy: '정확도',
8909+
f1: 'F1',
8910+
precision: '정밀도',
8911+
recall: '재현율',
8912+
train_param_optimizer_adam: 'Adam',
8913+
train_param_optimizer_sgd: 'SGD',
88298914
neighbor_count: '이웃 개수',
88308915
cluster_option_centroids_kmpp: '가장 먼 거리',
88318916
cluster_option_centroids_random: '무작위',
@@ -8835,8 +8920,13 @@ Lang.AiLearning = {
88358920
model_status_2: '상태: 학습완료',
88368921
model_status_3: '상태: 모델없음',
88378922
train_param_learningRate: '학습률',
8838-
train_param_epochs: '세대',
8839-
train_param_validationRate: '테스트 데이터 비율',
8923+
train_param_epochs: '에포크',
8924+
train_param_validationRate: '검증 데이터 비율',
8925+
train_param_C: 'C',
8926+
train_param_kernel_polynomial: '다항식',
8927+
train_param_kernel_rbf: 'RBF',
8928+
train_param_degree: '차수',
8929+
train_param_gamma: '감마',
88408930
};
88418931
Lang.SharePolicy = {
88428932
title: '엔트리 작품/게시물 공유 가이드',

extern/util/static.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,9 @@ EntryStatic.getAllBlocks = function() {
417417
'learning_title_number',
418418
'learning_title_regression',
419419
'learning_title_cluster',
420+
'learning_title_logistic_regression',
421+
'learning_title_decisiontree',
422+
'learning_title_svm',
420423
'retrain_model',
421424
'model_is_trained',
422425
'set_train_visible',
@@ -429,6 +432,32 @@ EntryStatic.getAllBlocks = function() {
429432
'get_regression_predict_5',
430433
'get_regression_predict_6',
431434
'get_regression_accuracy',
435+
'set_logistic_regression_option',
436+
'set_logistic_regression_optimizer',
437+
'get_logistic_regression_probability_1',
438+
'get_logistic_regression_probability_2',
439+
'get_logistic_regression_probability_3',
440+
'get_logistic_regression_probability_4',
441+
'get_logistic_regression_probability_5',
442+
'get_logistic_regression_probability_6',
443+
'set_decisiontree_option',
444+
'set_decisiontree_tree',
445+
'set_svm_option',
446+
'set_kernel_linear',
447+
'set_kernel_option',
448+
'is_result_1',
449+
'is_result_2',
450+
'is_result_3',
451+
'is_result_4',
452+
'is_result_5',
453+
'is_result_6',
454+
'get_predict_1',
455+
'get_predict_2',
456+
'get_predict_3',
457+
'get_predict_4',
458+
'get_predict_5',
459+
'get_predict_6',
460+
'get_result_info',
432461
'set_cluster_option_k',
433462
'set_cluster_option_centroids',
434463
'get_cluster_centriod_count',

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@
5656
"html-webpack-template": "^6.2.0",
5757
"isomorphic-fetch": "^2.2.1",
5858
"jest": "^24.9.0",
59+
"libsvm-js": "^0.2.1",
5960
"lodash": "^4.17.15",
6061
"mathjs": "^7.1.0",
62+
"ml-cart": "^2.1.1",
6163
"pixi.js": "5.3.7",
6264
"postcss-flexbugs-fixes": "^4.1.0",
6365
"simplebar": "^3.1.1",

src/class/AILearning.js

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import Classification, { classes as ClassificationClasses } from './learning/Cla
66
import NumberClassification, {
77
classes as NumberClassificationClasses,
88
} from './learning/NumberClassification';
9+
import DecisionTree, { classes as DecisionTreeClasses } from './learning/DecisionTree';
10+
import LogisticRegression, {
11+
classes as LogisticRegressionClasses,
12+
} from './learning/LogisticRegression';
13+
import Svm, { classes as SvmClasses } from './learning/Svm';
914
import DataTable from './DataTable';
1015

1116
const banClasses = [
@@ -15,6 +20,9 @@ const banClasses = [
1520
...ImageClasses,
1621
...ClassificationClasses,
1722
...NumberClassificationClasses,
23+
...DecisionTreeClasses,
24+
...LogisticRegressionClasses,
25+
...SvmClasses,
1826
];
1927

2028
export default class AILearning {
@@ -162,6 +170,33 @@ export default class AILearning {
162170
type,
163171
recordTime,
164172
});
173+
} else if (type === 'logisticRegression') {
174+
this.#tableData = tableData || createDataTable(classes, name);
175+
this.#module = new LogisticRegression({
176+
name,
177+
result,
178+
url,
179+
trainParam,
180+
table: this.#tableData,
181+
});
182+
} else if (type === 'decisionTree') {
183+
this.#tableData = tableData || createDataTable(classes, name);
184+
this.#module = new DecisionTree({
185+
name,
186+
result,
187+
url,
188+
trainParam,
189+
table: this.#tableData,
190+
});
191+
} else if (type === 'svm') {
192+
this.#tableData = tableData || createDataTable(classes, name);
193+
this.#module = new Svm({
194+
name,
195+
result,
196+
url,
197+
trainParam,
198+
table: this.#tableData,
199+
});
165200
}
166201

167202
if (this.#module) {
@@ -309,8 +344,8 @@ function getBlockMenu(playground) {
309344
}
310345

311346
function createDataTable(classes, name) {
312-
if(!classes.length) {
313-
return ;
347+
if (!classes.length) {
348+
return;
314349
}
315350
try {
316351
const [{ samples }] = classes;
@@ -320,10 +355,7 @@ function createDataTable(classes, name) {
320355
data = JSON.parse(data);
321356
}
322357
if (data && data.id && !DataTable.getSource(data.id)) {
323-
DataTable.addSource(
324-
data,
325-
false
326-
);
358+
DataTable.addSource(data, false);
327359
}
328360
return data;
329361
} catch (e) {

src/class/DataTable.js

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { DataAnalytics, ModalChart, ModalTable } from '@entrylabs/tool';
1414
class DataTable {
1515
#tables = [];
1616
#view;
17-
modal;
17+
modals = [];
1818
selected;
1919

2020
get tables() {
@@ -260,12 +260,14 @@ class DataTable {
260260
console.log(`not exist souce, table id: ${tableId}`);
261261
return;
262262
}
263-
if (!source.modal) {
264-
source.modal = this.createChart(source, chartIndex);
263+
let chart = source.modals.find((m) => m.name === 'chart');
264+
if (!chart) {
265+
chart = this.createChart(source, chartIndex);
266+
source.modals.push(chart);
267+
this.modals.push(chart);
265268
}
266269
source.forceApply();
267-
source.modal.show(undefined, { chartIndex });
268-
this.modal = source.modal;
270+
chart.show(undefined, { chartIndex });
269271
}
270272

271273
showTable(tableId) {
@@ -275,18 +277,20 @@ class DataTable {
275277
console.log(`not exist souce, table id: ${tableId}`);
276278
return;
277279
}
278-
if (!source.modal) {
279-
source.modal = this.createTable(source);
280+
let table = source.modals.find((m) => m.name === 'table');
281+
if (!table) {
282+
table = this.createTable(source);
283+
source.modals.push(table);
284+
this.modals.push(table);
280285
}
281286
source.forceApply();
282-
source.modal.show();
283-
this.modal = source.modal;
287+
table.show();
284288
}
285289

286290
closeModal() {
287-
if (this.modal && this.modal.isShow) {
288-
this.modal.hide();
289-
}
291+
this.modals.forEach((m) => {
292+
m.hide();
293+
});
290294
}
291295

292296
createChart(source, chartIndex = 0) {
@@ -295,7 +299,7 @@ class DataTable {
295299
class: 'entry-table-chart',
296300
parent: $(Entry.modalContainer),
297301
})[0];
298-
return new ModalChart({
302+
const modal = new ModalChart({
299303
data: {
300304
chartIndex,
301305
source: { fields, origin: rows, chart },
@@ -305,14 +309,16 @@ class DataTable {
305309
},
306310
container,
307311
});
312+
modal.name = 'chart';
313+
return modal;
308314
}
309315

310316
createTable(source) {
311317
const container = Entry.Dom('div', {
312318
class: 'entry-table-modal',
313319
parent: $(Entry.modalContainer),
314320
})[0];
315-
return new ModalTable({
321+
const modal = new ModalTable({
316322
data: {
317323
table: source,
318324
tables: this.tables,
@@ -322,11 +328,13 @@ class DataTable {
322328
},
323329
container,
324330
});
331+
modal.name = 'table';
332+
return modal;
325333
}
326334

327335
clear() {
328336
this.#tables = [];
329-
this.modal = null;
337+
this.modals = [];
330338
}
331339
}
332340

0 commit comments

Comments
 (0)