@datagrok/eda 1.1.27 → 1.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/111.js +2 -0
  3. package/dist/111.js.map +1 -0
  4. package/dist/153.js +2 -0
  5. package/dist/153.js.map +1 -0
  6. package/dist/23.js +2 -2
  7. package/dist/23.js.map +1 -0
  8. package/dist/234.js +2 -0
  9. package/dist/234.js.map +1 -0
  10. package/dist/242.js +2 -0
  11. package/dist/242.js.map +1 -0
  12. package/dist/260.js +2 -0
  13. package/dist/260.js.map +1 -0
  14. package/dist/317.js +2 -0
  15. package/dist/317.js.map +1 -0
  16. package/dist/33.js +2 -0
  17. package/dist/33.js.map +1 -0
  18. package/dist/348.js +2 -0
  19. package/dist/348.js.map +1 -0
  20. package/dist/377.js +2 -0
  21. package/dist/377.js.map +1 -0
  22. package/dist/412.js +2 -0
  23. package/dist/412.js.map +1 -0
  24. package/dist/415.js +2 -0
  25. package/dist/415.js.map +1 -0
  26. package/dist/531.js +2 -0
  27. package/dist/531.js.map +1 -0
  28. package/dist/583.js +2 -0
  29. package/dist/583.js.map +1 -0
  30. package/dist/589.js +2 -0
  31. package/dist/589.js.map +1 -0
  32. package/dist/603.js +2 -0
  33. package/dist/603.js.map +1 -0
  34. package/dist/656.js +2 -0
  35. package/dist/656.js.map +1 -0
  36. package/dist/682.js +2 -0
  37. package/dist/682.js.map +1 -0
  38. package/dist/705.js +2 -0
  39. package/dist/705.js.map +1 -0
  40. package/dist/731.js +2 -0
  41. package/dist/731.js.map +1 -0
  42. package/dist/738.js +3 -0
  43. package/dist/738.js.map +1 -0
  44. package/dist/763.js +2 -0
  45. package/dist/763.js.map +1 -0
  46. package/dist/778.js +2 -0
  47. package/dist/778.js.map +1 -0
  48. package/dist/783.js +2 -0
  49. package/dist/783.js.map +1 -0
  50. package/dist/793.js +2 -0
  51. package/dist/793.js.map +1 -0
  52. package/dist/907.js +2 -0
  53. package/dist/907.js.map +1 -0
  54. package/dist/91.js +2 -0
  55. package/dist/91.js.map +1 -0
  56. package/dist/950.js +2 -0
  57. package/dist/950.js.map +1 -0
  58. package/dist/package-test.js +2 -2
  59. package/dist/package-test.js.map +1 -0
  60. package/dist/package.js +2 -2
  61. package/dist/package.js.map +1 -0
  62. package/package.json +3 -3
  63. package/src/missing-values-imputation/ui.ts +80 -66
  64. package/src/package.ts +104 -46
  65. package/src/pls/pls-tools.ts +5 -6
  66. package/src/svm.ts +19 -17
  67. package/tsconfig.json +4 -4
  68. package/webpack.config.js +1 -1
  69. package/dist/208.js +0 -2
  70. package/dist/221.js +0 -2
  71. package/dist/231.js +0 -2
  72. package/dist/261.js +0 -2
  73. package/dist/282.js +0 -2
  74. package/dist/334.js +0 -2
  75. package/dist/356.js +0 -2
  76. package/dist/36.js +0 -2
  77. package/dist/367.js +0 -2
  78. package/dist/374.js +0 -2
  79. package/dist/40.js +0 -2
  80. package/dist/413.js +0 -2
  81. package/dist/42.js +0 -2
  82. package/dist/427.js +0 -2
  83. package/dist/445.js +0 -2
  84. package/dist/467.js +0 -2
  85. package/dist/523.js +0 -3
  86. package/dist/533.js +0 -2
  87. package/dist/590.js +0 -2
  88. package/dist/65.js +0 -2
  89. package/dist/694.js +0 -2
  90. package/dist/729.js +0 -2
  91. package/dist/796.js +0 -2
  92. package/dist/901.js +0 -2
  93. package/dist/902.js +0 -2
  94. package/dist/910.js +0 -2
  95. package/dist/972.js +0 -2
  96. /package/dist/{523.js.LICENSE.txt → 738.js.LICENSE.txt} +0 -0
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@datagrok/eda",
3
3
  "friendlyName": "EDA",
4
- "version": "1.1.27",
4
+ "version": "1.1.28",
5
5
  "description": "Exploratory Data Analysis Tools",
