Как ввести шум в данные последовательности, используя TraMineR? - PullRequest
0 голосов
/ 03 июля 2018

Я хочу случайным образом изменить состояния в наборе данных последовательности для целей моделирования. Цель состоит в том, чтобы увидеть, как различные показатели качества кластеров ведут себя с различными степенями структуры данных.

Если бы я вводил пропуски, в TraMineRextras есть удобная функция seqgen.missing(), но она добавляет только пропущенные состояния. Как бы я пошел случайным образом выбрать пропорцию p последовательностей и случайным образом вставить в них случайно выбранный элемент алфавита с вероятностями p_g, p_l и p_r для их вставки в середину, слева и право?

1 Ответ

0 голосов
/ 04 июля 2018

Ниже приведена функция seq.rand.chg (адаптированная от seqgen.missing), которая случайным образом применяет изменения состояния к пропорции p.cases последовательностей. Для каждой случайно выбранной последовательности функция случайным образом меняет состояние либо

  1. Когда p.gaps > 0, в пропорции от 0 до p.gaps позиций;

  2. Когда p.left > 0 и / или p.right > 0, самое большее p.left (p.right) в пропорции слева (справа).

Как и в функции seqgen.missing, p.gaps, p.left и p.right - это максимальная доля случаев, измененных в каждой выбранной последовательности. Это не совсем ваши вероятности p_g, p_l и p_r. Но должно быть легко адаптировать функцию для этого.

Вот функция:

seq.rand.chg <- function(seqdata, p.cases=.1, p.left=.0, p.gaps=0.1, p.right=.0){
  n <- nrow(seqdata)
  alph <- alphabet(seqdata)
  lalph <- length(alph)
  lgth <- max(seqlength(seqdata))

  nm <- round(p.cases * n, 0)
  ## selecting cases
  idm <- sort(sample(1:n, nm))
  rdu.r <- runif(n,min=0,max=p.right)
  rdu.g <- runif(n,min=0,max=p.gaps)
  rdu.l <- runif(n,min=0,max=p.left)

  for (i in idm){
    # inner positions
    gaps <- sample(1:lgth, round(rdu.g[i] * lgth, 0))
    seqdata[i,gaps] <- alph[sample(1:lalph, length(gaps), replace=TRUE)]
    # left positions
    nl <- round(rdu.l[i] * lgth, 0)
    if (nl>0) seqdata[i,1:nl] <- alph[sample(1:lalph, nl, replace=TRUE)]
    # right positions
    nr <- round(rdu.r[i] * lgth, 0)
    if (nr>0) seqdata[i,(lgth-nr+1):lgth] <- alph[sample(1:lalph, nr, replace=TRUE)]
  }

  return(seqdata)
}

Мы иллюстрируем использование функции с первыми тремя последовательностями данных mvad

library(TraMineR)
data(mvad)
mvad.lab <- c("employment", "further education", "higher education",
              "joblessness", "school", "training")
mvad.shortlab <- c("EM", "FE", "HE", "JL", "SC", "TR")
mvad.seq <- seqdef(mvad[, 17:62], states = mvad.shortlab,
                   labels = mvad.lab, xtstep = 6)
mvad.ori <- mvad.seq[1:3,]

## Changing up to 50% of states in 30% of the sequences
seed=11
mvad.chg <- seq.rand.chg(mvad.ori, p.cases = .3, p.gaps=0.5)

## plotting the outcome 
par(mfrow=c(3,1))
seqiplot(mvad.ori, with.legend=FALSE, main="Original sequences")
seqiplot(mvad.chg, with.legend=FALSE, main="After random changes")
seqlegend(mvad.ori, ncol=6 )

Sequences before and after changes]

Мы видим, что изменения были применены к случайно выбранной 3-й последовательности.

...