# K-Means Algorithm - Feature Selection

Suppose I've this dataset:

Employee_ID  Store_ID  Company_ID  Stock_ID  Product_Value
1            1          1          2           3.7
4            1          4          2            8
...


Where:

Employee_ID: Is the unique number for a employee that sold the product
Store_ID: Unique number for Store Chain
Company_ID: Unique number for product supplier
Stock_ID: Unique number for the product purchased
Product_Value: Product Value


And I want to make a segmentation over my dataset using K-Means... Its make sense use all the variables for my dataset?

## 2 Answers

So long as you want to use those variables to define closeness then yes, you just have to encode them differently. You should use a one-hot-encoding for the discrete variables (e.g., Employee_ID, Store_ID, etc.) and just the Product_Value as is. I answered a similar question about K-means for just categorical variables (like Employee_ID) so I've copied the code below that gives a quick demo for using the Clusters as a feature for predicting something after you use K-means. As I said in my old answer, in general, this framework isn't optimal but it's okay for a simulation.

library(glmnet)
library(Matrix)
n <- 1e5
nclusters <- 5
set.seed(420)
ls <- data.frame(sample(letters, n, replace=TRUE))
xs <- sparse.model.matrix(~.,data=ls)
print(head(xs))
# Now let's run k-means
out <- kmeans(xs, centers=nclusters)
bs <- rep(1, dim(xs))
# Let's run k-means on the different categories
clusterpred <- data.frame(out[])
ys <- xs %*% bs + rnorm(n)
print(table(clusterpred))
# Now let's use a clustered data set to predict some outcome
cxs <- sparse.model.matrix(~.,data=clusterpred)
model <- glmnet(y=ys, x=xs, alpha=0)
cmodel <- glmnet(y=ys, x=cxs, alpha=0)

# Predictions
yhat <- predict(model, xs)
yhatc <- predict(cmodel, cxs)
# Looking at the difference RMSEs
print(sqrt( sum( (ys-yhat)**2 )))
print(sqrt( sum( (ys-yhatc)**2 )))


## Never apply k-means to id columns

Even when they are numerical: the mean does not make sense.

Instead, you need to aggregate and pivot your data appropriately. One row per entity that you want to cluster (e.g. stores, or employees?). Multiple value columns. No id except the row number.

Don't forget to normalize / preprocess your data. E.g. one store may have a much better location. If you cluster your employees, expect to find a cluster that is simply a store. (Which is a correct, albeit useless, clustering).