6
6
  "dependencies": {
7
7
  "@datagrok-libraries/math": "^1.1.10",
8
- "@datagrok-libraries/ml": "^6.6.11",
8
+ "@datagrok-libraries/ml": "^6.6.13",
9
9
  "@datagrok-libraries/tutorials": "^1.3.6",
10
10
  "@datagrok-libraries/utils": "^4.1.44",
11
11
  "@keckelt/tsne": "^1.0.2",
12
12
  "@webgpu/types": "^0.1.40",
13
13
  "cash-dom": "^8.1.1",
14
- "datagrok-api": "^1.16.0",
14
+ "datagrok-api": "^1.20.0",
15
15
  "dayjs": "^1.11.9",
16
16
  "jstat": "^1.9.6",
17
17
  "source-map-loader": "^4.0.1",
@@ -2,51 +2,51 @@ import * as grok from 'datagrok-api/grok';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
- import { TITLE, KNN_IMPUTER, ERROR_MSG, HINT } from './ui-constants';
6
- import { SUPPORTED_COLUMN_TYPES, METRIC_TYPE, DISTANCE_TYPE, MetricInfo, DEFAULT, MIN_NEIGHBORS,
7
- impute, getMissingValsIndices, areThereFails, imputeFailed } from "./knn-imputer";
5
+ import {TITLE, KNN_IMPUTER, ERROR_MSG, HINT} from './ui-constants';
6
+ import {SUPPORTED_COLUMN_TYPES, METRIC_TYPE, DISTANCE_TYPE, MetricInfo, DEFAULT, MIN_NEIGHBORS,
7
+ impute, getMissingValsIndices, areThereFails, imputeFailed} from './knn-imputer';
8
8
 
9
9
  /** Setting of the feature metric inputs */
10
10
  type FeatureInputSettings = {
11
11
  defaultWeight: number,
12
12
  defaultMetric: METRIC_TYPE,
13
- availableMetrics: METRIC_TYPE[],
13
+ availableMetrics: METRIC_TYPE[],
14
14
  };
15
15
 
16
16
  /** Return default setting of the feature metric inputs */
17
17
  function getFeatureInputSettings(type: DG.COLUMN_TYPE): FeatureInputSettings {
18
18
  switch (type) {
19
- case DG.COLUMN_TYPE.STRING:
20
- case DG.COLUMN_TYPE.DATE_TIME:
21
- return {
22
- defaultWeight: DEFAULT.WEIGHT,
23
- defaultMetric: METRIC_TYPE.ONE_HOT,
24
- availableMetrics: [METRIC_TYPE.ONE_HOT]
25
- };
26
-
27
- case DG.COLUMN_TYPE.INT:
28
- case DG.COLUMN_TYPE.FLOAT:
29
- case DG.COLUMN_TYPE.QNUM:
30
- return {
31
- defaultWeight: DEFAULT.WEIGHT,
32
- defaultMetric: METRIC_TYPE.DIFFERENCE,
33
- availableMetrics: [METRIC_TYPE.DIFFERENCE, METRIC_TYPE.ONE_HOT]
34
- };
35
-
36
- default:
37
- throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);
19
+ case DG.COLUMN_TYPE.STRING:
20
+ case DG.COLUMN_TYPE.DATE_TIME:
21
+ return {
22
+ defaultWeight: DEFAULT.WEIGHT,
23
+ defaultMetric: METRIC_TYPE.ONE_HOT,
24
+ availableMetrics: [METRIC_TYPE.ONE_HOT],
25
+ };
26
+
27
+ case DG.COLUMN_TYPE.INT:
28
+ case DG.COLUMN_TYPE.FLOAT:
29
+ case DG.COLUMN_TYPE.QNUM:
30
+ return {
31
+ defaultWeight: DEFAULT.WEIGHT,
32
+ defaultMetric: METRIC_TYPE.DIFFERENCE,
33
+ availableMetrics: [METRIC_TYPE.DIFFERENCE, METRIC_TYPE.ONE_HOT],
34
+ };
35
+
36
+ default:
37
+ throw new Error(ERROR_MSG.UNSUPPORTED_COLUMN_TYPE);
38
38
  }
39
39
  }
40
40
 
41
41
  /** Run the KNN missing values imputer */
