<jupyter_start><jupyter_text>Steps   1) Select variables you want to cluster: df = df[["col1", "col2"]]      2) Convert to array & dtype float: np_array = df.values.astype("float32", copy = False)      3) Scale to standard normal:   - stscaler = StandardScaler().fit(np_array) np_array = stscaler.transform(np_array)          4) Create DBSCAN object and fit: dbsc = DBSCAN(eps = .75, min_samples = 15).fit(np_array)      5) Extract labels: labels = dbsc.labels_      6) Add labels back to original dataframe:   - df['labels'] = labels           7) Explore:   - df.labels.value_counts() sns.scatterplot(df.col1, df.col2, hue=df.labels)<jupyter_code># from __future__ import division
import itertools
import warnings
warnings.filterwarnings("ignore")
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
import pandas as pd
import math
from sklearn import metrics
from random import randint
from matplotlib import style
import seaborn as sns
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import MinMaxScaler

%matplotlib inline
from env import host, user, password

def get_db_url(database, host=host, user=user, password=password):
    return f'mysql+pymysql://{user}:{password}@{host}/{database}'
url = get_db_url("grocery_db")

sql = """
select *
from grocery_customers
"""

df = pd.read_sql(sql, url, index_col="customer_id")
# df.drop(["Channel", "Region"], axis = 1, inplace = True)
df = df[["Grocery", "Milk","Fresh"]]
np_array = df.values.astype("float32", copy = False)
np_array[0:10]
# make the thing
scaler = MinMaxScaler().fit(np_array)

# fit the thing
np_array = scaler.transform(np_array)

# use the thing
np_array[0:10]
dbsc = DBSCAN(eps = .10, min_samples = 20).fit(np_array)
# Now, let's add the scaled value columns back onto the dataframe
columns = list(df.columns)
scaled_columns = ["Scaled_" + column for column in columns]

# Save a copy of the original dataframe
original_df = df.copy()

# Create a dataframe containing the scaled values
scaled_df = pd.DataFrame(np_array, columns=scaled_columns)

# Merge the scaled and non-scaled values into one dataframe
df = df.merge(scaled_df, on=df.index)
df = df.drop(columns=['key_0'])
labels = dbsc.labels_
labels[0:10]
df['labels'] = labels
df.labels.value_counts()
# 31 outliers, Only one cluster of 409
df[df.labels==-1].head()
# Let's look at the descriptive stats for the entire population, the inliers, then the outliers/anomalies
print("Population")
print(df.describe())
print("-------------")
print("Inliers")
print(df[df.labels==0].describe())
print("-------------")
print("Outliers")
print(df[df.labels==-1].describe())
sns.scatterplot(df.Grocery, df.Fresh, hue=df.labels)
plt.show()

sns.scatterplot(df.Milk, df.Fresh, hue=df.labels)
plt.show()
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(1, figsize=(8, 8))
ax = Axes3D(fig, rect=[0, 0, .95, 1], elev=48, azim=134)

# plot the points
ax.scatter(df.Fresh, df.Milk, df.Grocery,
           c=df.labels, edgecolor='k')

ax.w_xaxis.set_ticklabels([])
ax.w_yaxis.set_ticklabels([])
ax.w_zaxis.set_ticklabels([])

ax.set_xlabel('Fresh')
ax.set_ylabel('Milk')
ax.set_zlabel('Grocery')<jupyter_output><empty_output><jupyter_text>sklearn.model_selection.GridSearchCV- Use this to idnetify best perameters for model outcomes.<jupyter_code>df.head()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1406855439642325, 'fraction_numerical': 0.017287630402384502, 'mean_word_length': 5.157798165137614, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '582333', 'license': 'MIT', 'n_tokens_mistral': 1232, 'n_tokens_neox': 1177, 'n_words': 307, 'path': 'DBSCAN_lesson.ipynb', 'repo_name': 'ljackson707/anomaly-detection-exercises', 'size': '3355'}