This commit is contained in:
Hubert Sokołowski
2021-01-17 22:27:01 +01:00
parent b18df23653
commit ee1c0de7f7
26 changed files with 177950 additions and 26 deletions

1
.gitignore vendored
View File

@@ -21,3 +21,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.eslintcache

1825
package-lock.json generated
View File

File diff suppressed because it is too large Load Diff

View File

@@ -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"
}
}

View File

@@ -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;

View 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
View 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;

View 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
View 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
View 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;

View File

View File

50
src/css/main.scss Normal file
View 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;
}

View File

File diff suppressed because it is too large Load Diff

28383
src/data/ar2.json Normal file
View File

File diff suppressed because it is too large Load Diff

115493
src/data/arrythmia.json Normal file
View File

File diff suppressed because it is too large Load Diff

152
src/data/iris.json Normal file
View 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
View 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
View 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

View File

@@ -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>

View File

@@ -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
View 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
View 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;
})();

View File

@@ -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
View 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);
})
}