이번 달의 도전 과제에 대한 저의 동기는 이상치에 대한 기존의 정의를 넘어서 데이터 중심에서 멀리 떨어진 관측치(데이터 변동성의 양에 비해)에 불과하다고 생각하게 하는 것이었습니다. 일반적으로 이상치는 나머지 데이터에 속하지 않는 비대표적인 데이터 포인트로 간주할 수 있습니다. 여기에 진정한 도전이 있습니다. 대표자를 어떻게 정의합니까? 내가 아래에 제공하는 접근 방식은 문제에 대한 나의 견해입니다.
아래 알고리즘은 관측치를 점 사이의 거리에 따라 유사하거나 유사하지 않은 집합으로 그룹화합니다. 클러스터링에 대한 표준 응집 접근 방식과 달리 하나의 그룹으로 시작합니다. 거리가 75 사이의 차이의 3배를 초과하는 경우 가장 멀리 떨어져 있는 관측값 사이의 중간 값으로 절단점을 정의합니다. NS 0이 아닌 모든 거리의 분위수 및 중앙값(거리 스프레드). 컷 포인트가 없으면 중지합니다. 그렇지 않으면 기존 그룹을 두 개의 새 그룹으로 바꿉니다. 새 그룹 또는 전체 데이터 세트에서 더 큰 거리를 사용하여 각 새 그룹에 대해 위의 절차를 반복합니다. 절단점이 포함된 그룹이 없을 때까지 계속합니다.
findOutliers = Function({vals},{Default Local},
q1 = 3; //Spread Multiplier
q2 = 0.75; //Quantile to define upper bound of spread
distSpread = 0;
nMissing = 0;
tmpTbl = New Table("tmp",New Column("C1",Values(vals)),Private);
sumTbl = tmpTbl << Summary(Group(:C1),Private);
vals = Column(sumTbl,1) << Get Values;
freqs = Column(sumTbl,2) << Get Values;
If(N Row(Loc(vals)) == 1, Return([]));
Close(tmpTbl,No Save);
If(Is Missing(vals[1]),
nMissing = freqs[1];
freqs = freqs[2::N Row(vals)];
vals = vals[2::N Row(vals)];
);
vals = Sort Ascending(vals[Loc Nonmissing(vals)]);
groups = Eval List({vals});
cutPoints = [];
While(N Items(groups) > 0,
newGroups = {};
For Each({nextVals},groups,
distances = nextVals[2::N Row(nextVals)] - nextVals[1::(N Row(nextVals)-1)];
distSpread = Max(distSpread,Median(distances[Loc(distances>0)]) + q1*(Quantile(q2,distances[Loc(distances>0)]) - Median(distances[Loc(distances>0)])));
maxDist = Maximum(distances);
If(maxDist>distSpread,
cutID = Loc(distances==maxDist)[1];
cutPoints |/= (nextVals[cutID+1]+nextVals[cutID])/2;
If(cutID == 1,
Insert Into(newGroups,nextVals[2::N Row(nextVals)]),//ELSE
If(cutID == N Row(distances),
Insert Into(newGroups,nextVals[1::cutID]),
//ELSE
Insert Into(newGroups,nextVals[1::cutID]);
Insert Into(newGroups,nextVals[(cutID+1)::N Row(nextVals)]);
)
)
);
);
groups = newGroups;
);
cutPoints = Sort Ascending(cutPoints);
cutPoints;
);
시작하려면 단일 값으로 데이터를 우회하기 위해 약간의 하우스키핑이 필요합니다. 의 결과를 바탕으로 도전 9 , 요약을 사용하여 데이터에서 고유한 값을 동시에 찾고 정렬합니다. 거리는 벡터를 1만큼 오프셋하고 그 차이를 취하여 구합니다. 알고리즘은 절단점을 수집하고 절단점이 없는 그룹을 버리는 방식으로 진행됩니다. 이것은 그룹이 남지 않을 때까지 계속됩니다.
알고리즘은 상당히 빠르며, 모든 데이터 열을 처리하는 데 약 1.6초가 필요합니다. 조사 내 컴퓨터의 샘플 데이터 데이터 테이블. 알고리즘 상단에 3배 승수와 75배를 변경할 수 있는 두 개의 변수를 추가했습니다. NS 분위수. 아래 첨부된 스크립트에서, 챌린지 11 이상치 스크리닝 , 약간의 인터페이스를 제공하기 위해 몇 가지 추가 창 드레싱을 포함하여 열 선택 및 요약 정보 및 참조선으로 그려진 절단점이 있는 히스토그램이 포함된 보고서 창 생성을 허용합니다.
다른 스크립팅 프로젝트에서 작업하기 위해 JMP Challenge에서 잠시 휴식을 취하겠습니다. 신규 및 중급 사용자가 JSL 기술을 향상시키는 데 도움이 되도록 소규모 프로젝트에 대한 서면 지침과 비디오를 함께 만들 것입니다. 테이블을 함께 배치하고, 여러 소스의 데이터에 액세스하고, 사용자 지정 보고서를 작성하는 등의 일반적인 작업에 중점을 둘 것입니다. 또한 표현식 처리 및 패턴 일치와 같은 고급 작업을 수행하려고 합니다. 가치 있다고 생각되는 것이 있으면 여기에 게시하거나 커뮤니티 메시지 또는 이메일( don.mccormack@jmp.com ).