电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

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

瀏覽:127日期: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
相關文章:
主站蜘蛛池模板: 小型铜米机-干式铜米机-杂线全自动铜米机-河南鑫世昌机械制造有限公司 | 开锐教育-学历提升-职称评定-职业资格培训-积分入户 | 北京百度网站优化|北京网站建设公司-百谷网络科技 | 安驭邦官网-双向万能直角铣头,加工中心侧铣头,角度头[厂家直销] 闸阀_截止阀_止回阀「生产厂家」-上海卡比阀门有限公司 | 一体化污水处理设备-一体化净水设备-「山东梦之洁水处理」 | 密集架-手摇-智能-移动-价格_内蒙古档案密集架生产厂家 | 厚壁钢管-厚壁无缝钢管-小口径厚壁钢管-大口径厚壁钢管 - 聊城宽达钢管有限公司 | 生物颗粒燃烧机-生物质燃烧机-热风炉-生物颗粒蒸汽发生器-丽水市久凯能源设备有限公司 | 【铜排折弯机,钢丝折弯成型机,汽车发泡钢丝折弯机,线材折弯机厂家,线材成型机,铁线折弯机】贝朗折弯机厂家_东莞市贝朗自动化设备有限公司 | 宿松新闻网 宿松网|宿松在线|宿松门户|安徽宿松(直管县)|宿松新闻综合网站|宿松官方新闻发布 | 康明斯发电机,上柴柴油发电机,玉柴柴油发电机组_海南重康电力官网 | 滚筒线,链板线,总装线,流水线-上海体能机电有限公司 | 高扬程排污泵_隔膜泵_磁力泵_节能自吸离心水泵厂家-【上海博洋】 | ge超声波测厚仪-电动涂膜机-电动划格仪-上海洪富 | 杭州火蝠电商_京东代运营_拼多多全托管代运营【天猫代运营】 | 粘度计,数显粘度计,指针旋转粘度计 | ★店家乐|服装销售管理软件|服装店收银系统|内衣店鞋店进销存软件|连锁店管理软件|收银软件手机版|会员管理系统-手机版,云版,App | 警用|治安|保安|不锈钢岗亭-售货亭价格-垃圾分类亭-移动厕所厂家-苏州灿宇建材 | 电脑知识|软件|系统|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网 | 注塑机-压铸机-塑料注塑机-卧式注塑机-高速注塑机-单缸注塑机厂家-广东联升精密智能装备科技有限公司 | 金属管浮子流量计_金属转子流量计厂家-淮安润中仪表科技有限公司 | 压力控制器,差压控制器,温度控制器,防爆压力控制器,防爆温度控制器,防爆差压控制器-常州天利智能控制股份有限公司 | 液氮罐(生物液氮罐)百科-无锡爱思科| 锡膏喷印机-全自动涂覆机厂家-全自动点胶机-视觉点胶机-深圳市博明智控科技有限公司 | 超声波电磁流量计-液位计-孔板流量计-料位计-江苏信仪自动化仪表有限公司 | 并离网逆变器_高频UPS电源定制_户用储能光伏逆变器厂家-深圳市索克新能源 | 德国UST优斯特氢气检漏仪-德国舒赐乙烷检测仪-北京泽钏 | 天津仓储物流-天津电商云仓-天津云仓一件代发-博程云仓官网 | 电线电缆厂家|沈阳电缆厂|电线厂|沈阳英联塑力线缆有限公司 | 拉力测试机|材料拉伸试验机|电子拉力机价格|万能试验机厂家|苏州皖仪实验仪器有限公司 | ptc_浴霸_大巴_干衣机_呼吸机_毛巾架_电动车加热器-上海帕克 | 动库网动库商城-体育用品专卖店:羽毛球,乒乓球拍,网球,户外装备,运动鞋,运动包,运动服饰专卖店-正品运动品网上商城动库商城网 - 动库商城 | 火锅底料批发-串串香技术培训[川禾川调官网] | CCE素质教育博览会 | CCE素博会 | 教育展 | 美育展 | 科教展 | 素质教育展 | 暴风影音| 农业仪器网 - 中国自动化农业仪器信息交流平台| 铝合金线槽_铝型材加工_空调挡水板厂家-江阴炜福金属制品有限公司 | 体感VRAR全息沉浸式3D投影多媒体展厅展会游戏互动-万展互动 | 聚合氯化铝价格_聚合氯化铝厂家_pac絮凝剂-唐达净水官网 | 臭氧发生器_臭氧消毒机 - 【同林品牌 实力厂家】 | 包头市鑫枫装饰有限公司|