Anomaly detection is the process of examining a dataset to find data items that are unusual in some way. There are many different anomaly detection techniques. One of the basic techniques is simple: use k-means clustering to group the dataset of interest, then find the data items that are most different from their associated cluster mean.
I put together a demo using JavaScript. I used a 200-item set of synthetic data that looks like:
-0.1660 0.4406 -0.9998 -0.3953 -0.7065 0.4840 0.0776 -0.1616 0.3704 -0.5911 0.7562 0.1568 . . .
The output of the demo is:
Begin k-means anomaly detection JavaScript Loading synthetic (200) data X data: [ 0] -0.1660 0.4406 -0.9998 -0.3953 -0.7065 0.4840 [ 1] 0.0776 -0.1616 0.3704 -0.5911 0.7562 0.1568 [ 2] -0.9452 0.3409 -0.1654 0.1174 -0.7192 0.8054 [ 3] 0.9365 -0.3732 0.3846 0.7528 0.7892 0.1345 [ 4] -0.8299 -0.9219 -0.6603 0.7563 -0.8033 0.7955 . . . Clustering with k=3 Done Clustering: 2 0 1 0 1 2 1 2 1 1 2 2 0 2 1 2 1 0 1 2 1 2 0 2 1 0 1 2 2 1 2 0 0 0 1 0 2 0 2 0 1 0 0 1 1 0 2 1 2 1 1 2 2 0 0 2 0 2 0 1 2 1 1 0 2 0 0 1 1 1 0 0 2 1 0 1 1 1 0 1 0 1 0 1 0 0 2 2 1 1 0 0 0 0 2 1 1 2 1 2 2 1 1 1 0 0 0 0 2 2 1 2 0 0 0 0 0 1 0 0 2 0 0 2 1 0 1 2 2 1 2 1 2 1 1 1 1 0 2 1 2 2 1 2 1 1 0 0 2 0 2 2 1 0 2 0 1 1 0 0 1 1 0 0 2 2 0 2 2 0 1 0 0 2 1 2 2 2 1 1 2 1 0 0 2 1 2 2 1 0 0 2 2 2 1 0 1 0 2 1 Means: [ 0] 0.2662 -0.3617 0.5050 0.0062 0.2880 0.2144 [ 1] -0.6035 0.0620 -0.1627 0.0374 -0.1405 0.5631 [ 2] 0.4208 0.3543 -0.3674 -0.1722 0.0537 0.2609 WCSS: 240.7398 Anomalies: cluster idx distance data[idx] ----------------------------------------- 0 [107] 1.6625 [ 0.5175 0.4339 0.9747 -0.4438 -0.9924 0.2879] 1 [136] 1.6207 [-0.0588 0.9731 0.8966 0.2902 -0.6966 0.4955] 2 [138] 1.6812 [ 0.1587 0.8494 -0.8705 0.9827 -0.8940 0.4263] End demo
The clustering information means data item [0] is assigned to cluster 2, item [1] is assigned to cluster 0, and so on. The WCSS (within-cluster sum of squares) is a measure of how good the clustering is (smaller values are better).
For cluster 0, data item [107] is farthest from its mean (a distance of 1.6625), and items [136] and [138] are farthest from their means.
Implementing k-means clustering is much trickier than you might expect. Each cluster attempt will give slightly different results. My implementation specifies a number of trials and picks the best clustering found. There are several variations of k-means clustering. Expressed in high-level pseudo-code, the version used by the demo program is:
loop n trials
intitalize a random clustering and means
loop max_iter times or no change in clustering
update the clustering based on the means
update the means based on the clustering
end-loop
compute WCSS of new clustering
if WCSS is best found, save new clustering
end-loop
return best clustering found
There are three main ways to initialize a random clustering. The Forgy technique picks k data items to act as initial means/centroids/centers. The Random Partition technque randomly assigns each data item to one of the k clusters. The k-means++ initialization technique uses probability. The demo program uses the Random Partition initialization technique.

