uid[] $max = count($positives); for ($i = 0; $i < $max; $i++) { $positive = $positives->sample($i); $uidVecStr = implode('', array_slice($positive, 0, 16)); $ipVecStr = implode('', array_slice($positive, 16)); if (!isset($map[$ipVecStr])) { $map[$ipVecStr] = [ $uidVecStr, ]; } elseif (!in_array($uidVecStr, $map[$ipVecStr])) { $map[$ipVecStr][] = $uidVecStr; } } $uniqueMap = array_filter($map, function (array $uidVecs) { return count($uidVecs) === 1; }); return array_map(function (string $ipVecStr): array { // Split the IP vec again, but also past the digits return array_map(function (string $c): int { return (int)$c; }, str_split($ipVecStr)); }, array_keys($uniqueMap)); } private function generateFromRealData(array $uidVec, array $uniqueIps): array { return array_merge( $uidVec, $uniqueIps[random_int(0, count($uniqueIps) - 1)] ); } private function generateRandom(array $uidVec, AClassificationStrategy $strategy): array { return array_merge( $uidVec, $strategy->generateRandomIpVector() ); } /** * @param DataSet $positives * @param int $num * * @return DataSet */ public function generateRandomFromPositiveSamples(Dataset $positives, int $num, AClassificationStrategy $strategy): DataSet { $max = count($positives); return new Labeled( array_map(function (int $id) use ($strategy, $positives, $max) { return $this->generateRandom(array_slice($positives[$id % $max], 0, 16), $strategy); }, range(0, $num - 1)), array_fill(0, $num, Trainer::LABEL_NEGATIVE) ); } /** * @param DataSet $positives * @param int $num * * @return DataSet */ public function generateShuffledFromPositiveSamples(DataSet $positives, int $num): DataSet { $max = count($positives); $uniqueIps = $this->getUniqueIPsPerUser($positives); if ($uniqueIps === []) { return new Labeled(); } return new Labeled( array_map(function (int $id) use ($uniqueIps, $positives, $max) { $sample = $positives->sample($id % $max); return $this->generateFromRealData(array_slice($sample, 0, 16), $uniqueIps); }, range(0, $num - 1)), array_fill(0, $num, Trainer::LABEL_NEGATIVE) ); } }