mirror of
https://github.com/hsokolowski/iTree.git
synced 2026-06-11 06:14:20 -04:00
init
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,3 +21,4 @@
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.eslintcache
|
||||
|
||||
1825
package-lock.json
generated
1825
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -3,11 +3,19 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@chakra-ui/icons": "^1.0.3",
|
||||
"@chakra-ui/react": "^1.1.4",
|
||||
"@emotion/react": "^11.1.4",
|
||||
"@emotion/styled": "^11.0.0",
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
"@testing-library/react": "^11.2.3",
|
||||
"@testing-library/user-event": "^12.6.0",
|
||||
"csv-parse": "^4.14.2",
|
||||
"framer-motion": "^3.2.1",
|
||||
"node-sass": "^4.14.1",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-file-reader": "^1.1.4",
|
||||
"react-scripts": "4.0.1",
|
||||
"web-vitals": "^0.2.4"
|
||||
},
|
||||
@@ -34,5 +42,9 @@
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^7.18.0",
|
||||
"eslint-plugin-react": "^7.22.0"
|
||||
}
|
||||
}
|
||||
|
||||
33
src/App.js
33
src/App.js
@@ -1,25 +1,18 @@
|
||||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
import React from "react";
|
||||
//import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
|
||||
import "./css/App.scss";
|
||||
import Main from './components/Main'
|
||||
import { ChakraProvider , CSSReset } from "@chakra-ui/react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src={logo} className="App-logo" alt="logo" />
|
||||
<p>
|
||||
Edit <code>src/App.js</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<ChakraProvider >
|
||||
<CSSReset />
|
||||
<div id="app" className="App">
|
||||
<Main></Main>
|
||||
</div>
|
||||
</ChakraProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
78
src/components/FileReader.js
Normal file
78
src/components/FileReader.js
Normal file
@@ -0,0 +1,78 @@
|
||||
import React, { useState } from "react";
|
||||
import ReactFileReader from "react-file-reader";
|
||||
//import { IconButton, Button,Stack } from "@chakra-ui/react";
|
||||
import { readLocalFile } from "../utils/file-reader";
|
||||
import parseCsv from "csv-parse/lib/sync";
|
||||
|
||||
function FileReader() {
|
||||
const [dataSet, setDataSet] = useState(null);
|
||||
const [parameters, setParameters] = useState(null);
|
||||
const [ignoreParameters, setignoreParameters] = useState(null);
|
||||
|
||||
// const handleFiles = files => {
|
||||
// console.log(files)
|
||||
// let reader = new FileReader();
|
||||
// reader.onload = () => {
|
||||
// // Use reader.result
|
||||
// console.log(reader.result);
|
||||
// //getting attribute parameters decison tree
|
||||
// // let firstLine = reader.result.split('\n').shift();
|
||||
// // console.log(firstLine);
|
||||
// // let clearVars = firstLine.replace(/['"]+/g, '');
|
||||
// // console.log(clearVars);
|
||||
// // let params = clearVars.split(',');
|
||||
// // ////console.log(params);
|
||||
// // let ignore = params.slice();
|
||||
// // ignore.unshift("-EMPTY-");
|
||||
// // ignore[ignore.length-1]=ignore[ignore.length-1].substring(0, ignore[ignore.length-1].length - 1);
|
||||
|
||||
// // let jsonObj = csv.toObjects(reader.result);
|
||||
// // console.log(jsonObj);
|
||||
|
||||
// // setDataSet(jsonObj)
|
||||
// // setParameters(params)
|
||||
// // setignoreParameters(ignore)
|
||||
|
||||
// }
|
||||
// reader.readAsText(files[0]);
|
||||
// // console.log(parameters,ignoreParameters);
|
||||
// // console.log(dataSet);
|
||||
// };
|
||||
const handleFiles = async (files) => {
|
||||
const file = await readLocalFile(files[0]);
|
||||
console.log(file);
|
||||
const clean = file
|
||||
.split("\n")
|
||||
.map((line) => {
|
||||
return line.replace(/(^"|"$)/g, "");
|
||||
})
|
||||
.join("\n");
|
||||
const data = parseCsv(clean, {
|
||||
columns: (h) => {
|
||||
//console.log(h);
|
||||
return h.map((v, i) => v || `attr${i}`);
|
||||
},
|
||||
comment: "#",
|
||||
skipEmptyLines: true,
|
||||
delimiter: [",", "\t"],
|
||||
});
|
||||
//const data = parseCsv(file,{columns: true, comment: "#",skipEmptyLines: true,})
|
||||
console.log(data);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ReactFileReader
|
||||
multipleFiles={false}
|
||||
fileTypes={[".csv"]}
|
||||
handleFiles={handleFiles}
|
||||
>
|
||||
<div className="btn" id="uploadBtn">
|
||||
<i className="icon-upload-1"></i>Deploy
|
||||
</div>
|
||||
</ReactFileReader>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FileReader;
|
||||
23
src/components/Main.js
Normal file
23
src/components/Main.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from "react";
|
||||
import '../css/main.scss'
|
||||
import Tree from './Tree'
|
||||
//import {start} from '../services/Playground.js'
|
||||
import * as model from '../data/mock.data.json'
|
||||
import Navigation from "./Navigation";
|
||||
import {builder} from '../services/Playground'
|
||||
|
||||
function Main() {
|
||||
//console.log(builder);
|
||||
return (
|
||||
<div id="main" className="main">
|
||||
<Navigation />
|
||||
{/* <Button onClick={start}>Drzewo</Button> */}
|
||||
<br></br>
|
||||
<div>
|
||||
<Tree options={builder}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Main;
|
||||
38
src/components/Navigation.js
Normal file
38
src/components/Navigation.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import React from "react";
|
||||
import "../css/main.scss";
|
||||
import { IconButton, Button,Stack } from "@chakra-ui/react";
|
||||
import { PhoneIcon, AddIcon, WarningIcon, SearchIcon } from "@chakra-ui/icons";
|
||||
import FileReader from "./FileReader";
|
||||
|
||||
function Navigation() {
|
||||
return (
|
||||
<div id="navigation-navbar" className="center-horizontal">
|
||||
<div style={{ padding: "10px" }}>
|
||||
<Stack spacing={4} direction="row" align="center">
|
||||
<Button colorScheme="teal" size="md">
|
||||
<FileReader/>
|
||||
</Button>
|
||||
<Button colorScheme="teal" size="md">
|
||||
Button
|
||||
</Button>
|
||||
<Button colorScheme="teal" size="md">
|
||||
Button
|
||||
</Button>
|
||||
<Button colorScheme="teal" size="md">
|
||||
Button
|
||||
</Button>
|
||||
</Stack>
|
||||
<IconButton aria-label="Search database" icon={<SearchIcon />} />
|
||||
Hello there
|
||||
<IconButton aria-label="Search database" icon={<AddIcon />} />
|
||||
Hello there
|
||||
<IconButton aria-label="Search database" icon={<WarningIcon />} />
|
||||
Hello there
|
||||
<IconButton aria-label="Search database" icon={<PhoneIcon />} />
|
||||
Hello there
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Navigation;
|
||||
81
src/components/Node.jsx
Normal file
81
src/components/Node.jsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import React, { useState } from "react";
|
||||
//import { addNode } from "./utils";
|
||||
|
||||
const Node = (props) => {
|
||||
console.log(props.node);
|
||||
const [highlighted, setHighlighted] = useState(false);
|
||||
const [node, setNode] = useState(props.node) || {};
|
||||
console.log(node);
|
||||
const {
|
||||
category,
|
||||
quality,
|
||||
matchedCount,
|
||||
notMatchedCount,
|
||||
match,
|
||||
notMatch,
|
||||
attr2,
|
||||
predicateName,
|
||||
pivot,
|
||||
} = node || {};
|
||||
|
||||
const onNodeClicked = (e) => {
|
||||
console.log(e);
|
||||
e.stopPropagation();
|
||||
console.log("Node clicked", node);
|
||||
//const changed = addComment(node);
|
||||
//props.onChange(changed);
|
||||
//setNode(changed);
|
||||
setHighlighted(true);
|
||||
setTimeout(() => setHighlighted(false), 500);
|
||||
};
|
||||
|
||||
const onChange = (node) => {
|
||||
const index = match.findIndex((c) => c.id === node.id);
|
||||
match.splice(index, 1, node);
|
||||
props.node.match = [...match];
|
||||
};
|
||||
|
||||
var NODE = null;
|
||||
console.log(category);
|
||||
if (!category) {
|
||||
console.log("JOINT");
|
||||
NODE = Joint(attr2,predicateName,pivot,match,notMatch,onChange)
|
||||
} else {
|
||||
console.log("LEAF");
|
||||
NODE = Leaf(category, matchedCount, notMatchedCount, quality);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`node ${highlighted ? "highlight" : ""}`}
|
||||
onClick={onNodeClicked}
|
||||
>
|
||||
{NODE}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Node;
|
||||
|
||||
function Leaf(category, matchedCount, notMatchedCount, quality) {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
{category} {matchedCount} {notMatchedCount} {quality}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Joint(attr2,predicateName,pivot,match,notMatch,onChange) {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
{attr2} <b>{predicateName}</b> {pivot}
|
||||
</p>
|
||||
<Node node={match} onChange={onChange} />
|
||||
<Node node={notMatch} onChange={onChange} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
268
src/components/Tree.jsx
Normal file
268
src/components/Tree.jsx
Normal file
@@ -0,0 +1,268 @@
|
||||
import React, {useMemo, useState }from "react";
|
||||
import { start } from "../services/Playground";
|
||||
import { dt } from "../services/TSP";
|
||||
//import Node from "./Node";
|
||||
|
||||
const Tree = ({options}) => {
|
||||
// const tree = useMemo(()=>{
|
||||
// //return dt.TSPDecisionTree(options)
|
||||
// var abc = start(options)
|
||||
|
||||
// console.log(abc);
|
||||
// return abc
|
||||
// },[options])
|
||||
const [aaaaaa,setTree] = useState(buildDecisionTree(options))
|
||||
|
||||
const logTree = () => console.log(aaaaaa);
|
||||
|
||||
console.log(aaaaaa)
|
||||
|
||||
function buildDecisionTree(builder, isChanged = false) {
|
||||
debugger;
|
||||
var trainingSet = builder.trainingSet;
|
||||
var minItemsCount = builder.minItemsCount;
|
||||
var categoryAttr = builder.categoryAttr;
|
||||
var entropyThrehold = builder.entropyThrehold;
|
||||
var maxTreeDepth = builder.maxTreeDepth;
|
||||
var ignoredAttributes = builder.ignoredAttributes;
|
||||
//console.log("########## NOWY WEZEL ########", trainingSet.length);
|
||||
var _quality = 0;
|
||||
if (maxTreeDepth === 0 || trainingSet.length <= minItemsCount) {
|
||||
//console.log(
|
||||
// "LISC BO MAX TREE DEPTH",
|
||||
// maxTreeDepth,
|
||||
// "LISC ILOSC",
|
||||
// trainingSet.length
|
||||
//);
|
||||
//gger;
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log("KATEGORIA JAKO:", _category);
|
||||
trainingSet.forEach((element) => {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
//ugger;
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet.map(x=> x[categoryAttr])
|
||||
};
|
||||
}
|
||||
var attributes = builder.allAttributes.filter(function (el) {
|
||||
return ![...ignoredAttributes, categoryAttr].includes(el);
|
||||
});
|
||||
//console.log(builder.minItemsCount, builder.trainingSet.length);
|
||||
|
||||
// tu juz musi byc przekazana cm wyzerowana
|
||||
|
||||
var podzial = [];
|
||||
//console.log(attributes);
|
||||
var right = 0,
|
||||
left = 0;
|
||||
var maxDif = 100,
|
||||
attribute1 = -1,
|
||||
attribute2 = -1;
|
||||
var directrion = "<";
|
||||
var leftList = [],
|
||||
rightList = [],
|
||||
classMatrix = [
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
],
|
||||
match = [],
|
||||
notMatch = [];
|
||||
for (let i = 0; i < attributes.length; i++) {
|
||||
let attr1 = attributes[i];
|
||||
for (let j = 0; j < attributes.length; j++) {
|
||||
let attr2 = attributes[j];
|
||||
if (attr1 !== attr2) {
|
||||
right = left = 0;
|
||||
leftList = [];
|
||||
rightList = [];
|
||||
classMatrix = [
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
];
|
||||
|
||||
for (let index = 0; index < trainingSet.length; index++) {
|
||||
const element = trainingSet[index];
|
||||
|
||||
if (element[attr1] < element[attr2]) {
|
||||
left++;
|
||||
leftList.push(element);
|
||||
classMatrix[0][builder.allClasses.indexOf(element[categoryAttr])]++;
|
||||
} else {
|
||||
right++;
|
||||
rightList.push(element);
|
||||
classMatrix[1][builder.allClasses.indexOf(element[categoryAttr])]++;
|
||||
}
|
||||
}
|
||||
//console.log(classMatrix);
|
||||
var probR = 0,
|
||||
probL = 0,
|
||||
rankL = 0,
|
||||
rankR = 0;
|
||||
for (let k = 0; k < builder.allClasses.length; k++) {
|
||||
probL = left === 0 ? 0 : classMatrix[0][k] / left;
|
||||
probR = right === 0 ? 0 : classMatrix[1][k] / right;
|
||||
|
||||
rankL += probL * probL;
|
||||
rankR += probR * probR;
|
||||
}
|
||||
//console.log("Rank Lewy",rankL,"Rank Prawy",rankR);
|
||||
|
||||
var currentDif =
|
||||
(right / trainingSet.length) * (1 - rankR) +
|
||||
(left / trainingSet.length) * (1 - rankL);
|
||||
if (currentDif < maxDif) {
|
||||
//console.log("------Zapisanie maxDif-------");
|
||||
//console.log(attr1,attr2);
|
||||
//console.log("R/L ", right + ":" + left);
|
||||
//console.log("cur/mD",currentDif + ":" + maxDif);
|
||||
maxDif = currentDif;
|
||||
attribute1 = attr1;
|
||||
attribute2 = attr2;
|
||||
match = leftList;
|
||||
notMatch = rightList;
|
||||
podzial = classMatrix;
|
||||
//console.log("-----------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log("PO WYLICZENIU NAJLEPSZEGO");
|
||||
//console.log(attribute1, attribute2);
|
||||
//console.log("L/R ", match.length + ":" + notMatch.length);
|
||||
//console.log(podzial);
|
||||
//console.log("MaxDifference:", maxDif);
|
||||
if (!maxDif) {
|
||||
//console.log("LISC BO MAX DIF ZERO", trainingSet.length);
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log("KATEGORIA JAKO:", _category);
|
||||
trainingSet.forEach((element) => {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet.map(x=> x[categoryAttr])
|
||||
};
|
||||
}
|
||||
// sprawdzic
|
||||
// wssytskies stringi do ignored
|
||||
if (match.length === 0 || notMatch.length === 0) {
|
||||
//console.log("LISC BO JEDNA ZE STRON MA 0");
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log(_category);
|
||||
trainingSet.forEach((element) => {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
// restriction by maximal depth of tree
|
||||
// or size of training set is to small
|
||||
// so we have to terminate process of building tree
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet.map(x=> x[categoryAttr])
|
||||
};
|
||||
}
|
||||
|
||||
builder.maxTreeDepth = maxTreeDepth - 1;
|
||||
//builder.trainingSet = match;
|
||||
//var matchSubTree = buildDecisionTree(builder);
|
||||
|
||||
//builder.trainingSet = notMatch;
|
||||
//var notMatchSubTree = buildDecisionTree(builder);
|
||||
console.log("TUTAJ");
|
||||
return {
|
||||
attr2: attribute2,
|
||||
pivot: attribute1,
|
||||
predicateName: directrion,
|
||||
//match: matchSubTree,
|
||||
//notMatch: notMatchSubTree, //{category: ...}
|
||||
matchedCount: match.length,
|
||||
notMatchedCount: notMatch.length,
|
||||
};
|
||||
//console.log(attributes);
|
||||
}
|
||||
function countUniqueValues(items, attr) {
|
||||
var counter = {};
|
||||
|
||||
// detecting different values of attribute
|
||||
for (var i = items.length - 1; i >= 0; i--) {
|
||||
// items[i][attr] - value of attribute
|
||||
counter[items[i][attr]] = 0;
|
||||
}
|
||||
|
||||
// counting number of occurrences of each of values
|
||||
// of attribute
|
||||
for (var j = items.length - 1; j >= 0; j--) {
|
||||
counter[items[j][attr]] += 1;
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
function mostFrequentValue(items, attr) {
|
||||
// counting number of occurrences of each of values
|
||||
// of attribute
|
||||
var counter = countUniqueValues(items, attr);
|
||||
|
||||
var mostFrequentCount = 0;
|
||||
var mostFrequentValue;
|
||||
|
||||
for (var value in counter) {
|
||||
if (counter[value] > mostFrequentCount) {
|
||||
mostFrequentCount = counter[value];
|
||||
mostFrequentValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
return mostFrequentValue;
|
||||
}
|
||||
function getAllClasses(set, cattegoryAttr) {
|
||||
let array = [];
|
||||
set.forEach((element) => {
|
||||
let _class = element[cattegoryAttr];
|
||||
if (!array.includes(_class)) array.push(_class);
|
||||
});
|
||||
console.log(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
return (
|
||||
<div id='tree'>
|
||||
<h1>Tree</h1>
|
||||
<p>
|
||||
<button onClick={logTree}>Log tree</button>
|
||||
</p>
|
||||
<h2>Nodes:</h2>
|
||||
{/* <Node node={tree} onChange={() => {}} /> */}
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
//{/* */}
|
||||
|
||||
export default Tree;
|
||||
50
src/css/main.scss
Normal file
50
src/css/main.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
$gainsboro: #d8dbe2ff;
|
||||
$light-steel-blue: #a9bcd0ff;
|
||||
$cadet-blue: #58a4b0ff;
|
||||
$charcoal: #373f51ff;
|
||||
$raisin-black: #1b1b1eff;
|
||||
//gradients https://coolors.co/d8dbe2-a9bcd0-58a4b0-373f51-1b1b1e
|
||||
$gradient-top: linear-gradient(0deg, #d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
$gradient-right: linear-gradient(90deg, #d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
$gradient-bottom: linear-gradient(180deg, #d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
$gradient-left: linear-gradient(270deg, #d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
$gradient-top-right: linear-gradient(45deg, #d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
$gradient-bottom-right: linear-gradient(135deg, #d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
$gradient-top-left: linear-gradient(225deg, #d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
$gradient-bottom-left: linear-gradient(315deg, #d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
$gradient-radial: radial-gradient(#d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1b1b1eff);
|
||||
|
||||
.center-horizontal {
|
||||
background-color: #09f;
|
||||
}
|
||||
.center-vertical {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.center-all {
|
||||
@extend .center-horizontal, .center-vertical;
|
||||
}
|
||||
.main {
|
||||
height: 100vh;
|
||||
background-color: azure;
|
||||
}
|
||||
#navigation-navbar {
|
||||
background-color: red;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.node {
|
||||
margin-left: 2em;
|
||||
transition: all 0.5s;
|
||||
background: white;
|
||||
color: #333;
|
||||
}
|
||||
.node.highlight {
|
||||
background: #09f;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#tree {
|
||||
text-align: left;
|
||||
}
|
||||
30170
src/data/US_Politics_Twitter.json
Normal file
30170
src/data/US_Politics_Twitter.json
Normal file
File diff suppressed because it is too large
Load Diff
28383
src/data/ar2.json
Normal file
28383
src/data/ar2.json
Normal file
File diff suppressed because it is too large
Load Diff
115493
src/data/arrythmia.json
Normal file
115493
src/data/arrythmia.json
Normal file
File diff suppressed because it is too large
Load Diff
152
src/data/iris.json
Normal file
152
src/data/iris.json
Normal file
@@ -0,0 +1,152 @@
|
||||
[
|
||||
{"sepalLength": 5.1, "sepalWidth": 3.5, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.9, "sepalWidth": 3.0, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.7, "sepalWidth": 3.2, "petalLength": 1.3, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.6, "sepalWidth": 3.1, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 3.6, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.4, "sepalWidth": 3.9, "petalLength": 1.7, "petalWidth": 0.4, "species": "setosa"},
|
||||
{"sepalLength": 4.6, "sepalWidth": 3.4, "petalLength": 1.4, "petalWidth": 0.3, "species": "setosa"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 3.4, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.4, "sepalWidth": 2.9, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.9, "sepalWidth": 3.1, "petalLength": 1.5, "petalWidth": 0.1, "species": "setosa"},
|
||||
{"sepalLength": 5.4, "sepalWidth": 3.7, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.8, "sepalWidth": 3.4, "petalLength": 1.6, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.8, "sepalWidth": 3.0, "petalLength": 1.4, "petalWidth": 0.1, "species": "setosa"},
|
||||
{"sepalLength": 4.3, "sepalWidth": 3.0, "petalLength": 1.1, "petalWidth": 0.1, "species": "setosa"},
|
||||
{"sepalLength": 5.8, "sepalWidth": 4.0, "petalLength": 1.2, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.7, "sepalWidth": 4.4, "petalLength": 1.5, "petalWidth": 0.4, "species": "setosa"},
|
||||
{"sepalLength": 5.4, "sepalWidth": 3.9, "petalLength": 1.3, "petalWidth": 0.4, "species": "setosa"},
|
||||
{"sepalLength": 5.1, "sepalWidth": 3.5, "petalLength": 1.4, "petalWidth": 0.3, "species": "setosa"},
|
||||
{"sepalLength": 5.7, "sepalWidth": 3.8, "petalLength": 1.7, "petalWidth": 0.3, "species": "setosa"},
|
||||
{"sepalLength": 5.1, "sepalWidth": 3.8, "petalLength": 1.5, "petalWidth": 0.3, "species": "setosa"},
|
||||
{"sepalLength": 5.4, "sepalWidth": 3.4, "petalLength": 1.7, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.1, "sepalWidth": 3.7, "petalLength": 1.5, "petalWidth": 0.4, "species": "setosa"},
|
||||
{"sepalLength": 4.6, "sepalWidth": 3.6, "petalLength": 1.0, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.1, "sepalWidth": 3.3, "petalLength": 1.7, "petalWidth": 0.5, "species": "setosa"},
|
||||
{"sepalLength": 4.8, "sepalWidth": 3.4, "petalLength": 1.9, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 3.0, "petalLength": 1.6, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 3.4, "petalLength": 1.6, "petalWidth": 0.4, "species": "setosa"},
|
||||
{"sepalLength": 5.2, "sepalWidth": 3.5, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.2, "sepalWidth": 3.4, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.7, "sepalWidth": 3.2, "petalLength": 1.6, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.8, "sepalWidth": 3.1, "petalLength": 1.6, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.4, "sepalWidth": 3.4, "petalLength": 1.5, "petalWidth": 0.4, "species": "setosa"},
|
||||
{"sepalLength": 5.2, "sepalWidth": 4.1, "petalLength": 1.5, "petalWidth": 0.1, "species": "setosa"},
|
||||
{"sepalLength": 5.5, "sepalWidth": 4.2, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.9, "sepalWidth": 3.1, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 3.2, "petalLength": 1.2, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.5, "sepalWidth": 3.5, "petalLength": 1.3, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.9, "sepalWidth": 3.6, "petalLength": 1.4, "petalWidth": 0.1, "species": "setosa"},
|
||||
{"sepalLength": 4.4, "sepalWidth": 3.0, "petalLength": 1.3, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.1, "sepalWidth": 3.4, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 3.5, "petalLength": 1.3, "petalWidth": 0.3, "species": "setosa"},
|
||||
{"sepalLength": 4.5, "sepalWidth": 2.3, "petalLength": 1.3, "petalWidth": 0.3, "species": "setosa"},
|
||||
{"sepalLength": 4.4, "sepalWidth": 3.2, "petalLength": 1.3, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 3.5, "petalLength": 1.6, "petalWidth": 0.6, "species": "setosa"},
|
||||
{"sepalLength": 5.1, "sepalWidth": 3.8, "petalLength": 1.9, "petalWidth": 0.4, "species": "setosa"},
|
||||
{"sepalLength": 4.8, "sepalWidth": 3.0, "petalLength": 1.4, "petalWidth": 0.3, "species": "setosa"},
|
||||
{"sepalLength": 5.1, "sepalWidth": 3.8, "petalLength": 1.6, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 4.6, "sepalWidth": 3.2, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.3, "sepalWidth": 3.7, "petalLength": 1.5, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 3.3, "petalLength": 1.4, "petalWidth": 0.2, "species": "setosa"},
|
||||
{"sepalLength": 7.0, "sepalWidth": 3.2, "petalLength": 4.7, "petalWidth": 1.4, "species": "versicolor"},
|
||||
{"sepalLength": 6.4, "sepalWidth": 3.2, "petalLength": 4.5, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 6.9, "sepalWidth": 3.1, "petalLength": 4.9, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 5.5, "sepalWidth": 2.3, "petalLength": 4.0, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 6.5, "sepalWidth": 2.8, "petalLength": 4.6, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 5.7, "sepalWidth": 2.8, "petalLength": 4.5, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 3.3, "petalLength": 4.7, "petalWidth": 1.6, "species": "versicolor"},
|
||||
{"sepalLength": 4.9, "sepalWidth": 2.4, "petalLength": 3.3, "petalWidth": 1.0, "species": "versicolor"},
|
||||
{"sepalLength": 6.6, "sepalWidth": 2.9, "petalLength": 4.6, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 5.2, "sepalWidth": 2.7, "petalLength": 3.9, "petalWidth": 1.4, "species": "versicolor"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 2.0, "petalLength": 3.5, "petalWidth": 1.0, "species": "versicolor"},
|
||||
{"sepalLength": 5.9, "sepalWidth": 3.0, "petalLength": 4.2, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 6.0, "sepalWidth": 2.2, "petalLength": 4.0, "petalWidth": 1.0, "species": "versicolor"},
|
||||
{"sepalLength": 6.1, "sepalWidth": 2.9, "petalLength": 4.7, "petalWidth": 1.4, "species": "versicolor"},
|
||||
{"sepalLength": 5.6, "sepalWidth": 2.9, "petalLength": 3.6, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 6.7, "sepalWidth": 3.1, "petalLength": 4.4, "petalWidth": 1.4, "species": "versicolor"},
|
||||
{"sepalLength": 5.6, "sepalWidth": 3.0, "petalLength": 4.5, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 5.8, "sepalWidth": 2.7, "petalLength": 4.1, "petalWidth": 1.0, "species": "versicolor"},
|
||||
{"sepalLength": 6.2, "sepalWidth": 2.2, "petalLength": 4.5, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 5.6, "sepalWidth": 2.5, "petalLength": 3.9, "petalWidth": 1.1, "species": "versicolor"},
|
||||
{"sepalLength": 5.9, "sepalWidth": 3.2, "petalLength": 4.8, "petalWidth": 1.8, "species": "versicolor"},
|
||||
{"sepalLength": 6.1, "sepalWidth": 2.8, "petalLength": 4.0, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 2.5, "petalLength": 4.9, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 6.1, "sepalWidth": 2.8, "petalLength": 4.7, "petalWidth": 1.2, "species": "versicolor"},
|
||||
{"sepalLength": 6.4, "sepalWidth": 2.9, "petalLength": 4.3, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 6.6, "sepalWidth": 3.0, "petalLength": 4.4, "petalWidth": 1.4, "species": "versicolor"},
|
||||
{"sepalLength": 6.8, "sepalWidth": 2.8, "petalLength": 4.8, "petalWidth": 1.4, "species": "versicolor"},
|
||||
{"sepalLength": 6.7, "sepalWidth": 3.0, "petalLength": 5.0, "petalWidth": 1.7, "species": "versicolor"},
|
||||
{"sepalLength": 6.0, "sepalWidth": 2.9, "petalLength": 4.5, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 5.7, "sepalWidth": 2.6, "petalLength": 3.5, "petalWidth": 1.0, "species": "versicolor"},
|
||||
{"sepalLength": 5.5, "sepalWidth": 2.4, "petalLength": 3.8, "petalWidth": 1.1, "species": "versicolor"},
|
||||
{"sepalLength": 5.5, "sepalWidth": 2.4, "petalLength": 3.7, "petalWidth": 1.0, "species": "versicolor"},
|
||||
{"sepalLength": 5.8, "sepalWidth": 2.7, "petalLength": 3.9, "petalWidth": 1.2, "species": "versicolor"},
|
||||
{"sepalLength": 6.0, "sepalWidth": 2.7, "petalLength": 5.1, "petalWidth": 1.6, "species": "versicolor"},
|
||||
{"sepalLength": 5.4, "sepalWidth": 3.0, "petalLength": 4.5, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 6.0, "sepalWidth": 3.4, "petalLength": 4.5, "petalWidth": 1.6, "species": "versicolor"},
|
||||
{"sepalLength": 6.7, "sepalWidth": 3.1, "petalLength": 4.7, "petalWidth": 1.5, "species": "versicolor"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 2.3, "petalLength": 4.4, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 5.6, "sepalWidth": 3.0, "petalLength": 4.1, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 5.5, "sepalWidth": 2.5, "petalLength": 4.0, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 5.5, "sepalWidth": 2.6, "petalLength": 4.4, "petalWidth": 1.2, "species": "versicolor"},
|
||||
{"sepalLength": 6.1, "sepalWidth": 3.0, "petalLength": 4.6, "petalWidth": 1.4, "species": "versicolor"},
|
||||
{"sepalLength": 5.8, "sepalWidth": 2.6, "petalLength": 4.0, "petalWidth": 1.2, "species": "versicolor"},
|
||||
{"sepalLength": 5.0, "sepalWidth": 2.3, "petalLength": 3.3, "petalWidth": 1.0, "species": "versicolor"},
|
||||
{"sepalLength": 5.6, "sepalWidth": 2.7, "petalLength": 4.2, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 5.7, "sepalWidth": 3.0, "petalLength": 4.2, "petalWidth": 1.2, "species": "versicolor"},
|
||||
{"sepalLength": 5.7, "sepalWidth": 2.9, "petalLength": 4.2, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 6.2, "sepalWidth": 2.9, "petalLength": 4.3, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 5.1, "sepalWidth": 2.5, "petalLength": 3.0, "petalWidth": 1.1, "species": "versicolor"},
|
||||
{"sepalLength": 5.7, "sepalWidth": 2.8, "petalLength": 4.1, "petalWidth": 1.3, "species": "versicolor"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 3.3, "petalLength": 6.0, "petalWidth": 2.5, "species": "virginica"},
|
||||
{"sepalLength": 5.8, "sepalWidth": 2.7, "petalLength": 5.1, "petalWidth": 1.9, "species": "virginica"},
|
||||
{"sepalLength": 7.1, "sepalWidth": 3.0, "petalLength": 5.9, "petalWidth": 2.1, "species": "virginica"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 2.9, "petalLength": 5.6, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 6.5, "sepalWidth": 3.0, "petalLength": 5.8, "petalWidth": 2.2, "species": "virginica"},
|
||||
{"sepalLength": 7.6, "sepalWidth": 3.0, "petalLength": 6.6, "petalWidth": 2.1, "species": "virginica"},
|
||||
{"sepalLength": 4.9, "sepalWidth": 2.5, "petalLength": 4.5, "petalWidth": 1.7, "species": "virginica"},
|
||||
{"sepalLength": 7.3, "sepalWidth": 2.9, "petalLength": 6.3, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 6.7, "sepalWidth": 2.5, "petalLength": 5.8, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 7.2, "sepalWidth": 3.6, "petalLength": 6.1, "petalWidth": 2.5, "species": "virginica"},
|
||||
{"sepalLength": 6.5, "sepalWidth": 3.2, "petalLength": 5.1, "petalWidth": 2.0, "species": "virginica"},
|
||||
{"sepalLength": 6.4, "sepalWidth": 2.7, "petalLength": 5.3, "petalWidth": 1.9, "species": "virginica"},
|
||||
{"sepalLength": 6.8, "sepalWidth": 3.0, "petalLength": 5.5, "petalWidth": 2.1, "species": "virginica"},
|
||||
{"sepalLength": 5.7, "sepalWidth": 2.5, "petalLength": 5.0, "petalWidth": 2.0, "species": "virginica"},
|
||||
{"sepalLength": 5.8, "sepalWidth": 2.8, "petalLength": 5.1, "petalWidth": 2.4, "species": "virginica"},
|
||||
{"sepalLength": 6.4, "sepalWidth": 3.2, "petalLength": 5.3, "petalWidth": 2.3, "species": "virginica"},
|
||||
{"sepalLength": 6.5, "sepalWidth": 3.0, "petalLength": 5.5, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 7.7, "sepalWidth": 3.8, "petalLength": 6.7, "petalWidth": 2.2, "species": "virginica"},
|
||||
{"sepalLength": 7.7, "sepalWidth": 2.6, "petalLength": 6.9, "petalWidth": 2.3, "species": "virginica"},
|
||||
{"sepalLength": 6.0, "sepalWidth": 2.2, "petalLength": 5.0, "petalWidth": 1.5, "species": "virginica"},
|
||||
{"sepalLength": 6.9, "sepalWidth": 3.2, "petalLength": 5.7, "petalWidth": 2.3, "species": "virginica"},
|
||||
{"sepalLength": 5.6, "sepalWidth": 2.8, "petalLength": 4.9, "petalWidth": 2.0, "species": "virginica"},
|
||||
{"sepalLength": 7.7, "sepalWidth": 2.8, "petalLength": 6.7, "petalWidth": 2.0, "species": "virginica"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 2.7, "petalLength": 4.9, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 6.7, "sepalWidth": 3.3, "petalLength": 5.7, "petalWidth": 2.1, "species": "virginica"},
|
||||
{"sepalLength": 7.2, "sepalWidth": 3.2, "petalLength": 6.0, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 6.2, "sepalWidth": 2.8, "petalLength": 4.8, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 6.1, "sepalWidth": 3.0, "petalLength": 4.9, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 6.4, "sepalWidth": 2.8, "petalLength": 5.6, "petalWidth": 2.1, "species": "virginica"},
|
||||
{"sepalLength": 7.2, "sepalWidth": 3.0, "petalLength": 5.8, "petalWidth": 1.6, "species": "virginica"},
|
||||
{"sepalLength": 7.4, "sepalWidth": 2.8, "petalLength": 6.1, "petalWidth": 1.9, "species": "virginica"},
|
||||
{"sepalLength": 7.9, "sepalWidth": 3.8, "petalLength": 6.4, "petalWidth": 2.0, "species": "virginica"},
|
||||
{"sepalLength": 6.4, "sepalWidth": 2.8, "petalLength": 5.6, "petalWidth": 2.2, "species": "virginica"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 2.8, "petalLength": 5.1, "petalWidth": 1.5, "species": "virginica"},
|
||||
{"sepalLength": 6.1, "sepalWidth": 2.6, "petalLength": 5.6, "petalWidth": 1.4, "species": "virginica"},
|
||||
{"sepalLength": 7.7, "sepalWidth": 3.0, "petalLength": 6.1, "petalWidth": 2.3, "species": "virginica"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 3.4, "petalLength": 5.6, "petalWidth": 2.4, "species": "virginica"},
|
||||
{"sepalLength": 6.4, "sepalWidth": 3.1, "petalLength": 5.5, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 6.0, "sepalWidth": 3.0, "petalLength": 4.8, "petalWidth": 1.8, "species": "virginica"},
|
||||
{"sepalLength": 6.9, "sepalWidth": 3.1, "petalLength": 5.4, "petalWidth": 2.1, "species": "virginica"},
|
||||
{"sepalLength": 6.7, "sepalWidth": 3.1, "petalLength": 5.6, "petalWidth": 2.4, "species": "virginica"},
|
||||
{"sepalLength": 6.9, "sepalWidth": 3.1, "petalLength": 5.1, "petalWidth": 2.3, "species": "virginica"},
|
||||
{"sepalLength": 5.8, "sepalWidth": 2.7, "petalLength": 5.1, "petalWidth": 1.9, "species": "virginica"},
|
||||
{"sepalLength": 6.8, "sepalWidth": 3.2, "petalLength": 5.9, "petalWidth": 2.3, "species": "virginica"},
|
||||
{"sepalLength": 6.7, "sepalWidth": 3.3, "petalLength": 5.7, "petalWidth": 2.5, "species": "virginica"},
|
||||
{"sepalLength": 6.7, "sepalWidth": 3.0, "petalLength": 5.2, "petalWidth": 2.3, "species": "virginica"},
|
||||
{"sepalLength": 6.3, "sepalWidth": 2.5, "petalLength": 5.0, "petalWidth": 1.9, "species": "virginica"},
|
||||
{"sepalLength": 6.5, "sepalWidth": 3.0, "petalLength": 5.2, "petalWidth": 2.0, "species": "virginica"},
|
||||
{"sepalLength": 6.2, "sepalWidth": 3.4, "petalLength": 5.4, "petalWidth": 2.3, "species": "virginica"},
|
||||
{"sepalLength": 5.9, "sepalWidth": 3.0, "petalLength": 5.1, "petalWidth": 1.8, "species": "virginica"}
|
||||
]
|
||||
175
src/data/mock.data.json
Normal file
175
src/data/mock.data.json
Normal file
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"attr2": "attribute223",
|
||||
"pivot": "attribute2",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"attr2": "attribute257",
|
||||
"pivot": "attribute1",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"category": "5",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 2
|
||||
},
|
||||
"notMatch": {
|
||||
"category": "10",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 9
|
||||
},
|
||||
"matchedCount": 2,
|
||||
"notMatchedCount": 9
|
||||
},
|
||||
"notMatch": {
|
||||
"attr2": "attribute193",
|
||||
"pivot": "attribute276",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"attr2": "attribute148",
|
||||
"pivot": "attribute32",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"attr2": "attribute46",
|
||||
"pivot": "attribute172",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"category": "2",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 5
|
||||
},
|
||||
"notMatch": {
|
||||
"attr2": "attribute44",
|
||||
"pivot": "attribute1",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"category": "1",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 3
|
||||
},
|
||||
"notMatch": {
|
||||
"category": "9",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 3
|
||||
},
|
||||
"matchedCount": 3,
|
||||
"notMatchedCount": 3
|
||||
},
|
||||
"matchedCount": 5,
|
||||
"notMatchedCount": 6
|
||||
},
|
||||
"notMatch": {
|
||||
"category": "4",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 4
|
||||
},
|
||||
"matchedCount": 11,
|
||||
"notMatchedCount": 4
|
||||
},
|
||||
"notMatch": {
|
||||
"attr2": "attribute14",
|
||||
"pivot": "attribute136",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"attr2": "attribute20",
|
||||
"pivot": "attribute75",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"attr2": "attribute179",
|
||||
"pivot": "attribute175",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"category": "6",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 5
|
||||
},
|
||||
"notMatch": {
|
||||
"attr2": "attribute123",
|
||||
"pivot": "attribute15",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"category": "3",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 2
|
||||
},
|
||||
"notMatch": {
|
||||
"attr2": "attribute42",
|
||||
"pivot": "attribute101",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"category": "6",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 1
|
||||
},
|
||||
"notMatch": {
|
||||
"attr2": "attribute238",
|
||||
"pivot": "attribute1",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"category": "5",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 1
|
||||
},
|
||||
"notMatch": {
|
||||
"category": "1",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 52
|
||||
},
|
||||
"matchedCount": 1,
|
||||
"notMatchedCount": 52
|
||||
},
|
||||
"matchedCount": 1,
|
||||
"notMatchedCount": 53
|
||||
},
|
||||
"matchedCount": 2,
|
||||
"notMatchedCount": 54
|
||||
},
|
||||
"matchedCount": 5,
|
||||
"notMatchedCount": 56
|
||||
},
|
||||
"notMatch": {
|
||||
"attr2": "attribute269",
|
||||
"pivot": "attribute15",
|
||||
"predicateName": "<",
|
||||
"match": {
|
||||
"category": "4",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 2
|
||||
},
|
||||
"notMatch": {
|
||||
"category": "1",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 5
|
||||
},
|
||||
"matchedCount": 2,
|
||||
"notMatchedCount": 5
|
||||
},
|
||||
"matchedCount": 61,
|
||||
"notMatchedCount": 7
|
||||
},
|
||||
"notMatch": {
|
||||
"category": "6",
|
||||
"quality": "0.00",
|
||||
"matchedCount": 0,
|
||||
"notMatchedCount": 7
|
||||
},
|
||||
"matchedCount": 68,
|
||||
"notMatchedCount": 7
|
||||
},
|
||||
"matchedCount": 15,
|
||||
"notMatchedCount": 75
|
||||
},
|
||||
"matchedCount": 11,
|
||||
"notMatchedCount": 90
|
||||
}
|
||||
7
src/img/logo.svg
Normal file
7
src/img/logo.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
|
||||
<g fill="#61DAFB">
|
||||
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
|
||||
<circle cx="420.9" cy="296.5" r="45.7"/>
|
||||
<path d="M520.5 78.1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import './css/index.scss';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import reportWebVitals from './tests/reportWebVitals';
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
623
src/services/Playground.js
Normal file
623
src/services/Playground.js
Normal file
@@ -0,0 +1,623 @@
|
||||
//var json = require("../data/arrythmia.json");
|
||||
var json = require("../data/ar2.json");
|
||||
//var json = require("../data/iris.json");
|
||||
//var json = require("../data/US_Politics_Twitter.json");
|
||||
export var builder = {
|
||||
//categoryAttr: "Sex",
|
||||
//categoryAttr: "species",
|
||||
categoryAttr: "attribute279",
|
||||
//ignoredAttributes: ['Instagram_username','Birthday','816181091673448400','Account_start_time'],
|
||||
//ignoredAttributes: ["sepalWidth", "petalLength"],
|
||||
ignoredAttributes: [],
|
||||
allAttributes: [
|
||||
"attribute1",
|
||||
"attribute2",
|
||||
"attribute3",
|
||||
"attribute4",
|
||||
"attribute5",
|
||||
"attribute6",
|
||||
"attribute7",
|
||||
"attribute8",
|
||||
"attribute9",
|
||||
"attribute10",
|
||||
"attribute11",
|
||||
"attribute12",
|
||||
"attribute13",
|
||||
"attribute14",
|
||||
"attribute15",
|
||||
"attribute16",
|
||||
"attribute17",
|
||||
"attribute18",
|
||||
"attribute19",
|
||||
"attribute20",
|
||||
"attribute21",
|
||||
"attribute22",
|
||||
"attribute23",
|
||||
"attribute24",
|
||||
"attribute25",
|
||||
"attribute26",
|
||||
"attribute27",
|
||||
"attribute28",
|
||||
"attribute29",
|
||||
"attribute30",
|
||||
"attribute31",
|
||||
"attribute32",
|
||||
"attribute33",
|
||||
"attribute34",
|
||||
"attribute35",
|
||||
"attribute36",
|
||||
"attribute37",
|
||||
"attribute38",
|
||||
"attribute39",
|
||||
"attribute40",
|
||||
"attribute41",
|
||||
"attribute42",
|
||||
"attribute43",
|
||||
"attribute44",
|
||||
"attribute45",
|
||||
"attribute46",
|
||||
"attribute47",
|
||||
"attribute48",
|
||||
"attribute49",
|
||||
"attribute50",
|
||||
"attribute51",
|
||||
"attribute52",
|
||||
"attribute53",
|
||||
"attribute54",
|
||||
"attribute55",
|
||||
"attribute56",
|
||||
"attribute57",
|
||||
"attribute58",
|
||||
"attribute59",
|
||||
"attribute60",
|
||||
"attribute61",
|
||||
"attribute62",
|
||||
"attribute63",
|
||||
"attribute64",
|
||||
"attribute65",
|
||||
"attribute66",
|
||||
"attribute67",
|
||||
"attribute68",
|
||||
"attribute69",
|
||||
"attribute70",
|
||||
"attribute71",
|
||||
"attribute72",
|
||||
"attribute73",
|
||||
"attribute74",
|
||||
"attribute75",
|
||||
"attribute76",
|
||||
"attribute77",
|
||||
"attribute78",
|
||||
"attribute79",
|
||||
"attribute80",
|
||||
"attribute81",
|
||||
"attribute82",
|
||||
"attribute83",
|
||||
"attribute84",
|
||||
"attribute85",
|
||||
"attribute86",
|
||||
"attribute87",
|
||||
"attribute88",
|
||||
"attribute89",
|
||||
"attribute90",
|
||||
"attribute91",
|
||||
"attribute92",
|
||||
"attribute93",
|
||||
"attribute94",
|
||||
"attribute95",
|
||||
"attribute96",
|
||||
"attribute97",
|
||||
"attribute98",
|
||||
"attribute99",
|
||||
"attribute100",
|
||||
"attribute101",
|
||||
"attribute102",
|
||||
"attribute103",
|
||||
"attribute104",
|
||||
"attribute105",
|
||||
"attribute106",
|
||||
"attribute107",
|
||||
"attribute108",
|
||||
"attribute109",
|
||||
"attribute110",
|
||||
"attribute111",
|
||||
"attribute112",
|
||||
"attribute113",
|
||||
"attribute114",
|
||||
"attribute115",
|
||||
"attribute116",
|
||||
"attribute117",
|
||||
"attribute118",
|
||||
"attribute119",
|
||||
"attribute120",
|
||||
"attribute121",
|
||||
"attribute122",
|
||||
"attribute123",
|
||||
"attribute124",
|
||||
"attribute125",
|
||||
"attribute126",
|
||||
"attribute127",
|
||||
"attribute128",
|
||||
"attribute129",
|
||||
"attribute130",
|
||||
"attribute131",
|
||||
"attribute132",
|
||||
"attribute133",
|
||||
"attribute134",
|
||||
"attribute135",
|
||||
"attribute136",
|
||||
"attribute137",
|
||||
"attribute138",
|
||||
"attribute139",
|
||||
"attribute140",
|
||||
"attribute141",
|
||||
"attribute142",
|
||||
"attribute143",
|
||||
"attribute144",
|
||||
"attribute145",
|
||||
"attribute146",
|
||||
"attribute147",
|
||||
"attribute148",
|
||||
"attribute149",
|
||||
"attribute150",
|
||||
"attribute151",
|
||||
"attribute152",
|
||||
"attribute153",
|
||||
"attribute154",
|
||||
"attribute155",
|
||||
"attribute156",
|
||||
"attribute157",
|
||||
"attribute158",
|
||||
"attribute159",
|
||||
"attribute160",
|
||||
"attribute161",
|
||||
"attribute162",
|
||||
"attribute163",
|
||||
"attribute164",
|
||||
"attribute165",
|
||||
"attribute166",
|
||||
"attribute167",
|
||||
"attribute168",
|
||||
"attribute169",
|
||||
"attribute170",
|
||||
"attribute171",
|
||||
"attribute172",
|
||||
"attribute173",
|
||||
"attribute174",
|
||||
"attribute175",
|
||||
"attribute176",
|
||||
"attribute177",
|
||||
"attribute178",
|
||||
"attribute179",
|
||||
"attribute180",
|
||||
"attribute181",
|
||||
"attribute182",
|
||||
"attribute183",
|
||||
"attribute184",
|
||||
"attribute185",
|
||||
"attribute186",
|
||||
"attribute187",
|
||||
"attribute188",
|
||||
"attribute189",
|
||||
"attribute190",
|
||||
"attribute191",
|
||||
"attribute192",
|
||||
"attribute193",
|
||||
"attribute194",
|
||||
"attribute195",
|
||||
"attribute196",
|
||||
"attribute197",
|
||||
"attribute198",
|
||||
"attribute199",
|
||||
"attribute200",
|
||||
"attribute201",
|
||||
"attribute202",
|
||||
"attribute203",
|
||||
"attribute204",
|
||||
"attribute205",
|
||||
"attribute206",
|
||||
"attribute207",
|
||||
"attribute208",
|
||||
"attribute209",
|
||||
"attribute210",
|
||||
"attribute211",
|
||||
"attribute212",
|
||||
"attribute213",
|
||||
"attribute214",
|
||||
"attribute215",
|
||||
"attribute216",
|
||||
"attribute217",
|
||||
"attribute218",
|
||||
"attribute219",
|
||||
"attribute220",
|
||||
"attribute221",
|
||||
"attribute222",
|
||||
"attribute223",
|
||||
"attribute224",
|
||||
"attribute225",
|
||||
"attribute226",
|
||||
"attribute227",
|
||||
"attribute228",
|
||||
"attribute229",
|
||||
"attribute230",
|
||||
"attribute231",
|
||||
"attribute232",
|
||||
"attribute233",
|
||||
"attribute234",
|
||||
"attribute235",
|
||||
"attribute236",
|
||||
"attribute237",
|
||||
"attribute238",
|
||||
"attribute239",
|
||||
"attribute240",
|
||||
"attribute241",
|
||||
"attribute242",
|
||||
"attribute243",
|
||||
"attribute244",
|
||||
"attribute245",
|
||||
"attribute246",
|
||||
"attribute247",
|
||||
"attribute248",
|
||||
"attribute249",
|
||||
"attribute250",
|
||||
"attribute251",
|
||||
"attribute252",
|
||||
"attribute253",
|
||||
"attribute254",
|
||||
"attribute255",
|
||||
"attribute256",
|
||||
"attribute257",
|
||||
"attribute258",
|
||||
"attribute259",
|
||||
"attribute260",
|
||||
"attribute261",
|
||||
"attribute262",
|
||||
"attribute263",
|
||||
"attribute264",
|
||||
"attribute265",
|
||||
"attribute266",
|
||||
"attribute267",
|
||||
"attribute268",
|
||||
"attribute269",
|
||||
"attribute270",
|
||||
"attribute271",
|
||||
"attribute272",
|
||||
"attribute273",
|
||||
"attribute274",
|
||||
"attribute275",
|
||||
"attribute276",
|
||||
"attribute277",
|
||||
"attribute278",
|
||||
"attribute279",
|
||||
],
|
||||
//allAttributes: [
|
||||
// "sepalLength",
|
||||
// "sepalWidth",
|
||||
// "petalLength",
|
||||
// "petalWidth",
|
||||
// "species",
|
||||
// ],
|
||||
// allAttributes: [
|
||||
// "Name","Twitter_username","Account_start_time","Account_ID","Sex","Birthplace","Birthday","Age","Instagram_username","Political_party"
|
||||
// ],
|
||||
trainingSet: json,
|
||||
maxTreeDepth: 20,
|
||||
minItemsCount: 5,
|
||||
//allClasses: getAllClasses(json,"species")
|
||||
allClasses: getAllClasses(json, "attribute279"),
|
||||
};
|
||||
|
||||
|
||||
export function start(builder) {
|
||||
//console.log(builder);
|
||||
return buildDecisionTree(builder, false);
|
||||
};
|
||||
|
||||
function buildDecisionTree(builder, isChanged = false) {
|
||||
var trainingSet = builder.trainingSet;
|
||||
var minItemsCount = builder.minItemsCount;
|
||||
var categoryAttr = builder.categoryAttr;
|
||||
var entropyThrehold = builder.entropyThrehold;
|
||||
var maxTreeDepth = builder.maxTreeDepth;
|
||||
var ignoredAttributes = builder.ignoredAttributes;
|
||||
//console.log("########## NOWY WEZEL ########", trainingSet.length);
|
||||
var _quality = 0;
|
||||
debugger;
|
||||
if (maxTreeDepth === 0 || trainingSet.length <= minItemsCount) {
|
||||
console.log("LISC BO MAX TREE DEPTH",maxTreeDepth,"LISC ILOSC",trainingSet.length)
|
||||
//);
|
||||
//gger;
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log("KATEGORIA JAKO:", _category);
|
||||
trainingSet.forEach((element) => {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
//ugger;
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet.map(x=> x[categoryAttr])
|
||||
};
|
||||
}
|
||||
var attributes = builder.allAttributes.filter(function (el) {
|
||||
return ![...ignoredAttributes, categoryAttr].includes(el);
|
||||
});
|
||||
//console.log(builder.minItemsCount, builder.trainingSet.length);
|
||||
|
||||
// tu juz musi byc przekazana cm wyzerowana
|
||||
|
||||
var podzial = [];
|
||||
//console.log(attributes);
|
||||
var right = 0,
|
||||
left = 0;
|
||||
var maxDif = 100,
|
||||
attribute1 = -1,
|
||||
attribute2 = -1;
|
||||
var directrion = "<";
|
||||
var leftList = [],
|
||||
rightList = [],
|
||||
classMatrix = [
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
],
|
||||
match = [],
|
||||
notMatch = [];
|
||||
for (let i = 0; i < attributes.length; i++) {
|
||||
let attr1 = attributes[i];
|
||||
for (let j = 0; j < attributes.length; j++) {
|
||||
let attr2 = attributes[j];
|
||||
if (attr1 !== attr2) {
|
||||
right = left = 0;
|
||||
leftList = [];
|
||||
rightList = [];
|
||||
classMatrix = [
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
];
|
||||
|
||||
for (let index = 0; index < trainingSet.length; index++) {
|
||||
const element = trainingSet[index];
|
||||
|
||||
if (element[attr1] < element[attr2]) {
|
||||
left++;
|
||||
leftList.push(element);
|
||||
classMatrix[0][builder.allClasses.indexOf(element[categoryAttr])]++;
|
||||
} else {
|
||||
right++;
|
||||
rightList.push(element);
|
||||
classMatrix[1][builder.allClasses.indexOf(element[categoryAttr])]++;
|
||||
}
|
||||
}
|
||||
//console.log(classMatrix);
|
||||
var probR = 0,
|
||||
probL = 0,
|
||||
rankL = 0,
|
||||
rankR = 0;
|
||||
for (let k = 0; k < builder.allClasses.length; k++) {
|
||||
probL = left === 0 ? 0 : classMatrix[0][k] / left;
|
||||
probR = right === 0 ? 0 : classMatrix[1][k] / right;
|
||||
|
||||
rankL += probL * probL;
|
||||
rankR += probR * probR;
|
||||
}
|
||||
//console.log("Rank Lewy",rankL,"Rank Prawy",rankR);
|
||||
|
||||
var currentDif =
|
||||
(right / trainingSet.length) * (1 - rankR) +
|
||||
(left / trainingSet.length) * (1 - rankL);
|
||||
if (currentDif < maxDif) {
|
||||
//console.log("------Zapisanie maxDif-------");
|
||||
//console.log(attr1,attr2);
|
||||
//console.log("R/L ", right + ":" + left);
|
||||
//console.log("cur/mD",currentDif + ":" + maxDif);
|
||||
maxDif = currentDif;
|
||||
attribute1 = attr1;
|
||||
attribute2 = attr2;
|
||||
match = leftList;
|
||||
notMatch = rightList;
|
||||
podzial = classMatrix;
|
||||
//console.log("-----------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log("PO WYLICZENIU NAJLEPSZEGO");
|
||||
//console.log(attribute1, attribute2);
|
||||
//console.log("L/R ", match.length + ":" + notMatch.length);
|
||||
//console.log(podzial);
|
||||
//console.log("MaxDifference:", maxDif);
|
||||
if (!maxDif) {
|
||||
console.log("LISC BO MAX DIF ZERO", trainingSet.length);
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log("KATEGORIA JAKO:", _category);
|
||||
trainingSet.forEach((element) => {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet.map(x=> x[categoryAttr])
|
||||
};
|
||||
}
|
||||
// sprawdzic
|
||||
// wssytskies stringi do ignored
|
||||
if (match.length === 0 || notMatch.length === 0) {
|
||||
console.log("LISC BO JEDNA ZE STRON MA 0");
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log(_category);
|
||||
trainingSet.forEach((element) => {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
// restriction by maximal depth of tree
|
||||
// or size of training set is to small
|
||||
// so we have to terminate process of building tree
|
||||
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet.map(x=> x[categoryAttr])
|
||||
};
|
||||
}
|
||||
|
||||
builder.maxTreeDepth = maxTreeDepth - 1;
|
||||
builder.trainingSet = match;
|
||||
//var matchSubTree = buildDecisionTree(builder);
|
||||
|
||||
builder.trainingSet = notMatch;
|
||||
//var notMatchSubTree = buildDecisionTree(builder);
|
||||
console.log("TUTAJ");
|
||||
return {
|
||||
attr2: attribute2,
|
||||
pivot: attribute1,
|
||||
predicateName: directrion,
|
||||
//match: matchSubTree,
|
||||
//notMatch: notMatchSubTree, //{category: ...}
|
||||
matchedCount: match.length,
|
||||
notMatchedCount: notMatch.length,
|
||||
};
|
||||
//console.log(attributes);
|
||||
}
|
||||
// var tree={root : buildDecisionTree(builder, true)}
|
||||
// var json = JSON.stringify(tree);
|
||||
// var blob = new Blob([json], {type: "application/json"});
|
||||
// var url = URL.createObjectURL(blob);
|
||||
|
||||
|
||||
// var a = document.createElement('a');
|
||||
// a.download = "backup.json";
|
||||
// a.href = url;
|
||||
// a.textContent = "Download backup.json";
|
||||
// a.innerHTML="tutaj download"
|
||||
// document.getElementById('main').innerHTML=a
|
||||
//console.log(tree);
|
||||
|
||||
// function fillConfusionMatrix() {
|
||||
// let confusionMatrix = buildArray(Object.keys(classes).length);
|
||||
|
||||
// set.forEach((element) => {
|
||||
// let prediction = predict(decisionTree.root, element);
|
||||
// let _class = element[window.CFG.categoryAttr];
|
||||
// if (prediction === _class) {
|
||||
// confusionMatrix[classes[_class]][classes[_class]]++;
|
||||
// } else {
|
||||
// confusionMatrix[classes[_class]][classes[prediction]]++;
|
||||
// }
|
||||
// });
|
||||
// //console.log(confusionMatrix)
|
||||
// return confusionMatrix;
|
||||
// }
|
||||
function countUniqueValues(items, attr) {
|
||||
var counter = {};
|
||||
|
||||
// detecting different values of attribute
|
||||
for (var i = items.length - 1; i >= 0; i--) {
|
||||
// items[i][attr] - value of attribute
|
||||
counter[items[i][attr]] = 0;
|
||||
}
|
||||
|
||||
// counting number of occurrences of each of values
|
||||
// of attribute
|
||||
for (var j = items.length - 1; j >= 0; j--) {
|
||||
counter[items[j][attr]] += 1;
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
function mostFrequentValue(items, attr) {
|
||||
// counting number of occurrences of each of values
|
||||
// of attribute
|
||||
var counter = countUniqueValues(items, attr);
|
||||
|
||||
var mostFrequentCount = 0;
|
||||
var mostFrequentValue;
|
||||
|
||||
for (var value in counter) {
|
||||
if (counter[value] > mostFrequentCount) {
|
||||
mostFrequentCount = counter[value];
|
||||
mostFrequentValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
return mostFrequentValue;
|
||||
}
|
||||
function getAllClasses(set, cattegoryAttr) {
|
||||
let array = [];
|
||||
set.forEach((element) => {
|
||||
let _class = element[cattegoryAttr];
|
||||
if (!array.includes(_class)) array.push(_class);
|
||||
});
|
||||
console.log(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
function takeAllClasses(set, cattegotyAttr) {
|
||||
let array = {};
|
||||
let counter = 0;
|
||||
//console.log(window.CFG.categoryAttr)
|
||||
set.forEach((element) => {
|
||||
let _class = element[cattegotyAttr];
|
||||
if (!array.hasOwnProperty(_class)) array[_class] = counter++;
|
||||
});
|
||||
|
||||
return array;
|
||||
}
|
||||
function buildArrayFillZeros(lenght) {
|
||||
let arr = [];
|
||||
for (var x = 0; x < lenght; x++) {
|
||||
arr[x] = [];
|
||||
for (var y = 0; y < lenght; y++) {
|
||||
arr[x][y] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function recursionTreePrint(tree, str, lvl) {
|
||||
//console.log(str)
|
||||
if (tree.category) {
|
||||
let l = " ";
|
||||
for (let i = 0; i < lvl; i++) {
|
||||
l += " ";
|
||||
}
|
||||
return "\n" + l + tree.category;
|
||||
}
|
||||
let l = " ";
|
||||
for (let i = 0; i < lvl; i++) {
|
||||
l += " ";
|
||||
}
|
||||
str +=
|
||||
"\n" + l + tree.attribute + " " + tree.predicateName + " " + tree.pivot;
|
||||
//console.log(tree.match)
|
||||
lvl++;
|
||||
str += recursionTreePrint(tree.match, "", lvl);
|
||||
//console.log(tree.notMatch)
|
||||
str += recursionTreePrint(tree.notMatch, "", lvl);
|
||||
return str;
|
||||
}
|
||||
545
src/services/TSP.js
Normal file
545
src/services/TSP.js
Normal file
@@ -0,0 +1,545 @@
|
||||
|
||||
export var dt = (function () {
|
||||
//debugger;
|
||||
/**
|
||||
* Creates an instance of DecisionTree
|
||||
*
|
||||
* @constructor
|
||||
* @param builder - contains training set and
|
||||
* some configuration parameters
|
||||
*/
|
||||
function TSPDecisionTree(builder, isChanged=false) {
|
||||
this.root = buildDecisionTree({
|
||||
trainingSet: builder.trainingSet,
|
||||
ignoredAttributes: arrayToHashSet(builder.ignoredAttributes),
|
||||
//ignoredAttributes: builder.ignoredAttributes,
|
||||
categoryAttr: builder.categoryAttr || 'category',
|
||||
minItemsCount: builder.minItemsCount ,//|| 4,
|
||||
entropyThrehold: builder.entropyThrehold,// || 0.1,
|
||||
maxTreeDepth: builder.maxTreeDepth,// || 30
|
||||
},isChanged);
|
||||
//console.log(builder.ignoredAttributes)
|
||||
}
|
||||
|
||||
|
||||
TSPDecisionTree.prototype.predict = function (item) {
|
||||
return predict(this.root, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of RandomForest
|
||||
* with specific number of trees
|
||||
*
|
||||
* @constructor
|
||||
* @param builder - contains training set and some
|
||||
* configuration parameters for
|
||||
* building decision trees
|
||||
*/
|
||||
function RandomForest(builder, treesNumber) {
|
||||
this.trees = buildRandomForest(builder, treesNumber);
|
||||
}
|
||||
|
||||
RandomForest.prototype.predict = function (item) {
|
||||
return predictRandomForest(this.trees, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforming array to object with such attributes
|
||||
* as elements of array (afterwards it can be used as HashSet)
|
||||
*/
|
||||
function arrayToHashSet(array) {
|
||||
var hashSet = {};
|
||||
if (array) {
|
||||
for(var i in array) {
|
||||
var attr = array[i];
|
||||
hashSet[attr] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hashSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculating how many objects have the same
|
||||
* values of specific attribute.
|
||||
*
|
||||
* @param items - array of objects
|
||||
*
|
||||
* @param attr - variable with name of attribute,
|
||||
* which embedded in each object
|
||||
*/
|
||||
function countUniqueValues(items, attr) {
|
||||
var counter = {};
|
||||
|
||||
// detecting different values of attribute
|
||||
for (var i = items.length - 1; i >= 0; i--) {
|
||||
// items[i][attr] - value of attribute
|
||||
counter[items[i][attr]] = 0;
|
||||
}
|
||||
|
||||
// counting number of occurrences of each of values
|
||||
// of attribute
|
||||
for (var j = items.length - 1; j >= 0; j--) {
|
||||
counter[items[j][attr]] += 1;
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculating entropy of array of objects
|
||||
* by specific attribute.
|
||||
*
|
||||
* @param items - array of objects
|
||||
*
|
||||
* @param attr - variable with name of attribute,
|
||||
* which embedded in each object
|
||||
*/
|
||||
function entropy(items, attr) {
|
||||
// counting number of occurrences of each of values
|
||||
// of attribute
|
||||
var counter = countUniqueValues(items, attr);
|
||||
|
||||
var entropy = 0;
|
||||
var p;
|
||||
for (var i in counter) {
|
||||
p = counter[i] / items.length;
|
||||
entropy += -p * Math.log(p);
|
||||
}
|
||||
|
||||
return entropy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splitting array of objects by value of specific attribute,
|
||||
* using specific predicate and pivot.
|
||||
*
|
||||
* Items which matched by predicate will be copied to
|
||||
* the new array called 'match', and the rest of the items
|
||||
* will be copied to array with name 'notMatch'
|
||||
*
|
||||
* @param items - array of objects
|
||||
*
|
||||
* @param attr - variable with name of attribute,
|
||||
* which embedded in each object
|
||||
*
|
||||
* @param predicate - function(x, y)
|
||||
* which returns 'true' or 'false'
|
||||
*
|
||||
* @param pivot - used as the second argument when
|
||||
* calling predicate function:
|
||||
* e.g. predicate(item[attr], pivot)
|
||||
*/
|
||||
function split(items, attr, predicate, pivot) {
|
||||
var match = [];
|
||||
var notMatch = [];
|
||||
|
||||
var item,
|
||||
attrValue;
|
||||
|
||||
for (var i = items.length - 1; i >= 0; i--) {
|
||||
item = items[i];
|
||||
attrValue = item[attr];
|
||||
|
||||
if (predicate(attrValue, pivot)) {
|
||||
match.push(item);
|
||||
} else {
|
||||
notMatch.push(item);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
match: match,
|
||||
notMatch: notMatch
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finding value of specific attribute which is most frequent
|
||||
* in given array of objects.
|
||||
*
|
||||
* @param items - array of objects
|
||||
*
|
||||
* @param attr - variable with name of attribute,
|
||||
* which embedded in each object
|
||||
*/
|
||||
function mostFrequentValue(items, attr) {
|
||||
// counting number of occurrences of each of values
|
||||
// of attribute
|
||||
var counter = countUniqueValues(items, attr);
|
||||
|
||||
var mostFrequentCount = 0;
|
||||
var mostFrequentValue;
|
||||
|
||||
for (var value in counter) {
|
||||
if (counter[value] > mostFrequentCount) {
|
||||
mostFrequentCount = counter[value];
|
||||
mostFrequentValue = value;
|
||||
}
|
||||
};
|
||||
|
||||
return mostFrequentValue;
|
||||
}
|
||||
|
||||
var predicates = {
|
||||
'==': function (a, b) { return a === b },
|
||||
'>=': function (a, b) { return a >= b }
|
||||
};
|
||||
|
||||
/**
|
||||
* Function for building decision tree
|
||||
*/
|
||||
function buildDecisionTree(builder,isChanged) {
|
||||
|
||||
var trainingSet = builder.trainingSet;
|
||||
var minItemsCount = builder.minItemsCount;
|
||||
var categoryAttr = builder.categoryAttr;
|
||||
var entropyThrehold = builder.entropyThrehold;
|
||||
var maxTreeDepth = builder.maxTreeDepth;
|
||||
var ignoredAttributes = builder.ignoredAttributes;
|
||||
|
||||
let _quality=0
|
||||
if ((maxTreeDepth === 0) || (trainingSet.length <= minItemsCount)) {
|
||||
let _category=mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter=0;
|
||||
let _hide=0;
|
||||
|
||||
trainingSet.forEach(element => {
|
||||
if(element[categoryAttr]===_category)_positiveCounter++;
|
||||
|
||||
});
|
||||
let _negativeCounter=trainingSet.length-_positiveCounter;
|
||||
_quality=_positiveCounter/trainingSet.length;
|
||||
if(_quality!==1) _hide=25;
|
||||
_quality=_quality*100;
|
||||
_quality=_quality.toFixed(2);
|
||||
// restriction by maximal depth of tree
|
||||
// or size of training set is to small
|
||||
// so we have to terminate process of building tree
|
||||
return {
|
||||
category: _category, quality:_quality, matchedCount:_positiveCounter, notMatchedCount:_negativeCounter, hide:_hide
|
||||
};
|
||||
}
|
||||
|
||||
var initialEntropy = entropy(trainingSet, categoryAttr);
|
||||
console.log("initialEntropy "+initialEntropy);
|
||||
if (initialEntropy <= entropyThrehold) {
|
||||
let _category=mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter=0;
|
||||
let _hide=0;
|
||||
|
||||
trainingSet.forEach(element => {
|
||||
if(element[categoryAttr]===_category)_positiveCounter++;
|
||||
|
||||
});
|
||||
let _negativeCounter=trainingSet.length-_positiveCounter;
|
||||
_quality=_positiveCounter/trainingSet.length;
|
||||
if(_quality!==1) _hide=25;
|
||||
_quality=_quality*100;
|
||||
_quality=_quality.toFixed(2);
|
||||
// entropy of training set too small
|
||||
// (it means that training set is almost homogeneous),
|
||||
// so we have to terminate process of building tree
|
||||
return {
|
||||
category: _category, quality:_quality,matchedCount:_positiveCounter,notMatchedCount:_negativeCounter, hide:_hide
|
||||
};
|
||||
}
|
||||
|
||||
// used as hash-set for avoiding the checking of split by rules
|
||||
// with the same 'attribute-predicate-pivot' more than once
|
||||
var alreadyChecked = {};
|
||||
|
||||
// this variable expected to contain rule, which splits training set
|
||||
// into subsets with smaller values of entropy (produces informational gain)
|
||||
var bestSplit = {gain: 0};
|
||||
|
||||
var pivot;
|
||||
var predicateName;
|
||||
var attrPredPivot;
|
||||
var predicate;
|
||||
var currSplit;
|
||||
var matchEntropy;
|
||||
var notMatchEntropy;
|
||||
var newEntropy;
|
||||
var currGain;
|
||||
|
||||
if(isChanged)
|
||||
{
|
||||
let attr = window.CurrentAttribute;
|
||||
|
||||
// let the value of current attribute be the pivot
|
||||
pivot = window.inputValue;
|
||||
|
||||
//console.log(attr +" "+ pivot)
|
||||
if(!isNaN(pivot))
|
||||
{
|
||||
pivot = parseFloat(pivot)
|
||||
}
|
||||
|
||||
// pick the predicate
|
||||
// depending on the type of the attribute value
|
||||
// var predicateName;
|
||||
if (typeof pivot == 'number') {
|
||||
predicateName = '>=';
|
||||
} else {
|
||||
// there is no sense to compare non-numeric attributes
|
||||
// so we will check only equality of such attributes
|
||||
predicateName = '==';
|
||||
}
|
||||
|
||||
attrPredPivot = attr + predicateName + pivot;
|
||||
if (alreadyChecked[attrPredPivot]) {
|
||||
// skip such pairs of 'attribute-predicate-pivot',
|
||||
// which been already checked
|
||||
//continue;
|
||||
}
|
||||
alreadyChecked[attrPredPivot] = true;
|
||||
|
||||
predicate = predicates[predicateName];
|
||||
|
||||
// splitting training set by given 'attribute-predicate-value'
|
||||
currSplit = split(trainingSet, attr, predicate, pivot);
|
||||
//console.log(currSplit.match)
|
||||
//console.log(currSplit.notMatch)
|
||||
|
||||
// calculating entropy of subsets
|
||||
matchEntropy = entropy(currSplit.match, categoryAttr);
|
||||
notMatchEntropy = entropy(currSplit.notMatch, categoryAttr);
|
||||
|
||||
// calculating informational gain
|
||||
newEntropy = 0;
|
||||
newEntropy += matchEntropy * currSplit.match.length;
|
||||
newEntropy += notMatchEntropy * currSplit.notMatch.length;
|
||||
newEntropy /= trainingSet.length;
|
||||
currGain = initialEntropy - newEntropy;
|
||||
console.log("CURRENT GAIN "+currGain)
|
||||
if (currGain > bestSplit.gain) {
|
||||
// remember pairs 'attribute-predicate-value'
|
||||
// which provides informational gain
|
||||
bestSplit = currSplit;
|
||||
bestSplit.predicateName = predicateName;
|
||||
bestSplit.predicate = predicate;
|
||||
bestSplit.attribute = attr;
|
||||
bestSplit.pivot = pivot;
|
||||
bestSplit.gain = currGain;
|
||||
}
|
||||
|
||||
isChanged=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//delete space from property in object
|
||||
// let ignore=""
|
||||
// if(!(Object.entries(ignoredAttributes).length === 0 && ignoredAttributes.constructor === Object)){
|
||||
// ignore = Object.keys(ignoredAttributes)
|
||||
// ignore = ignore[0].substring(0, ignore[0].length - 1);
|
||||
// console.log(ignore)
|
||||
// }
|
||||
//console.log("Liczy")
|
||||
|
||||
for (var i = trainingSet.length - 1; i >= 0; i--) {
|
||||
var item = trainingSet[i];
|
||||
|
||||
// iterating over all attributes of item
|
||||
for (var attr in item) {
|
||||
//console.log(ignoredAttributes)
|
||||
//if(ignoredAttributes[attr]===true) console.log("równe")
|
||||
if ((attr === categoryAttr) || ignoredAttributes[attr]) {
|
||||
//if ((attr === categoryAttr) || ignore===attr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// let the value of current attribute be the pivot
|
||||
pivot = item[attr];
|
||||
if(!isNaN(pivot))
|
||||
{
|
||||
pivot = parseFloat(pivot)
|
||||
}
|
||||
// pick the predicate
|
||||
// depending on the type of the attribute value
|
||||
//var predicateName;
|
||||
if (typeof pivot == 'number') {
|
||||
//console.log('is number ' + pivot + ' ' + typeof pivot)
|
||||
predicateName = '>=';
|
||||
} else {
|
||||
//console.log('is not number ' + pivot + ' ' + typeof pivot)
|
||||
|
||||
// there is no sense to compare non-numeric attributes
|
||||
// so we will check only equality of such attributes
|
||||
predicateName = '==';
|
||||
}
|
||||
|
||||
attrPredPivot = attr + predicateName + pivot;
|
||||
if (alreadyChecked[attrPredPivot]) {
|
||||
// skip such pairs of 'attribute-predicate-pivot',
|
||||
// which been already checked
|
||||
continue;
|
||||
}
|
||||
alreadyChecked[attrPredPivot] = true;
|
||||
|
||||
predicate = predicates[predicateName];
|
||||
|
||||
// splitting training set by given 'attribute-predicate-value'
|
||||
currSplit = split(trainingSet, attr, predicate, pivot);
|
||||
////console.log(currSplit)
|
||||
// calculating entropy of subsets
|
||||
matchEntropy = entropy(currSplit.match, categoryAttr);
|
||||
notMatchEntropy = entropy(currSplit.notMatch, categoryAttr);
|
||||
////console.log(bestSplit.gain)
|
||||
// calculating informational gain
|
||||
newEntropy = 0;
|
||||
newEntropy += matchEntropy * currSplit.match.length;
|
||||
newEntropy += notMatchEntropy * currSplit.notMatch.length;
|
||||
newEntropy /= trainingSet.length;
|
||||
currGain = initialEntropy - newEntropy;
|
||||
//console.log("CURRENT GAIN 2"+currGain)
|
||||
if (currGain > bestSplit.gain) {
|
||||
// remember pairs 'attribute-predicate-value'
|
||||
// which provides informational gain
|
||||
bestSplit = currSplit;
|
||||
bestSplit.predicateName = predicateName;
|
||||
bestSplit.predicate = predicate;
|
||||
bestSplit.attribute = attr;
|
||||
bestSplit.pivot = pivot;
|
||||
bestSplit.gain = currGain;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(bestSplit.gain)
|
||||
if (!bestSplit.gain) {
|
||||
let _category=mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter=0;
|
||||
let _hide=0
|
||||
//console.log(trainingSet);
|
||||
trainingSet.forEach(element => {
|
||||
if(element[categoryAttr]===_category)_positiveCounter++;
|
||||
|
||||
});
|
||||
let _negativeCounter=trainingSet.length-_positiveCounter;
|
||||
_quality=_positiveCounter/trainingSet.length;
|
||||
if(_quality!==1) _hide=25;
|
||||
_quality=_quality*100;
|
||||
_quality=_quality.toFixed(2);
|
||||
// can't find optimal split
|
||||
return { category:_category, quality:_quality,matchedCount:_positiveCounter,notMatchedCount:_negativeCounter, hide:_hide};
|
||||
}
|
||||
|
||||
if(window.isChange)
|
||||
{
|
||||
bestSplit.pivot=window.inputValue;
|
||||
window.isChange=false;
|
||||
}
|
||||
|
||||
let array = bestSplit.match.concat(bestSplit.notMatch);
|
||||
window.list_obj.push({id:window.counter,match:bestSplit.match,notMatch:bestSplit.notMatch, full:array});
|
||||
window.counter++;
|
||||
//console.log(window.list_obj)
|
||||
debugger;
|
||||
// nie przekazujemy isChanged bo jest już defaultowo na false nastawiony
|
||||
// building subtrees
|
||||
builder.maxTreeDepth = maxTreeDepth - 1;
|
||||
|
||||
builder.trainingSet = bestSplit.match;
|
||||
var matchSubTree = buildDecisionTree(builder);
|
||||
|
||||
builder.trainingSet = bestSplit.notMatch;
|
||||
var notMatchSubTree = buildDecisionTree(builder);
|
||||
|
||||
return {
|
||||
attribute: bestSplit.attribute,
|
||||
predicate: bestSplit.predicate,
|
||||
predicateName: bestSplit.predicateName,
|
||||
pivot: bestSplit.pivot,
|
||||
match: matchSubTree,
|
||||
notMatch: notMatchSubTree,
|
||||
matchedCount: bestSplit.match.length,
|
||||
notMatchedCount: bestSplit.notMatch.length
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Classifying item, using decision tree
|
||||
*/
|
||||
function predict(tree, item) {
|
||||
var attr,
|
||||
value,
|
||||
predicate,
|
||||
pivot;
|
||||
|
||||
// Traversing tree from the root to leaf
|
||||
while(true) {
|
||||
|
||||
if (tree.category) {
|
||||
// only leafs contains predicted category
|
||||
return tree.category;
|
||||
}
|
||||
|
||||
attr = tree.attribute;
|
||||
value = item[attr];
|
||||
|
||||
predicate = tree.predicate;
|
||||
pivot = tree.pivot;
|
||||
|
||||
// move to one of subtrees
|
||||
if (predicate(value, pivot)) {
|
||||
tree = tree.match;
|
||||
} else {
|
||||
tree = tree.notMatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Building array of decision trees
|
||||
*/
|
||||
function buildRandomForest(builder, treesNumber) {
|
||||
var items = builder.trainingSet;
|
||||
|
||||
// creating training sets for each tree
|
||||
var trainingSets = [];
|
||||
for (var t = 0; t < treesNumber; t++) {
|
||||
trainingSets[t] = [];
|
||||
}
|
||||
for (var i = items.length - 1; i >= 0 ; i--) {
|
||||
// assigning items to training sets of each tree
|
||||
// using 'round-robin' strategy
|
||||
var correspondingTree = i % treesNumber;
|
||||
trainingSets[correspondingTree].push(items[i]);
|
||||
}
|
||||
|
||||
// building decision trees
|
||||
var forest = [];
|
||||
for (var tt = 0; tt < treesNumber; tt++) {
|
||||
builder.trainingSet = trainingSets[tt];
|
||||
|
||||
var tree = new TSPDecisionTree(builder);
|
||||
forest.push(tree);
|
||||
}
|
||||
return forest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each of decision tree classifying item
|
||||
* ('voting' that item corresponds to some class).
|
||||
*
|
||||
* This function returns hash, which contains
|
||||
* all classifying results, and number of votes
|
||||
* which were given for each of classifying results
|
||||
*/
|
||||
function predictRandomForest(forest, item) {
|
||||
var result = {};
|
||||
for (var i in forest) {
|
||||
var tree = forest[i];
|
||||
var prediction = tree.predict(item);
|
||||
result[prediction] = result[prediction] ? result[prediction] + 1 : 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var exports = {};
|
||||
exports.DecisionTree = TSPDecisionTree;
|
||||
exports.RandomForest = RandomForest;
|
||||
return exports;
|
||||
})();
|
||||
@@ -1,5 +1,5 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
import App from '../App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
12
src/utils/file-reader.js
Normal file
12
src/utils/file-reader.js
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @param {File} file
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export function readLocalFile(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => resolve(reader.result.toString());
|
||||
reader.onerror = reject;
|
||||
reader.readAsText(file);
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user