他の回答で提案されたアプローチを簡単な例で説明しましょう
データを取得する
さまざまな手段で正規分布で生成された7つのチャンクを使用してデータをシミュレートします。
これは、グループを明確に区別し、簡単に限界点を検出できるため、重要です。この回答は基本的なしきい値のアプローチを使用しています。実際のデータには、より高度な方法が必要になる場合があります。
dt <- rbind(
data.frame(color=1, x = round(runif(50, min = 0, max = 50)), y = rnorm (50,mean=3.9, sd=.03)),
data.frame(color=2, x = round(runif(15, min = 50, max = 65)), y = rnorm (15,mean=4.5, sd=.03)),
data.frame(color=2, x = round(runif(15, min = 65, max = 80)), y = rnorm (15,mean=3.3, sd=.03)),
data.frame(color=1, x = round(runif(70, min = 80, max = 150)), y = rnorm (70,mean=3.9, sd=.03)),
data.frame(color=2, x = round(runif(15, min = 150, max = 165)), y = rnorm (15,mean=3.3, sd=.03)),
data.frame(color=3, x = round(runif(15, min = 165, max = 180)), y = rnorm (15,mean=2.9, sd=.03)),
data.frame(color=1, x = round(runif(120, min = 180, max = 300)), y = rnorm (120,mean=3.9, sd=.03))
)
dt$color <- as.factor(dt$color)
dt <- as_tibble(dt)
限界点を導き出す
前のポイントとの単純な違いによりlag(y)
、外れ値を取得します。それらは、しきい値を使用して分類されます。
行動分類の変更
あなたが説明したルールに基づいて、限界点はOK
およびに分類されproblem
ます。
この規則では、同じ方向の2つの変更は許可されていません。前の方向への2番目の動きは問題と見なされます。
logikがより高度な場合は、この単純な解釈を調整する必要がある場合があります。
## extract outliers and get previous value
dt2 <- filter(dt2, diff != 0) %>%
mutate(cs = cumsum(diff),
prev = lag(diff),
cls = case_when(
diff * prev > 0 ~ "problem",
TRUE ~ "OK"))
## show
dt2 %>% select(x,y,diff,prev,cls)
## # A tibble: 6 x 5
## x y diff prev cls
## <dbl> <dbl> <dbl> <dbl> <chr>
## 1 50 4.53 1 NA OK
## 2 66 3.32 -1 1 OK
## 3 80 3.87 1 -1 OK
## 4 151 3.32 -1 1 OK
## 5 167 2.91 -1 -1 problem
## 6 180 3.87 1 -1 OK
プレゼンテーション
最後に、認識された外れ値を元のデータに投影します
## project in the original data
ggplot(data=dt, mapping = aes(x=x, y=y) ) +
geom_point(mapping = aes(color = color) ) +
scale_color_manual(values=c("blue", "yellow", "red","green","red")) +
theme(legend.position="none") +
geom_vline(data=dt2, aes(xintercept=x, color=cls),
linetype="dashed", size = 2)