42
- export function runKNNImputer(): void {
42
+ export async function runKNNImputer(df?: DG.DataFrame): Promise<void> {
43
43
  /** current dataframe */
44
- let df: DG.DataFrame | null = grok.shell.t;
44
+ df ??= grok.shell.t;
45
45
 
46
46
  if (df === null) {
47
47
  grok.shell.warning(ERROR_MSG.NO_DATAFRAME);
48
48
  return;
49
- }
49
+ }
50
50
 
51
51
  /** columns with missing values */
52
52
  const colsWithMissingVals = [] as DG.Column[];
@@ -84,53 +84,54 @@ export function runKNNImputer(): void {
84
84
 
85
85
  // In-place components
86
86
  let inPlace = DEFAULT.IN_PLACE > 0;
87
- const inPlaceInput = ui.boolInput(TITLE.IN_PLACE, inPlace, () => { inPlace = inPlaceInput.value ?? false;});
87
+ const inPlaceInput = ui.input.bool(TITLE.IN_PLACE, {value: inPlace,
88
+ onValueChanged: () => {inPlace = inPlaceInput.value ?? false;}});
88
89
  inPlaceInput.setTooltip(HINT.IN_PLACE);
89
90
 
90
91
  // Keep empty feature
91
92
  let keepEmpty = DEFAULT.KEEP_EMPTY > 0;
92
- const keepEmptyInput = ui.boolInput(TITLE.KEEP_EMPTY, keepEmpty, () => { keepEmpty = keepEmptyInput.value ?? false });
93
+ const keepEmptyInput = ui.input.bool(TITLE.KEEP_EMPTY, {value: keepEmpty,
94
+ onValueChanged: () => {keepEmpty = keepEmptyInput.value ?? false;}});
93
95
  keepEmptyInput.setTooltip(HINT.KEEP_EMPTY);
94
96
 
95
97
  // Neighbors components
96
98
  let neighbors = DEFAULT.NEIGHBORS;
97
- const neighborsInput = ui.intInput(TITLE.NEIGHBORS, neighbors, () => {
99
+ const neighborsInput = ui.input.int(TITLE.NEIGHBORS, {value: neighbors, onValueChanged: () => {
98
100
  const val = neighborsInput.value;
99
101
  if (val === null)
100
102
  neighborsInput.value = neighbors;
101
- else if (val >= MIN_NEIGHBORS)
103
+ else if (val >= MIN_NEIGHBORS)
102
104
  neighbors = val;
103
105
  else
104
106
  neighborsInput.value = neighbors;
105
- });
107
+ }});
106
108
  neighborsInput.setTooltip(HINT.NEIGHBORS);
107
109
 
108
110
  // Distance components
109
111
  let distType = DISTANCE_TYPE.EUCLIDEAN;
110
- const distTypeInput = ui.choiceInput(TITLE.DISTANCE, distType, [DISTANCE_TYPE.EUCLIDEAN, DISTANCE_TYPE.MANHATTAN],
111
- () => distType = distTypeInput.value ?? DISTANCE_TYPE.EUCLIDEAN);
112
+ const distTypeInput: DG.ChoiceInput<DISTANCE_TYPE> = ui.input.choice(TITLE.DISTANCE, {value: distType,
113
+ items: [DISTANCE_TYPE.EUCLIDEAN, DISTANCE_TYPE.MANHATTAN], onValueChanged: () => distType = distTypeInput.value ?? DISTANCE_TYPE.EUCLIDEAN}) as DG.ChoiceInput<DISTANCE_TYPE>;
112
114
  distTypeInput.setTooltip(HINT.DISTANCE);
113
115
 
114
116
  // Target columns components (cols with missing values to be imputed)
115
117
  let targetColNames = colsWithMissingVals.map((col) => col.name);
116
- const targetColInput = ui.columnsInput(TITLE.COLUMNS, df, () => {
117
- targetColNames = targetColInput.value.map((col) => col.name);
118
+ const targetColInput = ui.input.columns(TITLE.COLUMNS, {table: df, onValueChanged: () => {
119
+ targetColNames = targetColInput.value.map((col) => col.name);
118
120
  checkApplicability();
119
- }, {available: availableTargetColsNames, checked: availableTargetColsNames});
121
+ }, available: availableTargetColsNames, checked: availableTargetColsNames});
120
122
  targetColInput.setTooltip(HINT.TARGET);
121
123
 
122
124
  // Feature columns components
123
125
  let selectedFeatureColNames = availableFeatureColsNames as string[];
124
- const featuresInput = ui.columnsInput(TITLE.FEATURES, df, () => {
126
+ const featuresInput = ui.input.columns(TITLE.FEATURES, {table: df, onValueChanged: () => {
125
127
  selectedFeatureColNames = featuresInput.value.map((col) => col.name);
126
128
 
127
129
  if (selectedFeatureColNames.length > 0) {
128
130
  checkApplicability();
129
- metricInfoInputs.forEach((div, name) => div.hidden = !selectedFeatureColNames.includes(name));
130
- }
131
- else
131
+ metricInfoInputs.forEach((div, name) => div.hidden = !selectedFeatureColNames.includes(name));
132
+ } else
132
133
  hideWidgets();
133
- }, {available: availableFeatureColsNames, checked: availableFeatureColsNames});
134
+ }, available: availableFeatureColsNames, checked: availableFeatureColsNames});
134
135
  featuresInput.setTooltip(HINT.FEATURES);
135
136
 
136
137
  /** Hide widgets (use if run is not applicable) */
@@ -155,14 +156,15 @@ export function runKNNImputer(): void {
155
156
 
156
157
  /** Check applicability of the imputation */
157
158
  const checkApplicability = () => {
158
- showWidgets();
159
-
159
+ showWidgets();
160
+
160
161
  if (selectedFeatureColNames.length === 1) {
161
162
  targetColNames.forEach((name) => {
162
163
  if (selectedFeatureColNames[0] === name) {
163
164
  hideWidgets();
164
165
  grok.shell.warning(`${ERROR_MSG.ONE_FEATURE_SELECTED} the column '${name}'`);
165
- }});
166
+ }
167
+ });
166
168
  }
