国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

PHP局部異常因子算法-Local Outlier Factor(LOF)算法的具體實現解析

瀏覽:83日期:2022-09-06 17:51:20

這兩天在完善自己系統的過程中要實現一個查找異常的功能,于是在朋友的指點下學習并實現了異常點查找的一個基本算法“局部異常因子算法-Local Outlier Factor(LOF)算法”。

首先,找相關說明看看這是個什么東西吧。

我參考了這一篇文章: 異常點/離群點檢測算法——LOF

大致明白了lof算法是在講什么,我的理解還有很多不完善的地方,不過還是作為一個初學者寫出來供大家批評指正。

根據我的理解大致描述如下:

1、 k-distance,點p的第k距離就是距離點p第k遠的那個點的距離,k可以是任意值。在實際生活中可能會這樣:小明說“小紅家是離我家第五近的,小趙、小錢、小孫、小李家都比她家離我家近”所以此處小紅家距離小明家的距離就是小明家k為5時的第k距離。

2、k-distance neighborhood of p,第k距離領域,按照上面的例子就是{小趙、小錢、小孫、小李、小紅},把離p最近的k個點放入一個數組就是第k距離領域了。

3、reach-distance:可達距離。點o到點p的第k可達距離分兩種情況,一種是p在o的第k距離領域那個數組中,這時候可達距離等于第k距離,第二種就是p離點o比較遠,不在o的第k距離領域中,此時的可達距離即為真實距離。依然使用上述的例子,小趙家在小明家的第k鄰域中,所以可達距離就是第k距離,就是小紅家的距離,而二狗子家里小明家很遠,可達距離就是真實距離了。

4、local reachability density:局部可達密度。點p的局部可達密度是指點p第k距離鄰域中所有成員到點p的可達距離的平均值的倒數,有點復雜,不過多讀幾遍還是蠻好理解的,就不舉例子了。

5、local outlier factor:局部離群因子。點p的局部離群因子即為領域中所有點的局部可達密度的平均數比點p的局部可達密度,不做解釋。到這里為止就是我對lof算法的一個大致理解,具體講解還要看上面我參考的那篇文章,寫的很清楚。

接下來我找了網上的一篇對此算法的實現,很遺憾沒有php版本,于是我就找到了這篇文章:基于密度的局部離群點檢測(lof算法) (Java 實現)

如題所示,是一篇Java實現,于是我就在大神的基礎上對其進行修改,改成了一個php的版本。因為對迭代器理解的不是很好,所以迭代器實現部分改成了一般函數,有機會再進行完善。

如下:

