Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP项目中数据可视化(多维缩放?)的算法_Php_Algorithm_Data Visualization_Multi Dimensional Scaling - Fatal编程技术网

PHP项目中数据可视化(多维缩放?)的算法

PHP项目中数据可视化(多维缩放?)的算法,php,algorithm,data-visualization,multi-dimensional-scaling,Php,Algorithm,Data Visualization,Multi Dimensional Scaling,我有+-100个点/值的小矩阵,测试结果和它们之间的距离(0-10,10是最接近的): 我想将其可视化为2D,以便快速找到一组接近的值。所以我需要处理这个矩阵,得到二维点的坐标 方法可能是多维缩放,但我无法找到算法、库或扩展,也无法将数学公式用于PHP代码 我在谷歌上搜索了两天,最近的结果是 - ? (不能作为新手共享更多链接) 我将非常感谢PHP项目中适用的任何解决方案(C++中编译的MaTlab代码)。< /P> 索引X.php: window.onload=函数(){ var chart

我有+-100个点/值的小矩阵,测试结果和它们之间的距离(0-10,10是最接近的):

我想将其可视化为2D,以便快速找到一组接近的值。所以我需要处理这个矩阵,得到二维点的坐标

方法可能是多维缩放,但我无法找到算法、库或扩展,也无法将数学公式用于PHP代码

我在谷歌上搜索了两天,最近的结果是 - ? (不能作为新手共享更多链接)

我将非常感谢PHP项目中适用的任何解决方案(C++中编译的MaTlab代码)。< /P> <代码>索引X.php: window.onload=函数(){ var chart=new CanvasJS.chart(“chartContainer”, { 标题:{ 文本:“MDS”, fontFamily:“arial黑色”, fontColor:“黑色” }, axisX:{ 标题:“, titleFontFamily:“arial” }, axisY:{ 标题:“, titleFontFamily:“arial”, 标题字体:12 }, 数据:[ { 键入:“散布”, ToolTicContent:“{name}x:{y},y:{y}”, 数据点:


请发布一个json_编码的数据样本和您理想的可视化效果。您希望在x轴和y轴上显示什么?据我所知,您有3个维度,而不是2个维度(水平矩阵位置、垂直矩阵位置、值)。您是要查找具有高值的对,还是要查找每个对都具有高值的组?您好,谢谢,这是json_编码矩阵,二维数组,每个点都有:。理想结果:。轴是虚拟的,没有意义,仅帮助显示点之间的距离(我希望是点组)这看起来非常接近我的需要:也许mathlab(R)cmdscale函数的代码(我也找不到)可以直接重写到php中?
index.php:

<?php
require("data.php");
require("Mds.php");
$mds = new Mds();
$mds->prepareData($data);
//cislo udava pocet iteraci algoritmu,
//idealne by melo mit hodnotu pocetUzlu na druhou, prakticky muze byt o dost mensi, 5 az 10 krat pocet uzlu.
$mds->scale(100);
//mira splneni podminek - vraci cislo < mensi nez 1. Cim blizsi k 1, tim lepe vyhovuji vzdalenosti
//z vypocteneho rozlozeni zadanym vzdalenostem.
//v nemetrickych datech ovsem dochazi rychle k poklesu az do zapornych hodnot, protoze ve 2D neexistuje
//pro nektere body zadne spravne misto.
echo $mds->getRSquared();
?>
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer",
{
title:{
text: "MDS",
fontFamily: "arial black",
fontColor: "black"
},
axisX: {
title:"",
titleFontFamily: "arial"

},
axisY:{
title: "",
titleFontFamily: "arial",
titleFontSize: 12
},

data: [
{
type: "scatter",
toolTipContent: "<span style='"'color: {color};'"'><strong>{name}</strong></span> x: {y}, y: {y}",
dataPoints:

<?php
echo $mds->printCoords('{x: %X, y: %Y, name: "%LABEL"}');
?>
}]
});

chart.render();
}
</script>

</head>
<body>
<div id="chartContainer" style="height: 600px; width: 600px;">
</div>

<a href="mds.zip">mds.zip</a>
</body>
</html>


data.php:



$data = array( 
array ("Jablko", "Voda", 2),
array("Jablko", "Ohen", 7),
array("Jablko", "Cervena", 3),
array("Jablko", "Zelena", 2),

array("Voda", "Ohen", 8),
array("Voda", "Cervena", 8),
array("Voda", "Zelena", 2),

array("Ohen", "Cervena", 1),
array("Ohen", "Zelena", 5),

array("Cervena", "Zelena", 3)
);


Mds.php:

<?php

class Mds {
//node - pole tvaru [[x, y, label], ...]
public $nodes = array();

//tvaru [source][target]=distance
public $givenDistances = array();
public $currentDistances = array();


public function prepareData($data) {
$nodesMap = array();
$xxxx = 10000;
$xxx= 1000;

// $xxxx = 5000;
// $xxx = 600;

foreach($data as $link) {
$source = $link[0];
$target = $link[1];
if(!isset($nodesMap[$source])) {
$nodesMap[$source] = true;
$this->nodes[]=array((float) rand(1,$xxxx) / $xxx, (float) rand(1,$xxxx) / $xxx, $source);
}
if(!isset($nodesMap[$target])) {
$nodesMap[$target] = true;
$this->nodes[]= array((float) rand(1,$xxxx) / $xxx, (float) rand(1,$xxxx) / $xxx, $target);
}
}
//vytvori matici pro ulozeni vzdalenosti
foreach($this->nodes as $node) {
$this->givenDistances[$node[2]] = array();
$this->currentDistances[$node[2]] = array();
}
foreach($data as $link) {
$source = $link[0];
$target = $link[1];
$distance = $link[2];
$this->givenDistances[$source][$target] = $distance;
$this->givenDistances[$target][$source] = $distance;
}
}

protected function countCurrentDistances() {
$mean = 0;
$i = 0;

foreach($this->nodes as $nodeA) {
foreach($this->nodes as $nodeB) {
$dist = sqrt(($nodeB[0]-$nodeA[0])*($nodeB[0]-$nodeA[0]) + ($nodeB[1]-$nodeA[1])*($nodeB[1]-$nodeA[1]));
$this->currentDistances[$nodeA[2]][$nodeB[2]] = $dist;

if($nodeA[2]!==$nodeB[2]) {
$mean += $this->givenDistances[$nodeA[2]][$nodeB[2]];
}
}
}
// echo "<pre>";
// var_dump($this->currentDistances);
// echo "</pre>";
$check = array();

$nodesCount = count($this->nodes);
$this->mean = $mean/($nodesCount*$nodesCount);
}

public function getRSquared() {
$this->countCurrentDistances();

$sum = 0;
$SStot = 0;
$SSres = 0;
foreach($this->nodes as $nodeA) {
foreach($this->nodes as $nodeB) {
$aLab = $nodeA[2];
$bLab = $nodeB[2];
if($aLab===$bLab) {
continue;
}

$given = $this->givenDistances[$aLab][$bLab];
$computed = $this->currentDistances[$aLab][$bLab];

$SSres+=(($given-$computed)*($given-$computed));
$SStot+= ($given-$this->mean)*($given-$this->mean);
}
}

return 1 - ($SSres/$SStot);
}

protected function iterate($inverseCoefStrenth=1) {
for($i=0; $i<count($this->nodes); $i++) {
$nodeA = $this->nodes[$i];
$move = array(0,0);
$moves = 0;

for($j=0; $j<count($this->nodes); $j++) {
if($j===$i) {
continue;
}

$nodeB = $this->nodes[$j];
$dist = $this->givenDistances[$nodeA[2]][$nodeB[2]];

$AB = array($nodeB[0]-$nodeA[0], $nodeB[1]-$nodeA[1]);
$lAB = sqrt(($AB[0]*$AB[0])+($AB[1]*$AB[1]));

$coef = ($lAB - $dist)/$lAB;

$AA1 = array($AB[0]*$coef, $AB[1]*$coef);

$moves++;
$move[0]+=$AA1[0];
$move[1]+=$AA1[1];
}

if($moves>0) {
$resultingMoveX = $move[0]/($moves*$inverseCoefStrenth);
$resultingMoveY = $move[1]/($moves*$inverseCoefStrenth);
$this->nodes[$i][0]+=$resultingMoveX;
$this->nodes[$i][1]+=$resultingMoveY;
}
}
}


public function scale($iterations, $coefIncrease=0) {
$basicCoef=1;
for($i=0; $i<$iterations; $i++) {
$this->iterate($basicCoef);
//echo $this->getRSquared();
//echo " | ";

$basicCoef+=$coefIncrease;
}
}

public function coordsAsString() {
$coords = array();
foreach($this->nodes as $node) {
$coords[]="[{$node[0]}, {$node[1]}]";
}

$res = join(", ",$coords);
return "[$res]";
}

public function printCoords($pattern='[%X,%Y,"%LABEL"]') {
$coords = array();
foreach($this->nodes as $node) {
$x = $node[0];
$y = $node[1];
$label = $node[2];
$res = str_replace('%X', $x, $pattern);
$res = str_replace('%Y', $y, $res);
$res = str_replace('%LABEL', $label, $res);
$coords[]=$res;
}

$res = join(", ",$coords);
return "[$res]";
}

public function pointsCoords() {
$coords = array();
foreach($this->nodes as $node) {
$res['x'] = round($node[0]*100);
$res['y'] = round($node[1]*100);
$res['label'] = $node[2];
$coords[] = $res;
}
return $coords;
}

}