167
169
  };
168
170
 
@@ -173,25 +175,26 @@ export function runKNNImputer(): void {
173
175
  metricsDiv.style.overflow = 'auto';
174
176
 
175
177
  // Create metrics UI
176
- availableFeatureColsNames.forEach((name) => {
178
+ availableFeatureColsNames.forEach((name) => {
177
179
  // initialization
178
180
  const type = df!.col(name)!.type as DG.COLUMN_TYPE;
179
181
  const settings = getFeatureInputSettings(type);
180
182
  featuresMetrics.set(name, {weight: settings.defaultWeight, type: settings.defaultMetric});
181
183
 
182
184
  // distance input
183
- const distTypeInput = ui.choiceInput(name, settings.defaultMetric, settings.availableMetrics, () => {
184
- const distInfo = featuresMetrics.get(name) ?? {weight: settings.defaultWeight, type: settings.defaultMetric};
185
- distInfo.type = distTypeInput.value ?? settings.defaultMetric;
186
- featuresMetrics.set(name, distInfo);
187
- });
185
+ const distTypeInput = ui.input.choice(name, {value: settings.defaultMetric,
186
+ items: settings.availableMetrics, onValueChanged: () => {
187
+ const distInfo = featuresMetrics.get(name) ?? {weight: settings.defaultWeight, type: settings.defaultMetric};
188
+ distInfo.type = distTypeInput.value ?? settings.defaultMetric;
189
+ featuresMetrics.set(name, distInfo);
190
+ }});
188
191
  distTypeInput.root.style.width = '50%';
189
192
  distTypeInput.setTooltip(HINT.METRIC);
190
193
  distTypeInput.root.hidden = true; // this input will be used further
191
194
 
192
195
  // The following should provide a slider (see th bug https://reddata.atlassian.net/browse/GROK-14431)
193
196
  // @ts-ignore
194
- const prop = DG.Property.fromOptions({ "name": name, "inputType": "Float", min: 0, max: 10, "showSlider": true, "step": 1});
197
+ const prop = DG.Property.fromOptions({'name': name, 'inputType': 'Float', 'min': 0, 'max': 10, 'showSlider': true, 'step': 1});
195
198
  const weightInput = ui.input.forProperty(prop);
196
199
  weightInput.value = settings.defaultWeight;
197
200
  weightInput.onChanged(() => {
@@ -200,7 +203,7 @@ export function runKNNImputer(): void {
200
203
  featuresMetrics.set(name, distInfo);
201
204
  });
202
205
  weightInput.setTooltip(HINT.WEIGHT);
203
-
206
+
204
207
  const div = ui.divH([distTypeInput.root, weightInput.root]);
205
208
  metricInfoInputs.set(name, div);
206
209
  metricsDiv.append(div);
@@ -214,11 +217,27 @@ export function runKNNImputer(): void {
214
217
  keepEmptyInput.root.hidden = !areThereFails(targetColNames, selectedFeatureColNames, misValsInds);
215
218
 
216
219
  // Icon showing/hiding metrics UI
217
- const settingsIcon = ui.icons.settings(() => { metricsDiv.hidden = !metricsDiv.hidden;}, HINT.METRIC_SETTINGS);
220
+ const settingsIcon = ui.icons.settings(() => {metricsDiv.hidden = !metricsDiv.hidden;}, HINT.METRIC_SETTINGS);
218
221
 
219
222
  const distDiv = ui.divH([distTypeInput.root, settingsIcon]);
220
223
 
221
- dlg.addButton(TITLE.RUN, () => {
224
+ let resolve: (value: void | PromiseLike<void>) => void;
225
+ let reject: (reason?: any) => void;
226
+ let okClicked = false;
227
+ const promise = new Promise<void>((res, rej) => {
228
+ resolve = res;
229
+ reject = rej;
230
+ });
231
+ dlg.add(targetColInput)
232
+ .add(featuresInput)
233
+ .add(distDiv)
234
+ .add(metricsDiv)
235
+ .add(neighborsInput)
236
+ .add(inPlaceInput)
237
+ .add(keepEmptyInput)
238
+ .show()
239
+ .onOK(() => {
240
+ okClicked = true;
222
241
  dlg.close();
223
242
  availableFeatureColsNames.filter((name) => !selectedFeatureColNames.includes(name)).forEach((name) => featuresMetrics.delete(name));
224
243
 
@@ -227,20 +246,15 @@ export function runKNNImputer(): void {
227
246
 
228
247
  if (!keepEmpty)
229
248
  imputeFailed(df!, failedToImpute);
230
- }
231
- catch (err) {
249
+ resolve();
250
+ } catch (err) {
232
251
  if (err instanceof Error)
233
252
  grok.shell.error(`${ERROR_MSG.KNN_FAILS}: ${err.message}`);
234
253
  else
235
254
  grok.shell.error(`${ERROR_MSG.KNN_FAILS}: ${ERROR_MSG.CORE_ISSUE}`);
236
- }
237
- })
238
- .add(targetColInput)
239
- .add(featuresInput)
240
- .add(distDiv)
241
- .add(metricsDiv)
242
- .add(neighborsInput)
243
- .add(inPlaceInput)
244
- .add(keepEmptyInput)
245
- .show();
255
+ reject(err);
256
+ }
257
+ }).onClose.subscribe(() => !okClicked && reject());
258
+
259
+ return promise;
246
260
  } // runKNNImputer
package/src/package.ts CHANGED
@@ -10,7 +10,7 @@ import {computePCA} from './eda-tools';
10
10
  import {addPrefixToEachColumnName, addOneWayAnovaVizualization} from './eda-ui';
11
11
  import {testDataForBinaryClassification} from './data-generators';
12
12
  import {LINEAR, RBF, POLYNOMIAL, SIGMOID,
13
- getTrainedModel, getPrediction, isApplicableSVM, showTrainReport, getPackedModel} from './svm';
13
+ getTrainedModel, getPrediction, isApplicableSVM, isInteractiveSVM, showTrainReport, getPackedModel} from './svm';
14
14
 
15
15
  import {PLS_ANALYSIS} from './pls/pls-constants';
16
16
  import {runMVA, runDemoMVA, getPlsAnalysis, PlsOutput} from './pls/pls-tools';
@@ -334,12 +334,12 @@ export async function testDataLinearNonSeparable(name: string, sigma: number, sa
334
334
  //meta.mlname: linear kernel LS-SVM
335
335
  //meta.mlrole: train
336
336
  //input: dataframe df
337
- //input: string predict_column
337
+ //input: column predictColumn
338
338
  //input: double gamma = 1.0 {category: Hyperparameters}
339
339
  //output: dynamic model
340
- export async function trainLinearKernelSVM(df: DG.DataFrame, predict_column: string,
340
+ export async function trainLinearKernelSVM(df: DG.DataFrame, predictColumn: DG.Column,
341
341
  gamma: number): Promise<any> {
342
- const trainedModel = await getTrainedModel({gamma: gamma, kernel: LINEAR}, df, predict_column);
342
+ const trainedModel = await getTrainedModel({gamma: gamma, kernel: LINEAR}, df, predictColumn);
343
343
  return getPackedModel(trainedModel);
344
344
  }
345
345
 
@@ -357,21 +357,31 @@ export async function applyLinearKernelSVM(df: DG.DataFrame, model: any): Promis
357
357
  //meta.mlname: linear kernel LS-SVM
358
358
  //meta.mlrole: isApplicable
359
359
  //input: dataframe df
360
- //input: string predict_column
360
+ //input: column predictColumn
361
361
  //output: bool result
362
- export async function isApplicableLinearKernelSVM(df: DG.DataFrame, predict_column: string): Promise<boolean> {
363
- return isApplicableSVM(df, predict_column);
362
+ export async function isApplicableLinearKernelSVM(df: DG.DataFrame, predictColumn: DG.Column): Promise<boolean> {
363
+ return isApplicableSVM(df, predictColumn);
364
+ }
365
+
366
+ //name: isInteractiveLinearKernelSVM
367
+ //meta.mlname: linear kernel LS-SVM
368
+ //meta.mlrole: isInteractive
369
+ //input: dataframe df
370
+ //input: column predictColumn
371
+ //output: bool result
372
+ export async function isInteractiveLinearKernelSVM(df: DG.DataFrame, predictColumn: DG.Column): Promise<boolean> {
373
+ return isInteractiveSVM(df, predictColumn);
364
374
  }
365
375
 
366
376
  //name: visualizeLinearKernelSVM
367
377
  //meta.mlname: linear kernel LS-SVM
368
378
  //meta.mlrole: visualize
369
379
  //input: dataframe df
370
- //input: string target_column
371
- //input: string predict_column
380
+ //input: column targetColumn
381
+ //input: column predictColumn
372
382
  //input: dynamic model
373
383
  //output: dynamic widget
374
- export async function visualizeLinearKernelSVM(df: DG.DataFrame, target_column: string, predict_column: string, model: any): Promise<any> {
384
+ export async function visualizeLinearKernelSVM(df: DG.DataFrame, targetColumn: DG.Column, predictColumn: DG.Column, model: any): Promise<any> {
375
385
  return showTrainReport(df, model);
376
386
  }
377
387
 
@@ -380,15 +390,15 @@ export async function visualizeLinearKernelSVM(df: DG.DataFrame, target_column:
380
390
  //meta.mlname: RBF-kernel LS-SVM
381
391
  //meta.mlrole: train
382
392
  //input: dataframe df
383
- //input: string predict_column
393
+ //input: column predictColumn
384
394
  //input: double gamma = 1.0 {category: Hyperparameters}
385
395
  //input: double sigma = 1.5 {category: Hyperparameters}
386
396
  //output: dynamic model
387
- export async function trainRBFkernelSVM(df: DG.DataFrame, predict_column: string,
397
+ export async function trainRBFkernelSVM(df: DG.DataFrame, predictColumn: DG.Column,
388
398
  gamma: number, sigma: number): Promise<any> {
389
399
  const trainedModel = await getTrainedModel(
390
400
  {gamma: gamma, kernel: RBF, sigma: sigma},
391
- df, predict_column);
401
+ df, predictColumn);
392
402
 
393
403
  return getPackedModel(trainedModel);
394
404
  }
@@ -407,21 +417,32 @@ export async function applyRBFkernelSVM(df: DG.DataFrame, model: any): Promise<D
407
417
  //meta.mlname: RBF-kernel LS-SVM
408
418
  //meta.mlrole: isApplicable
409
419
  //input: dataframe df
410
- //input: string predict_column
420
+ //input: column predictColumn
421
+ //output: bool result
422
+ export async function isApplicableRBFkernelSVM(df: DG.DataFrame, predictColumn: DG.Column): Promise<boolean> {
423
+ return isApplicableSVM(df, predictColumn);
424
+ }
425
+
426
+ //name: isInteractiveRBFkernelSVM
427
+ //meta.mlname: RBF-kernel LS-SVM
428
+ //meta.mlrole: isInteractive
429
+ //input: dataframe df
430
+ //input: column predictColumn
411
431
  //output: bool result
412
- export async function isApplicableRBFkernelSVM(df: DG.DataFrame, predict_column: string): Promise<boolean> {
413
- return isApplicableSVM(df, predict_column);
432
+ export async function isInteractiveRBFkernelSVM(df: DG.DataFrame, predictColumn: DG.Column): Promise<boolean> {
433
+ return isInteractiveSVM(df, predictColumn);
414
434
  }
415
435
 
436
+
416
437
  //name: visualizeRBFkernelSVM
417
438
  //meta.mlname: RBF-kernel LS-SVM
418
439
  //meta.mlrole: visualize
419
440
  //input: dataframe df
420
- //input: string target_column
421
- //input: string predict_column
441
+ //input: column targetColumn
442
+ //input: column predictColumn
422
443
  //input: dynamic model
423
444
  //output: dynamic widget
424
- export async function visualizeRBFkernelSVM(df: DG.DataFrame, target_column: string, predict_column: string, model: any): Promise<any> {
445
+ export async function visualizeRBFkernelSVM(df: DG.DataFrame, targetColumn: DG.Column, predictColumn: DG.Column, model: any): Promise<any> {
425
446
  return showTrainReport(df, model);
426
447
  }
427
448
 
@@ -429,16 +450,16 @@ export async function visualizeRBFkernelSVM(df: DG.DataFrame, target_column: str
429
450
  //meta.mlname: polynomial kernel LS-SVM
430
451
  //meta.mlrole: train
431
452
  //input: dataframe df
432
- //input: string predict_column
453
+ //input: column predictColumn
433
454
  //input: double gamma = 1.0 {category: Hyperparameters}
434
455
  //input: double c = 1 {category: Hyperparameters}
435
456
  //input: double d = 2 {category: Hyperparameters}
436
457
  //output: dynamic model
437
- export async function trainPolynomialKernelSVM(df: DG.DataFrame, predict_column: string,
458
+ export async function trainPolynomialKernelSVM(df: DG.DataFrame, predictColumn: DG.Column,
438
459
  gamma: number, c: number, d: number): Promise<any> {
439
460
  const trainedModel = await getTrainedModel(
440
461
  {gamma: gamma, kernel: POLYNOMIAL, cParam: c, dParam: d},
441
- df, predict_column);
462
+ df, predictColumn);
442
463
 
443
464
  return getPackedModel(trainedModel);
444
465
  } // trainPolynomialKernelSVM
@@ -457,21 +478,31 @@ export async function applyPolynomialKernelSVM(df: DG.DataFrame, model: any): Pr
457
478
  //meta.mlname: polynomial kernel LS-SVM
458
479
  //meta.mlrole: isApplicable
459
480
  //input: dataframe df
460
- //input: string predict_column
481
+ //input: column predictColumn
482
+ //output: bool result
483
+ export async function isApplicablePolynomialKernelSVM(df: DG.DataFrame, predictColumn: DG.Column): Promise<boolean> {
484
+ return isApplicableSVM(df, predictColumn);
485
+ }
486
+
487
+ //name: isInteractivePolynomialKernelSVM
488
+ //meta.mlname: polynomial kernel LS-SVM
489
+ //meta.mlrole: isInteractive
490
+ //input: dataframe df
491
+ //input: column predictColumn
461
492
  //output: bool result
462
- export async function isApplicablePolynomialKernelSVM(df: DG.DataFrame, predict_column: string): Promise<boolean> {
463
- return isApplicableSVM(df, predict_column);
493
+ export async function isInteractivePolynomialKernelSVM(df: DG.DataFrame, predictColumn: DG.Column): Promise<boolean> {
494
+ return isInteractiveSVM(df, predictColumn);
464
495
  }
465
496
 
466
497
  //name: visualizePolynomialKernelSVM
467
498
  //meta.mlname: polynomial kernel LS-SVM
468
499
  //meta.mlrole: visualize
469
500
  //input: dataframe df
470
- //input: string target_column
471
- //input: string predict_column
501
+ //input: column targetColumn
502
+ //input: column predictColumn
472
503
  //input: dynamic model
473
504
  //output: dynamic widget
474
- export async function visualizePolynomialKernelSVM(df: DG.DataFrame, target_column: string, predict_column: string, model: any): Promise<any> {
505
+ export async function visualizePolynomialKernelSVM(df: DG.DataFrame, targetColumn: DG.Column, predictColumn: DG.Column, model: any): Promise<any> {
475
506
  return showTrainReport(df, model);
476
507
  }
477
508
 
@@ -479,16 +510,16 @@ export async function visualizePolynomialKernelSVM(df: DG.DataFrame, target_colu
479
510
  //meta.mlname: sigmoid kernel LS-SVM
480
511
  //meta.mlrole: train
481
512
  //input: dataframe df
482
- //input: string predict_column
513
+ //input: column predictColumn
483
514
  //input: double gamma = 1.0 {category: Hyperparameters}
484
515
  //input: double kappa = 1 {category: Hyperparameters}
485
516
  //input: double theta = 1 {category: Hyperparameters}
486
517
  //output: dynamic model
487
- export async function trainSigmoidKernelSVM(df: DG.DataFrame, predict_column: string,
518
+ export async function trainSigmoidKernelSVM(df: DG.DataFrame, predictColumn: DG.Column,
488
519
  gamma: number, kappa: number, theta: number): Promise<any> {
489
520
  const trainedModel = await getTrainedModel(
490
521
  {gamma: gamma, kernel: SIGMOID, kappa: kappa, theta: theta},
491
- df, predict_column);
522
+ df, predictColumn);
492
523
 
493
524
  return getPackedModel(trainedModel);
494
525
  } // trainSigmoidKernelSVM
@@ -507,21 +538,31 @@ export async function applySigmoidKernelSVM(df: DG.DataFrame, model: any): Promi
507
538
  //meta.mlname: sigmoid kernel LS-SVM
508
539
  //meta.mlrole: isApplicable
509
540
  //input: dataframe df
510
- //input: string predict_column
541
+ //input: column predictColumn
511
542
  //output: bool result
512
- export async function isApplicableSigmoidKernelSVM(df: DG.DataFrame, predict_column: string): Promise<boolean> {
513
- return isApplicableSVM(df, predict_column);
543
+ export async function isApplicableSigmoidKernelSVM(df: DG.DataFrame, predictColumn: DG.Column): Promise<boolean> {
544
+ return isApplicableSVM(df, predictColumn);
545
+ }
546
+
547
+ //name: isInteractiveSigmoidKernelSVM
548
+ //meta.mlname: sigmoid kernel LS-SVM
549
+ //meta.mlrole: isInteractive
550
+ //input: dataframe df
551
+ //input: column predictColumn
552
+ //output: bool result
553
+ export async function isInteractiveSigmoidKernelSVM(df: DG.DataFrame, predictColumn: DG.Column): Promise<boolean> {
554
+ return isInteractiveSVM(df, predictColumn);
514
555
  }
515
556
 
516
557
  //name: visualizeSigmoidKernelSVM
517
558
  //meta.mlname: sigmoid kernel LS-SVM
518
559
  //meta.mlrole: visualize
519
560
  //input: dataframe df
520
- //input: string target_column
521
- //input: string predict_column
561
+ //input: column targetColumn
562
+ //input: column predictColumn
522
563
  //input: dynamic model
523
564
  //output: dynamic widget
524
- export async function visualizeSigmoidKernelSVM(df: DG.DataFrame, target_column: string, predict_column: string, model: any): Promise<any> {
565
+ export async function visualizeSigmoidKernelSVM(df: DG.DataFrame, targetColumn: DG.Column, predictColumn: DG.Column, model: any): Promise<any> {
525
566
  return showTrainReport(df, model);
526
567
  }
527
568
 
@@ -545,6 +586,13 @@ export function kNNImputation() {
545
586
  runKNNImputer();
546
587
  }
547
588
 
589
+ //name: KNN imputation for a table
590
+ //desription: Missing values imputation using the k-nearest neighbors method for a given table
591
+ //input: dataframe table
592
+ export async function kNNImputationForTable(table: DG.DataFrame) {
593
+ await runKNNImputer(table);
594
+ }
595
+
548
596
  //name: linearRegression
549
597
  //description: Linear Regression demo
550
598
  //input: dataframe table
@@ -591,14 +639,11 @@ export function generateDatasetForLinearRegressionTest(rowCount: number, colCoun
591
639
  //meta.mlname: Linear Regression
592
640
  //meta.mlrole: train
593
641
  //input: dataframe df
594
- //input: string predict_column
642
+ //input: column predictColumn
595
643
  //output: dynamic model
596
- export async function trainLinearRegression(df: DG.DataFrame, predict_column: string): Promise<Uint8Array> {
644
+ export async function trainLinearRegression(df: DG.DataFrame, predictColumn: DG.Column): Promise<Uint8Array> {
597
645
  const features = df.columns;
598
- const target = features.byName(predict_column);
599
- features.remove(predict_column);
600
-
601
- const params = await getLinearRegressionParams(features, target);
646
+ const params = await getLinearRegressionParams(features, predictColumn);
602
647
 
603
648
  return new Uint8Array(params.buffer);
604
649
  }
@@ -619,12 +664,25 @@ export function applyLinearRegression(df: DG.DataFrame, model: any): DG.DataFram
619
664
  //meta.mlname: Linear Regression
620
665
  //meta.mlrole: isApplicable
621
666
  //input: dataframe df
622
- //input: string predict_column
667
+ //input: column predictColumn
623
668
  //output: bool result
624
- export function isApplicableLinearRegression(df: DG.DataFrame, predict_column: string): boolean {
669
+ export function isApplicableLinearRegression(df: DG.DataFrame, predictColumn: DG.Column): boolean {
625
670
  for (const col of df.columns) {
626
- if ((col.type !== DG.COLUMN_TYPE.INT) && (col.type !== DG.COLUMN_TYPE.FLOAT) && (col.type !== DG.COLUMN_TYPE.QNUM) && (col.type !== DG.COLUMN_TYPE.BIG_INT))
671
+ if (!col.matches('numerical'))
627
672
  return false;
628
673
  }
674
+ if (!predictColumn.matches('numerical'))
675
+ return false;
676
+
629
677
  return true;
630
678
  }
679
+
680
+ //name: isInteractiveLinearRegression
681
+ //meta.mlname: Linear Regression
682
+ //meta.mlrole: isInteractive
683
+ //input: dataframe df
684
+ //input: column predictColumn
685
+ //output: bool result
686
+ export function isInteractiveLinearRegression(df: DG.DataFrame, predictColumn: DG.Column): boolean {
687
+ return df.rowCount <= 100000;
688
+ }
@@ -283,17 +283,16 @@ export async function runMVA(analysisType: PLS_ANALYSIS): Promise<void> {
283
283
 
284
284
  // responce (to predict)
285
285
  let predict = numCols[numCols.length - 1];
286
- const predictInput = ui.columnInput(TITLE.PREDICT, table, predict, () => {
286
+ const predictInput = ui.input.column(TITLE.PREDICT, {table: table, value: predict, onValueChanged: () => {
287
287
  predict = predictInput.value!;
288
288
  updateIputs();
289
- },
290
- {filter: (col: DG.Column) => isValidNumeric(col)},
289
+ }, filter: (col: DG.Column) => isValidNumeric(col)},
291
290
  );
292
291
  predictInput.setTooltip(HINT.PREDICT);
293
292
 
294
293
  // predictors (features)
295
294
  let features: DG.Column[];
296
- const featuresInput = ui.columnsInput(TITLE.USING, table, () => {}, {available: numColNames});
295
+ const featuresInput = ui.input.columns(TITLE.USING, {table: table, available: numColNames});
297
296
  featuresInput.onInput(() => updateIputs());
298
297
  featuresInput.setTooltip(HINT.FEATURES);
299
298
 
@@ -336,8 +335,8 @@ export async function runMVA(analysisType: PLS_ANALYSIS): Promise<void> {
336
335
 
337
336
  // names of samples
338
337
  let names = (strCols.length > 0) ? strCols[0] : null;
339
- const namesInputs = ui.columnInput(TITLE.NAMES, table, names, () => names = predictInput.value,
340
- {filter: (col: DG.Column) => col.type === DG.COLUMN_TYPE.STRING},
338
+ const namesInputs = ui.input.column(TITLE.NAMES, {table: table, value: names!, onValueChanged: () => names = predictInput.value,
339
+ filter: (col: DG.Column) => col.type === DG.COLUMN_TYPE.STRING},
341
340
  );
342
341
  namesInputs.setTooltip(HINT.NAMES);
343
342
  namesInputs.root.hidden = (strCols.length === 0) || (analysisType === PLS_ANALYSIS.COMPUTE_COMPONENTS);