<?php class DataNode { private $nodeName; // 樣本點名 private $dimensioin; // 樣本點的維度 private $kDistance; // k-距離 private $kNeighbor = array();// k-領域 private $distance; // 到給定點的歐幾里得距離 private $reachDensity;// 可達密度 private $reachDis;// 可達距離private $lof;// 局部離群因子public function __construct() { $num = func_num_args(); //獲得參數個數$args = func_get_args(); //獲得參數列表數組switch($num){case 0: break;case 2:$this->__call(’__construct2’, $args);break;} } public function __call($name, $arg) //根據函數名調用函數{return call_user_func_array(array($this, $name), $arg);} public function __construct2($nodeName, $dimensioin){$this->nodeName = $nodeName; $this->dimensioin = $dimensioin; } public function getNodeName() { return $this->nodeName; }public function setNodeName($nodeName) { $this->nodeName = $nodeName; }public function getDimensioin() { return $this->dimensioin; }public function setDimensioin($dimensioin) { $this->dimensioin = $dimensioin; }public function getkDistance() { return $this->kDistance; }public function setkDistance($kDistance) { $this->kDistance = $kDistance; }public function getkNeighbor() { return $this->kNeighbor; }public function setkNeighbor($kNeighbor) { $this->kNeighbor = $kNeighbor; }public function getDistance() { return $this->distance; }public function setDistance($distance) { $this->distance = $distance; }public function getReachDensity() { return $this->reachDensity; }public function setReachDensity($reachDensity) { $this->reachDensity = $reachDensity; }public function getReachDis() { return $this->reachDis; }public function setReachDis($reachDis) { $this->reachDis = $reachDis; }public function getLof() { return $this->lof; }public function setLof($lof) { $this->lof = $lof; } } class OutlierNodeDetect { private static $INT_K = 5;//正整數K// 1.找到給定點與其他點的歐幾里得距離 // 2.對歐幾里得距離進行排序,找到前5位的點,并同時記下k距離 // 3.計算每個點的可達密度 // 4.計算每個點的局部離群點因子 // 5.對每個點的局部離群點因子進行排序,輸出。 public function getOutlierNode($allNodes) { $kdAndKnList = $this->getKDAndKN($allNodes); $this->calReachDis($kdAndKnList); $this->calReachDensity($kdAndKnList); $this->calLof($kdAndKnList); //降序排序 $kdAndKnList = $this->rsortArr($kdAndKnList); return $kdAndKnList; }/** * 計算每個點的局部離群點因子 * @param kdAndKnList */ private function calLof($kdAndKnList) { foreach($kdAndKnList as $node): $tempNodes = $node->getkNeighbor(); $sum = 0.0; foreach($tempNodes as $tempNode): $rd = $this->getRD($tempNode->getNodeName(), $kdAndKnList); $sum = $rd / $node->getReachDensity() + $sum; endforeach; $sum = $sum / (double) self::$INT_K; $node->setLof($sum); endforeach; }/** * 計算每個點的可達距離 * @param kdAndKnList */ private function calReachDensity($kdAndKnList) { foreach($kdAndKnList as $node): $tempNodes = $node->getkNeighbor(); $sum = 0.0; $rd = 0.0; foreach($tempNodes as $tempNode): $sum = $tempNode->getReachDis() + $sum; endforeach; $rd = (double) self::$INT_K / $sum; $node->setReachDensity($rd); endforeach; } /** * 計算每個點的可達密度,reachdis(p,o)=max{ k-distance(o),d(p,o)} * @param kdAndKnList */ private function calReachDis($kdAndKnList) { //for (DataNode node : kdAndKnList) { foreach($kdAndKnList as $node): $tempNodes = $node->getkNeighbor(); //for (DataNode tempNode : tempNodes) { foreach($tempNodes as $tempNode): //獲取tempNode點的k-距離 $kDis = $this->getKDis($tempNode->getNodeName(), $kdAndKnList); if ($kDis < $tempNode->getDistance()) { $tempNode->setReachDis($tempNode->getDistance()); } else { $tempNode->setReachDis($kDis); } endforeach; endforeach; }/** * 獲取某個點的k-距離(kDistance) * @param nodeName * @param nodeList * @return */ private function getKDis($nodeName,$nodeList) { $kDis = 0; //for (DataNode node : nodeList) { foreach($nodeList as $node): if ($this->strcomp(trim($nodeName),trim($node->getNodeName()))) { $kDis =$node->getkDistance(); break; } endforeach; return $kDis;} privatefunction strcomp($str1,$str2){ if($str1 == $str2){ return TRUE; }else{ return FALSE; } } /** * 獲取某個點的可達距離 * @param nodeName * @param nodeList * @return */ private function getRD($nodeName, $nodeList) { $kDis = 0; //for (DataNode node : nodeList) { foreach($nodeList as $node): //if (nodeName.trim().equals(node.getNodeName().trim())) { if ($this->strcomp(trim($nodeName),trim($node->getNodeName()))) { $kDis = $node->getReachDensity(); break; } endforeach; return $kDis;} /** * 計算給定點NodeA與其他點NodeB的歐幾里得距離(distance),并找到NodeA點的前5位NodeB,然后記錄到NodeA的k-領域(kNeighbor)變量。 * 同時找到NodeA的k距離,然后記錄到NodeA的k-距離(kDistance)變量中。 * 處理步驟如下: * 1,計算給定點NodeA與其他點NodeB的歐幾里得距離,并記錄在NodeB點的distance變量中。 * 2,對所有NodeB點中的distance進行升序排序。 * 3,找到NodeB點的前5位的歐幾里得距離點,并記錄到到NodeA的kNeighbor變量中。 * 4,找到NodeB點的第5位距離,并記錄到NodeA點的kDistance變量中。 * @param allNodes * @return List<Node> */ private function getKDAndKN($allNodes) { $kdAndKnList = array(); for ($i = 0 ; $i < count($allNodes); $i++) { $tempNodeList = array(); $nodeA = new DataNode($allNodes[$i]->getNodeName(), $allNodes[$i]->getDimensioin()); //1,找到給定點NodeA與其他點NodeB的歐幾里得距離,并記錄在NodeB點的distance變量中。 for ($j = 0; $j < count($allNodes); $j++) { $nodeB = new DataNode($allNodes[$j]->getNodeName(), $allNodes[$j]->getDimensioin()); //計算NodeA與NodeB的歐幾里得距離(distance) $tempDis = $this->getDis($nodeA, $nodeB); $nodeB->setDistance($tempDis);array_push($tempNodeList,$nodeB);//$tempNodeList.add(nodeB); } //2,對所有NodeB點中的歐幾里得距離(distance)進行升序排序。$tempNodeList = $this->sortArr($tempNodeList); $neighArr = array(); for ($k = 1; $k <= self::$INT_K; $k++) { //3,找到NodeB點的前5位的歐幾里得距離點,并記錄到到NodeA的kNeighbor變量中。 array_push($neighArr ,$tempNodeList[$k]);if ($k == self::$INT_K - 1) { //4,找到NodeB點的第5位距離,并記錄到NodeA點的kDistance變量中。 $nodeA->setkDistance($tempNodeList[$k]->getDistance());} } $nodeA->setkNeighbor($neighArr); array_push($kdAndKnList,$nodeA); } return $kdAndKnList; } /** * 計算給定點A與其他點B之間的歐幾里得距離。 * 歐氏距離的公式: * d=sqrt( ∑(xi1-xi2)^2 ) 這里i=1,2..n * xi1表示第一個點的第i維坐標,xi2表示第二個點的第i維坐標 * n維歐氏空間是一個點集,它的每個點可以表示為(x(1),x(2),...x(n)), * 其中x(i)(i=1,2...n)是實數,稱為x的第i個坐標,兩個點x和y=(y(1),y(2)...y(n))之間的距離d(x,y)定義為上面的公式. * @param A * @param B * @return */ private function getDis($A, $B) { $dis = 0.0; $dimA = $A->getDimensioin(); $dimB = $B->getDimensioin(); if (count($dimA) == count($dimB)) { for ($i = 0; $i < count($dimA); $i++) { $temp = pow($dimA[$i] - $dimB[$i], 2); $dis = $dis + $temp; } $dis = pow($dis, 0.5); } return $dis; } //Distance比較 private function compareAandB($arr,$A, $B) { if(($arr[$A]->getDistance()-$arr[$B]->getDistance())<0) return -1;else if(($arr[$A]->getDistance()-$arr[$B]->getDistance())>0) return 1;else return 0; }//lof比較 private function compareAandBLof($arr,$A, $B) { if(($arr[$A]->getLof()-$arr[$B]->getLof())<0) return -1;else if(($arr[$A]->getLof()-$arr[$B]->getLof())>0) return 1;else return 0; }private function changeAandB($arr,$A, $B) { $tempChange = $arr[$A]; $arr[$A] = $arr[$B];$arr[$B] = $tempChange;return $arr; } //Distance升序 private function sortArr($arr) { for($i = 0;$i < count($arr);$i ++){for($j = $i + 1;$j < count($arr);$j ++){if($this->compareAandB($arr,$i, $j)>0){$arr=$this->changeAandB($arr,$i, $j);}}}return $arr; } //lof降序 private function rsortArr($arr) { for($i = 0;$i < count($arr);$i ++){for($j = $i + 1;$j < count($arr);$j ++){if($this->compareAandBLof($arr,$i, $j)<0){$arr=$this->changeAandB($arr,$i, $j);}}}return $arr; } public static function main() { $dpoints = array(); $a = array( 2, 3 ); $b = array( 2, 4 ); $c = array( 1, 4 ); $d = array( 1, 3 ); $e = array( 2, 2 ); $f = array( 3, 2 ); $g = array( 8, 7 ); $h = array( 8, 6 ); $i = array( 7, 7 ); $j = array( 7, 6 ); $k = array( 8, 5 ); $l = array( 100, 2 );// 孤立點 $m = array( 8, 20 ); $n = array( 8, 19 ); $o = array( 7, 18 ); $p = array( 7, 17 ); $yichen = array( 8, 21 ); array_push($dpoints,new DataNode('a', $a)); array_push($dpoints,new DataNode('b', $b)); array_push($dpoints,new DataNode('c', $c)); array_push($dpoints,new DataNode('d', $d)); array_push($dpoints,new DataNode('e', $e)); array_push($dpoints,new DataNode('f', $f)); array_push($dpoints,new DataNode('g', $g)); array_push($dpoints,new DataNode('h', $h)); array_push($dpoints,new DataNode('i', $i)); array_push($dpoints,new DataNode('j', $j)); array_push($dpoints,new DataNode('k', $k)); array_push($dpoints,new DataNode('l', $l)); array_push($dpoints,new DataNode('m', $m)); array_push($dpoints,new DataNode('n', $n)); array_push($dpoints,new DataNode('o', $o)); array_push($dpoints,new DataNode('p', $p)); array_push($dpoints,new DataNode('yichen', $yichen)); $lof = new OutlierNodeDetect(); $nodeList = $lof->getOutlierNode($dpoints); foreach($nodeList as $node): echo($node->getNodeName() . '--' . round($node->getLof(),4)); echo('<br>');endforeach; } } OutlierNodeDetect::main(); ?>

到此這篇關于PHP局部異常因子算法-Local Outlier Factor(LOF)算法的具體實現解析的文章就介紹到這了,更多相關PHP局部異常因子算法-Local Outlier Factor(LOF)算法內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: PHP
相關文章:
主站蜘蛛池模板: 亚洲一区二区视频 | 亚洲一区在线视频观看 | 天天干夜夜怕 | 欧美一区二区三区不卡免费观看 | 国产嫩草影院在线观看 | 美女流白浆网站 | 久久视频6免费观看视频精品 | 欧美精品人爱a欧美精品 | 在线观看一级毛片免费 | 久久99精品久久久久久三级 | 99久久国产综合精品五月天 | 亚洲一区二区三区福利在线 | 中文一区 | 色午夜在线 | 一个人的视频日本免费 | 五月色婷婷综合开心网4438 | 亚洲国产一区二区三区在线观看 | 91精品国产高清久久久久久91 | 欧美日韩在线观看区一二 | 欧美三级美国一级 | 亚洲一区二区三区成人 | 精品欧美成人高清在线观看2021 | 欧美性色xo在线 | a级毛片免费观看视频 | 亚洲毛片一级巨乳 | 久久久美女视频 | 黄色毛片视频网站 | 国产精品久久久久久久久免费观看 | 一本久道久久综合婷婷 | 免费萌白酱国产一区二区三区 | 性xxx69xxx视频在线观看 | 男人天堂成人 | 一区二区国产在线观看 | 久久国产首页 | 国产一级毛片一区二区三区 | 久久久久久极精品久久久 | 亚洲精品一区二区三区网址 | 亚洲女人被黑人猛躁进女人 | 日韩视频在线观看一区二区 | 夜夜骚视频 | 欧美日韩亚洲成色二本道三区 |