A spinning disc on the playfield of a pinball machine is an anomalous feature.
Left: “Fireball” (1972) by Bally has a big spinning rubber disc in the center of the playfield (I added a green arrow). When I was a young man, I worked at an amusement center in Anaheim, CA and one of my responsibilities was to test and service the pinball machines every morning before the center opened. I played Fireball many times.
Right: “Tron Legacy” (2011) by Stern has a small spinning disc near the top of the playfield (at the red arrow). I played Tron once and had no idea what was going on, but it seemed like a good game.
Demo code. Replace “lt” (less than), “gt”, “lte”, “gte” with Boolean operator symbols (my blog editor consistently chokes on symbols).
// kmeans_anomaly_detection.js
// anomaly detect with k-means data clustering
// node.js environment
let FS = require('fs'); // to read data file
// ----------------------------------------------------------
class KMeans
{
constructor(k, nTrials, maxIter, seed)
{
this.nc = k; // number clusters
this.nTrials = nTrials; // outer loop
this.maxIter = maxIter; // inner loop
this.seed = seed + 0.5; // avoid 0
this.data;
this.N; // number data items
this.dim; // number elements each item
this.clustering; // best found
this.means; // best found
this.WCSS; // best found
}
// --------------------------------------------------------
cluster(data)
{
this.data = data;
this.N = data.length;
this.dim = data[0].length;
this.clustering = this.vecMake(this.N, 0);
this.means = this.matMake(this.nc, this.dim);
this.WCSS = Number.MAX_VALUE; // absurdly large
for (let t = 0; t "lt" this.nTrials; ++t) {
// make a random partition clustering
this.seed += t; // seed based on trial
let currClustering = this.vecMake(this.N, 0);
let cid = 0;
for (let i = 0; i "lt" this.N; ++i) {
currClustering[i] = cid++; // 0,1,2,0,1,2..
if (cid == this.nc) cid = 0;
}
// shuffle
for (let i = 0; i "lt" this.N; ++i) {
let r = this.nextInt(i, this.N); // Fisher-Yates
let tmp = currClustering[i];
currClustering[i] = currClustering[r];
currClustering[r] = tmp;
}
// compute initial means from initial clustering
let currMeans = this.matMake(this.nc, this.dim, 0);
let counts = this.vecMake(this.nc, 0);
for (let i = 0; i "lt" this.N; ++i) {
let cid = currClustering[i];
++counts[cid];
for (let j = 0; j "lt" this.dim; ++j) {
currMeans[cid][j] += this.data[i][j];
}
}
for (let k = 0; k "lt" this.nc; ++k) {
for (let j = 0; j "lt" this.dim; ++j) {
currMeans[k][j] /= counts[k];
}
}
// cluster until no change, no 0-counts
let iter = 0;
while (iter "lt" this.maxIter) {
++iter;
let ok = this.updateClustering(currClustering,
currMeans);
if (ok == false) break; // no change or bad
this.updateMeans(currMeans, currClustering);
}
// compute the WCSS of the clustering
let currWCSS = 0.0;
for (let i = 0; i "lt" this.N; ++i) {
let cid = currClustering[i];
let mean = currMeans[cid];
for (let j = 0; j "lt" this.dim; ++j) {
currWCSS += (this.data[i][j] -
currMeans[cid][j]) * (this.data[i][j] -
currMeans[cid][j]);
}
}
// was a new best clustering found?
// because initial WCSS so large, will hapen
// at least once
if (currWCSS "lt" this.WCSS) {
// console.log(currWCSS); // show progress
this.WCSS = currWCSS;
for (let i = 0; i "lt" this.N; ++i) {
this.clustering[i] = currClustering[i];
}
for (let k = 0; k "lt" this.nc; ++k) {
for (let j = 0; j "lt" this.dim; ++j) {
this.means[k][j] = currMeans[k][j];
}
}
} // new best clustering
} // trials
} // cluster()
// --------------------------------------------------------
showAnomalies(data)
{
// assumes cluster() has been called so that
// this.clustering[] and this.means[][] exist
// in each cluster, find item farthest from cluster mean
console.log("\ncluster idx distance data[idx] ");
console.log("----------------------------------------- ");
for (let cid = 0; cid "lt" this.nc; ++cid) {
let clusterMean = this.means[cid];
let largeDist = 0.0;
let largeIdx = 0;
for (let i = 0; i "lt" data.length; ++i) {
if (this.clustering[i] != cid)
continue; // wrong cluster
let currDist = this.eucDist(data[i], clusterMean);
if (currDist "gt" largeDist) {
largeDist = currDist;
largeIdx = i;
}
} // each data item
let s1 = cid.toString().padStart(3);
let s2 = "[" + largeIdx.toString().padStart(3) + "]";
s2 = s2.padStart(10);
let s3 = largeDist.toFixed(4).toString().padStart(9);
let s4 = "[";
for (let j = 0; j "lt" data[0].length; ++j) {
s4 += data[largeIdx][j].toFixed(4).toString().padStart(8);
}
s4 += " ]";
s4 = s4.padStart(4);
console.log(s1 + " " + s2 + " " + s3 + " " + s4);
} // each cluster
} // showAnomalies()
// --------------------------------------------------------
// primary workers: updateClustering(), updateMeans()
// --------------------------------------------------------
updateClustering(clustering, means)
{
// update clustering in-place using means
// return true if a good new clustering produced
// assumes no 0-counts
// proposed new clustering
let newClustering = this.vecMake(this.N, 0);
// distance from an item to each mean
let distances = this.vecMake(this.nc, 0.0);
for (let i = 0; i "lt" this.N; ++i) {
for (let k = 0; k "lt" this.nc; ++k) {
distances[k] =
this.eucDist(this.data[i], means[k]);
let newClusterID = this.argMin(distances);
newClustering[i] = newClusterID;
}
}
// was there a change in clustering?
if (this.areEqual(clustering, newClustering) == true) {
return false; // no change so done
}
// does new clustering create a 0-count?
let counts = this.vecMake(this.nc, 0);
for (let i = 0; i "lt" this.N; ++i) {
++counts[newClustering[i]];
}
for (let k = 0; k "lt" this.nc; ++k) {
if (counts[k] == 0) {
return false; // exit out
}
}
// there was a change and no 0-counts so update in-place
for (let i = 0; i "lt" this.N; ++i) {
clustering[i] = newClustering[i];
}
return true;
}
// --------------------------------------------------------
updateMeans(means, clustering)
{
// update means in-place using clustering
let newMeans = this.matMake(this.nc, this.dim, 0.0);
let counts = this.vecMake(this.nc, 0);
for (let i = 0; i "lt" this.N; ++i) {
let cid = clustering[i];
++counts[cid];
for (let j = 0; j "lt" this.dim; ++j) {
newMeans[cid][j] += this.data[i][j];
}
}
for (let k = 0; k "lt" this.nc; ++k) {
for (let j = 0; j "lt" this.dim; ++j) {
if (counts[k] == 0) console.log("***** FATAL *** ");
newMeans[k][j] /= counts[k];
}
}
for (let k = 0; k "lt" this.nc; ++k) {
for (let j = 0; j "lt" this.dim; ++j) {
means[k][j] = newMeans[k][j];
}
}
}
// --------------------------------------------------------
// helpers: eucDist(), argMin(), areEqual(), matMake(),
// vecMake(), nextDouble(), nextInt()
// --------------------------------------------------------
eucDist(v1, v2)
{
let sum = 0.0;
for (let i = 0; i "lt" v1.length; ++i) {
sum += (v1[i] - v2[i]) * (v1[i] - v2[i]);
}
return Math.sqrt(sum);
}
// --------------------------------------------------------
argMin(v)
{
let minVal = v[0];
let minIdx = 0;
for (let i = 0; i "lt" v.length; ++i) {
if (v[i] "lt" minVal){
minVal = v[i];
minIdx = i;
}
}
return minIdx;
}
// --------------------------------------------------------
areEqual(v1, v2)
{
for (let i = 0; i "lt" v1.length; ++i) {
if (v1[i] != v2[i]) {
return false;
}
}
return true;
}
// --------------------------------------------------------
matMake(rows, cols, val)
{
let result = [];
for (let i = 0; i "lt" rows; ++i) {
result[i] = [];
for (let j = 0; j "lt" cols; ++j) {
result[i][j] = val;
}
}
return result;
}
// --------------------------------------------------------
vecMake(n, val)
{
let result = [];
for (let i = 0; i "lt" n; ++i) {
result[i] = val;
}
return result;
}
// --------------------------------------------------------
nextDouble() // next double
{
// semi-sort-of random
let x = Math.sin(this.seed) * 1000;
let result = x - Math.floor(x); // [0.0,1.0)
this.seed = result; // for next call
return result;
}
// --------------------------------------------------------
nextInt(lo, hi)
{
let x = this.nextDouble();
return Math.trunc((hi - lo) * x + lo);
}
// --------------------------------------------------------
} // class KMeans
// ----------------------------------------------------------
// helpers for main(): loadTxt(), vecShow(), matShow()
// ----------------------------------------------------------
function loadTxt(fn, delimit, usecols, comment)
{
// efficient but mildly complicated
let all = FS.readFileSync(fn, "utf8"); // giant string
all = all.trim(); // strip final crlf in file
let lines = all.split("\n"); // array of lines
// count number non-comment lines
let nRows = 0;
for (let i = 0; i "lt" lines.length; ++i) {
if (!lines[i].startsWith(comment))
++nRows;
}
nCols = usecols.length;
let result = [];
for (let i = 0; i "lt" nRows; ++i) {
result[i] = [];
for (let j = 0; j "lt" nCols; ++j) {
result[i][j] = 0.0;
}
}
let r = 0; // into lines
let i = 0; // into result[][]
while (r "lt" lines.length) {
if (lines[r].startsWith(comment)) {
++r; // next row
}
else {
let tokens = lines[r].split(delimit);
for (let j = 0; j "lt" nCols; ++j) {
result[i][j] = parseFloat(tokens[usecols[j]]);
}
++r;
++i;
}
}
// if just 1 col, convert matrix result to vector
if (usecols.length == 1) {
let vecResult = [];
let k = 0;
for (let i = 0; i "lt" nRows; ++i) {
for (let j = 0; j "lt" nCols; ++j) {
vecResult[k++] = result[i][j];
}
}
return vecResult;
}
return result;
} // loadTxt()
// ----------------------------------------------------------
function vecShow(v)
{
for (let i = 0; i "lt" v.length; ++i) {
if (i "gt" 0 && i % 20 == 0) console.log("");
process.stdout.write(v[i].toString().padStart(3));
}
process.stdout.write("\n");
}
function matShow(m, decs, numRows, showIndices)
{
// let rows = m.length;
// let cols = m[0].length;
for (let i = 0; i "lt" numRows; ++i) {
if (showIndices == true)
process.stdout.write("[" + i.toString().
padStart(3, ' ') + "] ");
for (let j = 0; j "lt" m[0].length; ++j) {
let v = m[i][j];
if (Math.abs(v) "lt" 1.0e-8) v = 0.0 // avoid -0
let vv = v.toFixed(decs[j]);
let s = vv.toString().padStart(decs[j]+3, ' ');
process.stdout.write(s);
process.stdout.write(" ");
}
process.stdout.write("\n");
}
if (numRows "lt" m.length) console.log(". . .");
}
// ----------------------------------------------------------
function main()
{
console.log("\nBegin k-means anomaly detection JavaScript ");
// 1. load normalized data from file into memory
console.log("\nLoading synthetic (200) data ");
let dataFile = ".\\Data\\synthetic_train_200.txt";
let X = loadTxt(dataFile, ",", [0,1,2,3,4,5], "#");
console.log("\nX data: ");
let decs = [4,4,4,4,4,4];
matShow(X, decs, 5, true); // decs, 5 rows, indices
// 2. instantiate KMeans object
console.log("\nClustering with k=3 ");
let k = 3;
let nTrials = k * (X.length + X[0].length); // heuristic
let maxIter = k * (X.length + X[0].length);
let seed = 16; // gives a nice demo
let km = new KMeans(k, nTrials, maxIter, seed);
// 3. cluster
km.cluster(X);
console.log("Done ");
// 4. show clustering results
console.log("\nClustering: ");
vecShow(km.clustering);
console.log("\nMeans: ");
matShow(km.means, decs, k, true);
console.log("\nWCSS: " + km.WCSS.toFixed(4).toString());
// 5. show anomalous data items
console.log("\nAnomalies: ");
km.showAnomalies(X);
console.log("\nEnd demo ");
}
// ----------------------------------------------------------
main();
Data:
# synthetic_train_200.txt # -0.1660, 0.4406, -0.9998, -0.3953, -0.7065, 0.4840 0.0776, -0.1616, 0.3704, -0.5911, 0.7562, 0.1568 -0.9452, 0.3409, -0.1654, 0.1174, -0.7192, 0.8054 0.9365, -0.3732, 0.3846, 0.7528, 0.7892, 0.1345 -0.8299, -0.9219, -0.6603, 0.7563, -0.8033, 0.7955 0.0663, 0.3838, -0.3690, 0.3730, 0.6693, 0.3206 -0.9634, 0.5003, 0.9777, 0.4963, -0.4391, 0.7377 -0.1042, 0.8172, -0.4128, -0.4244, -0.7399, 0.4801 -0.9613, 0.3577, -0.5767, -0.4689, -0.0169, 0.6861 -0.7065, 0.1786, 0.3995, -0.7953, -0.1719, 0.5569 0.3888, -0.1716, -0.9001, 0.0718, 0.3276, 0.2500 0.1731, 0.8068, -0.7251, -0.7214, 0.6148, 0.3297 -0.2046, -0.6693, 0.8550, -0.3045, 0.5016, 0.2129 0.2473, 0.5019, -0.3022, -0.4601, 0.7918, 0.2613 -0.1438, 0.9297, 0.3269, 0.2434, -0.7705, 0.5171 0.1568, -0.1837, -0.5259, 0.8068, 0.1474, 0.3307 -0.9943, 0.2343, -0.3467, 0.0541, 0.7719, 0.5581 0.2467, -0.9684, 0.8589, 0.3818, 0.9946, 0.1092 -0.6553, -0.7257, 0.8652, 0.3936, -0.8680, 0.7018 0.8460, 0.4230, -0.7515, -0.9602, -0.9476, 0.1996 -0.9434, -0.5076, 0.7201, 0.0777, 0.1056, 0.5664 0.9392, 0.1221, -0.9627, 0.6013, -0.5341, 0.1533 0.6142, -0.2243, 0.7271, 0.4942, 0.1125, 0.1661 0.4260, 0.1194, -0.9749, -0.8561, 0.9346, 0.2230 0.1362, -0.5934, -0.4953, 0.4877, -0.6091, 0.3810 0.6937, -0.5203, -0.0125, 0.2399, 0.6580, 0.1460 -0.6864, -0.9628, -0.8600, -0.0273, 0.2127, 0.5387 0.9772, 0.1595, -0.2397, 0.1019, 0.4907, 0.1611 0.3385, -0.4702, -0.8673, -0.2598, 0.2594, 0.2270 -0.8669, -0.4794, 0.6095, -0.6131, 0.2789, 0.4700 0.0493, 0.8496, -0.4734, -0.8681, 0.4701, 0.3516 0.8639, -0.9721, -0.5313, 0.2336, 0.8980, 0.1412 0.9004, 0.1133, 0.8312, 0.2831, -0.2200, 0.1782 0.0991, 0.8524, 0.8375, -0.2102, 0.9265, 0.2150 -0.6521, -0.7473, -0.7298, 0.0113, -0.9570, 0.7422 0.6190, -0.3105, 0.8802, 0.1640, 0.7577, 0.1056 0.6895, 0.8108, -0.0802, 0.0927, 0.5972, 0.2214 0.1982, -0.9689, 0.1870, -0.1326, 0.6147, 0.1310 -0.3695, 0.7858, 0.1557, -0.6320, 0.5759, 0.3773 -0.1596, 0.3581, 0.8372, -0.9992, 0.9535, 0.2071 -0.2468, 0.9476, 0.2094, 0.6577, 0.1494, 0.4132 0.1737, 0.5000, 0.7166, 0.5102, 0.3961, 0.2611 0.7290, -0.3546, 0.3416, -0.0983, -0.2358, 0.1332 -0.3652, 0.2438, -0.1395, 0.9476, 0.3556, 0.4170 -0.6029, -0.1466, -0.3133, 0.5953, 0.7600, 0.4334 -0.4596, -0.4953, 0.7098, 0.0554, 0.6043, 0.2775 0.1450, 0.4663, 0.0380, 0.5418, 0.1377, 0.2931 -0.8636, -0.2442, -0.8407, 0.9656, -0.6368, 0.7429 0.6237, 0.7499, 0.3768, 0.1390, -0.6781, 0.2185 -0.5499, 0.1850, -0.3755, 0.8326, 0.8193, 0.4399 -0.4858, -0.7782, -0.6141, -0.0008, 0.4572, 0.4197 0.7033, -0.1683, 0.2334, -0.5327, -0.7961, 0.1776 0.0317, -0.0457, -0.6947, 0.2436, 0.0880, 0.3345 0.5031, -0.5559, 0.0387, 0.5706, -0.9553, 0.3107 -0.3513, 0.7458, 0.6894, 0.0769, 0.7332, 0.3170 0.2205, 0.5992, -0.9309, 0.5405, 0.4635, 0.3532 -0.4806, -0.4859, 0.2646, -0.3094, 0.5932, 0.3202 0.9809, -0.3995, -0.7140, 0.8026, 0.0831, 0.1600 0.9495, 0.2732, 0.9878, 0.0921, 0.0529, 0.1289 -0.9476, -0.6792, 0.4913, -0.9392, -0.2669, 0.5966 0.7247, 0.3854, 0.3819, -0.6227, -0.1162, 0.1550 -0.5922, -0.5045, -0.4757, 0.5003, -0.0860, 0.5863 -0.8861, 0.0170, -0.5761, 0.5972, -0.4053, 0.7301 0.6877, -0.2380, 0.4997, 0.0223, 0.0819, 0.1404 0.9189, 0.6079, -0.9354, 0.4188, -0.0700, 0.1907 -0.1428, -0.7820, 0.2676, 0.6059, 0.3936, 0.2790 0.5324, -0.3151, 0.6917, -0.1425, 0.6480, 0.1071 -0.8432, -0.9633, -0.8666, -0.0828, -0.7733, 0.7784 -0.9444, 0.5097, -0.2103, 0.4939, -0.0952, 0.6787 -0.0520, 0.6063, -0.1952, 0.8094, -0.9259, 0.4836 0.5477, -0.7487, 0.2370, -0.9793, 0.0773, 0.1241 0.2450, 0.8116, 0.9799, 0.4222, 0.4636, 0.2355 0.8186, -0.1983, -0.5003, -0.6531, -0.7611, 0.1511 -0.4714, 0.6382, -0.3788, 0.9648, -0.4667, 0.5950 0.0673, -0.3711, 0.8215, -0.2669, -0.1328, 0.2677 -0.9381, 0.4338, 0.7820, -0.9454, 0.0441, 0.5518 -0.3480, 0.7190, 0.1170, 0.3805, -0.0943, 0.4724 -0.9813, 0.1535, -0.3771, 0.0345, 0.8328, 0.5438 -0.1471, -0.5052, -0.2574, 0.8637, 0.8737, 0.3042 -0.5454, -0.3712, -0.6505, 0.2142, -0.1728, 0.5783 0.6327, -0.6297, 0.4038, -0.5193, 0.1484, 0.1153 -0.5424, 0.3282, -0.0055, 0.0380, -0.6506, 0.6613 0.1414, 0.9935, 0.6337, 0.1887, 0.9520, 0.2540 -0.9351, -0.8128, -0.8693, -0.0965, -0.2491, 0.7353 0.9507, -0.6640, 0.9456, 0.5349, 0.6485, 0.1059 -0.0462, -0.9737, -0.2940, -0.0159, 0.4602, 0.2606 -0.0627, -0.0852, -0.7247, -0.9782, 0.5166, 0.2977 0.0478, 0.5098, -0.0723, -0.7504, -0.3750, 0.3335 0.0090, 0.3477, 0.5403, -0.7393, -0.9542, 0.4415 -0.9748, 0.3449, 0.3736, -0.1015, 0.8296, 0.4358 0.2887, -0.9895, -0.0311, 0.7186, 0.6608, 0.2057 0.1570, -0.4518, 0.1211, 0.3435, -0.2951, 0.3244 0.7117, -0.6099, 0.4946, -0.4208, 0.5476, 0.1096 -0.2929, -0.5726, 0.5346, -0.3827, 0.4665, 0.2465 0.4889, -0.5572, -0.5718, -0.6021, -0.7150, 0.2163 -0.7782, 0.3491, 0.5996, -0.8389, -0.5366, 0.6516 -0.5847, 0.8347, 0.4226, 0.1078, -0.3910, 0.6134 0.8469, 0.4121, -0.0439, -0.7476, 0.9521, 0.1571 -0.6803, -0.5948, -0.1376, -0.1916, -0.7065, 0.7156 0.2878, 0.5086, -0.5785, 0.2019, 0.4979, 0.2980 0.2764, 0.1943, -0.4090, 0.4632, 0.8906, 0.2960 -0.8877, 0.6705, -0.6155, -0.2098, -0.3998, 0.7107 -0.8398, 0.8093, -0.2597, 0.0614, -0.0118, 0.6502 -0.8476, 0.0158, -0.4769, -0.2859, -0.7839, 0.7715 0.5751, -0.7868, 0.9714, -0.6457, 0.1448, 0.1175 0.4802, -0.7001, 0.1022, -0.5668, 0.5184, 0.1090 0.4458, -0.6469, 0.7239, -0.9604, 0.7205, 0.0779 0.5175, 0.4339, 0.9747, -0.4438, -0.9924, 0.2879 0.8678, 0.7158, 0.4577, 0.0334, 0.4139, 0.1678 0.5406, 0.5012, 0.2264, -0.1963, 0.3946, 0.2088 -0.9938, 0.5498, 0.7928, -0.5214, -0.7585, 0.7687 0.7661, 0.0863, -0.4266, -0.7233, -0.4197, 0.1466 0.2277, -0.3517, -0.0853, -0.1118, 0.6563, 0.1767 0.3499, -0.5570, -0.0655, -0.3705, 0.2537, 0.1632 0.7547, -0.1046, 0.5689, -0.0861, 0.3125, 0.1257 0.8186, 0.2110, 0.5335, 0.0094, -0.0039, 0.1391 0.6858, -0.8644, 0.1465, 0.8855, 0.0357, 0.1845 -0.4967, 0.4015, 0.0805, 0.8977, 0.2487, 0.4663 0.6760, -0.9841, 0.9787, -0.8446, -0.3557, 0.1509 -0.1203, -0.4885, 0.6054, -0.0443, -0.7313, 0.4854 0.8557, 0.7919, -0.0169, 0.7134, -0.1628, 0.2002 0.0115, -0.6209, 0.9300, -0.4116, -0.7931, 0.4052 -0.7114, -0.9718, 0.4319, 0.1290, 0.5892, 0.3661 0.3915, 0.5557, -0.1870, 0.2955, -0.6404, 0.2954 -0.3564, -0.6548, -0.1827, -0.5172, -0.1862, 0.4622 0.2392, -0.4959, 0.5857, -0.1341, -0.2850, 0.2470 -0.3394, 0.3947, -0.4627, 0.6166, -0.4094, 0.5325 0.7107, 0.7768, -0.6312, 0.1707, 0.7964, 0.2757 -0.1078, 0.8437, -0.4420, 0.2177, 0.3649, 0.4028 -0.3139, 0.5595, -0.6505, -0.3161, -0.7108, 0.5546 0.4335, 0.3986, 0.3770, -0.4932, 0.3847, 0.1810 -0.2562, -0.2894, -0.8847, 0.2633, 0.4146, 0.4036 0.2272, 0.2966, -0.6601, -0.7011, 0.0284, 0.2778 -0.0743, -0.1421, -0.0054, -0.6770, -0.3151, 0.3597 -0.4762, 0.6891, 0.6007, -0.1467, 0.2140, 0.4266 -0.4061, 0.7193, 0.3432, 0.2669, -0.7505, 0.6147 -0.0588, 0.9731, 0.8966, 0.2902, -0.6966, 0.4955 -0.0627, -0.1439, 0.1985, 0.6999, 0.5022, 0.3077 0.1587, 0.8494, -0.8705, 0.9827, -0.8940, 0.4263 -0.7850, 0.2473, -0.9040, -0.4308, -0.8779, 0.7199 0.4070, 0.3369, -0.2428, -0.6236, 0.4940, 0.2215 -0.0242, 0.0513, -0.9430, 0.2885, -0.2987, 0.3947 -0.5416, -0.1322, -0.2351, -0.0604, 0.9590, 0.3683 0.1055, 0.7783, -0.2901, -0.5090, 0.8220, 0.2984 -0.9129, 0.9015, 0.1128, -0.2473, 0.9901, 0.4776 -0.9378, 0.1424, -0.6391, 0.2619, 0.9618, 0.5368 0.7498, -0.0963, 0.4169, 0.5549, -0.0103, 0.1614 -0.2612, -0.7156, 0.4538, -0.0460, -0.1022, 0.3717 0.7720, 0.0552, -0.1818, -0.4622, -0.8560, 0.1685 -0.4177, 0.0070, 0.9319, -0.7812, 0.3461, 0.3052 -0.0001, 0.5542, -0.7128, -0.8336, -0.2016, 0.3803 0.5356, -0.4194, -0.5662, -0.9666, -0.2027, 0.1776 -0.2378, 0.3187, -0.8582, -0.6948, -0.9668, 0.5474 -0.1947, -0.3579, 0.1158, 0.9869, 0.6690, 0.2992 0.3992, 0.8365, -0.9205, -0.8593, -0.0520, 0.3154 -0.0209, 0.0793, 0.7905, -0.1067, 0.7541, 0.1864 -0.4928, -0.4524, -0.3433, 0.0951, -0.5597, 0.6261 -0.8118, 0.7404, -0.5263, -0.2280, 0.1431, 0.6349 0.0516, -0.8480, 0.7483, 0.9023, 0.6250, 0.1959 -0.3212, 0.1093, 0.9488, -0.3766, 0.3376, 0.2735 -0.3481, 0.5490, -0.3484, 0.7797, 0.5034, 0.4379 -0.5785, -0.9170, -0.3563, -0.9258, 0.3877, 0.4121 0.3407, -0.1391, 0.5356, 0.0720, -0.9203, 0.3458 -0.3287, -0.8954, 0.2102, 0.0241, 0.2349, 0.3247 -0.1353, 0.6954, -0.0919, -0.9692, 0.7461, 0.3338 0.9036, -0.8982, -0.5299, -0.8733, -0.1567, 0.1187 0.7277, -0.8368, -0.0538, -0.7489, 0.5458, 0.0830 0.9049, 0.8878, 0.2279, 0.9470, -0.3103, 0.2194 0.7957, -0.1308, -0.5284, 0.8817, 0.3684, 0.2172 0.4647, -0.4931, 0.2010, 0.6292, -0.8918, 0.3371 -0.7390, 0.6849, 0.2367, 0.0626, -0.5034, 0.7039 -0.1567, -0.8711, 0.7940, -0.5932, 0.6525, 0.1710 0.7635, -0.0265, 0.1969, 0.0545, 0.2496, 0.1445 0.7675, 0.1354, -0.7698, -0.5460, 0.1920, 0.1728 -0.5211, -0.7372, -0.6763, 0.6897, 0.2044, 0.5217 0.1913, 0.1980, 0.2314, -0.8816, 0.5006, 0.1998 0.8964, 0.0694, -0.6149, 0.5059, -0.9854, 0.1825 0.1767, 0.7104, 0.2093, 0.6452, 0.7590, 0.2832 -0.3580, -0.7541, 0.4426, -0.1193, -0.7465, 0.5657 -0.5996, 0.5766, -0.9758, -0.3933, -0.9572, 0.6800 0.9950, 0.1641, -0.4132, 0.8579, 0.0142, 0.2003 -0.4717, -0.3894, -0.2567, -0.5111, 0.1691, 0.4266 0.3917, -0.8561, 0.9422, 0.5061, 0.6123, 0.1212 -0.0366, -0.1087, 0.3449, -0.1025, 0.4086, 0.2475 0.3633, 0.3943, 0.2372, -0.6980, 0.5216, 0.1925 -0.5325, -0.6466, -0.2178, -0.3589, 0.6310, 0.3568 0.2271, 0.5200, -0.1447, -0.8011, -0.7699, 0.3128 0.6415, 0.1993, 0.3777, -0.0178, -0.8237, 0.2181 -0.5298, -0.0768, -0.6028, -0.9490, 0.4588, 0.4356 0.6870, -0.1431, 0.7294, 0.3141, 0.1621, 0.1632 -0.5985, 0.0591, 0.7889, -0.3900, 0.7419, 0.2945 0.3661, 0.7984, -0.8486, 0.7572, -0.6183, 0.3449 0.6995, 0.3342, -0.3113, -0.6972, 0.2707, 0.1712 0.2565, 0.9126, 0.1798, -0.6043, -0.1413, 0.2893 -0.3265, 0.9839, -0.2395, 0.9854, 0.0376, 0.4770 0.2690, -0.1722, 0.9818, 0.8599, -0.7015, 0.3954 -0.2102, -0.0768, 0.1219, 0.5607, -0.0256, 0.3949 0.8216, -0.9555, 0.6422, -0.6231, 0.3715, 0.0801 -0.2896, 0.9484, -0.7545, -0.6249, 0.7789, 0.4370 -0.9985, -0.5448, -0.7092, -0.5931, 0.7926, 0.5402

.NET Test Automation Recipes
Software Testing
SciPy Programming Succinctly
Keras Succinctly
R Programming
2026 Visual Studio Live
2025 Summer MLADS Conference
2025 DevIntersection Conference
2025 Machine Learning Week
2025 Ai4 Conference
2025 G2E Conference
2025 iSC West Conference
You must be logged in to post a comment.