<jupyter_start><jupyter_text>Clustering Crypto<jupyter_code># Initial imports
import requests
import pandas as pd
import matplotlib.pyplot as plt
import hvplot.pandas
import plotly.express as px
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
import plotly.express as px
from pathlib import Path
import altair as alt
from IPython.display import display
!pip install -U altair
# Use the following endpoint to fetch json data
url = "https://min-api.cryptocompare.com/data/all/coinlist"
# Create a DataFrame 
# HINT: You will need to use the 'Data' key from the json response, then transpose the DataFrame.
file_path = Path("crypto_data.csv")
crypto_df = pd.read_csv(file_path)
print(crypto_df.shape)
crypto_df.describe()
crypto_df.head()<jupyter_output><empty_output><jupyter_text>Data Preprocessing<jupyter_code># Keep only necessary columns:
# 'CoinName','Algorithm','IsTrading','ProofType','TotalCoinsMined','TotalCoinSupply'
crypto_df['IsTrading'] = crypto_df['IsTrading'].astype(str)

bool_list = ['True']

crypto_df = crypto_df[crypto_df.IsTrading.isin(bool_list)]

crypto_df.info()
crypto_df.rename(columns = {'Unnamed: 0':'Ticker'}, inplace = True)
for col in crypto_df.columns:
    print(col)
crypto_df.set_index("Ticker", inplace=True)
crypto_df.head()
# Keep only cryptocurrencies that are trading
non_trading = crypto_df[crypto_df["IsTrading"] == False].index
crypto_df.drop(non_trading , inplace=True)

crypto_df['TotalCoinsMined'].sum()
# Keep only cryptocurrencies with a working algorithm
crypto_df= crypto_df[crypto_df['Algorithm']!= 'N/A']
# Remove the "IsTrading" column
#df.drop(columns=['IsTrading'],inplace=True)

# crypto_df.iloc[:,:].isnull().sum()

# df.replace('0',' ')

# df.TotalCoinsMined.dropna()
crypto_df.drop(columns=['IsTrading'], inplace=True)
crypto_df.head()
crypto_df.info()
# Remove rows with at least 1 null value
crypto_df = crypto_df.dropna()
# Remove rows with cryptocurrencies having no coins mined
rypto_df= crypto_df[crypto_df["TotalCoinsMined"]>0]
# Drop rows where there are 'N/A' text values
crypto_df= crypto_df[crypto_df!='N/A']
# Store the 'CoinName'column in its own DataFrame prior to dropping it from crypto_df
coins_name = pd.DataFrame(crypto_df['CoinName'])

coins_name
# y = coins_name['CoinName']

# y.head()
y = coins_name['CoinName']
y.head()
# Drop the 'CoinName' column since it's not going to be used on the clustering algorithm
from sklearn.preprocessing import OneHotEncoder, StandardScaler
crypto_df.drop(columns='CoinName', inplace=True)
# Create dummy variables for text features
crypto_dummies= pd.get_dummies(crypto_df, columns=['Algorithm', 'ProofType'])
crypto_dummies.head()
# Standardize data
crypto_scaled= StandardScaler().fit_transform(crypto_dummies)
crypto_scaled<jupyter_output><empty_output><jupyter_text>Reducing Dimensions Using PCA<jupyter_code># Use PCA to reduce dimensions to 3 principal components
pca = PCA(n_components=3)
crypto_pca = pca.fit_transform(crypto_scaled)
# Create a DataFrame with the principal components data
pca_df = pd.DataFrame(
         data=crypto_pca, columns=["PC 1", "PC 2", "PC 3"]
)
pca_df.head()<jupyter_output><empty_output><jupyter_text>Clustering Crytocurrencies Using K-MeansFind the Best Value for k Using the Elbow Curve<jupyter_code>inertia = []
k = list(range(1, 11))

# Calculate the inertia for the range ok k values
for i in k:
    km = KMeans(n_clusters=i, random_state=0)
    km.fit(pca_df)
    inertia.append(km.inertia_)

# Create the Elbow Curve using hvPlot
elbow_data = {"k": k, "inertia": inertia}
df_elbow = pd.DataFrame(elbow_data)
df_elbow.hvplot.line(x="k", y="inertia", xticks=k, title="Elbow Curve")
km = KMeans(n_clusters=4, random_state=0)
# Fit the model
km.fit(pca_df)
# Predict clusters
predictions = km.predict(pca_df)
# Creating a new DataFrame including predicted clusters and cryptocurrencies features
pca_df['class'] = km.labels_
pca_df.index = crypto_df.index
crypto_df.head()
clustered_df = pd.concat([crypto_df, pca_df,coins_name], axis=1, )
clustered_df.head()<jupyter_output><empty_output><jupyter_text>Visualizing Results3D-Scatter with Clusters<jupyter_code># Create a 3D-Scatter with the PCA data and the clusters
fig = px.scatter_3d(clustered_df, x="PC 1", y="PC 2", z="PC 3", color="class", hover_name="CoinName", hover_data=["Algorithm"])
fig.show()<jupyter_output><empty_output><jupyter_text>Table of Tradable Cryptocurrencies<jupyter_code># Table with tradable cryptos
clustered_df.hvplot.table(columns=['CoinName', "Algorithm", "ProofType", "TotalCoinSupply", "TotalCoinsMined", "class"])
# Print the total number of tradable cryptocurrencies
total_trade_coins = len(clustered_df.CoinName)
print(f"The total number of tradable cryptocurrencies are {total_trade_coins}.")<jupyter_output>The total number of tradable cryptocurrencies are 685.<jupyter_text>Scatter Plot with Tradable Cryptocurrencies<jupyter_code># Scale data to create the scatter plot
scaler = MinMaxScaler()

clustered_columns = ["TotalCoinsMined", "TotalCoinSupply"]
x = clustered_df[clustered_columns].values
x_scaled = scaler.fit_transform(x)
# Create a dataframe with scaled data
tradable_coins_df = pd.DataFrame(
    data=x_scaled, columns=clustered_columns
)
tradable_coins_df.head()
# Drop the existing columns `TotalCoinsMined` and `TotalCoinSupply` from the `clustered_df` dataframe to avoid duplicates.
clustered_df.drop(columns=clustered_columns, inplace=True)
clustered_df.head()
# Concate the two dataframes `clustered_df` and `tradable_coins_df`
clustered_tradable_df = pd.concat([clustered_df, tradable_coins_df], axis='columns', join='inner')
clustered_tradable_df.head()
# Plot the scatter with x="TotalCoinsMined" and y="TotalCoinSupply"
fig2 = alt.Chart(clustered_tradable_df).mark_circle(
    size=100
).encode(
    alt.X("TotalCoinsMined", title="TotalCoinsMined", scale=alt.Scale(zero=False)),
    alt.Y("TotalCoinSupply", title="TotalCoinSupply", scale=alt.Scale(zero=False)),
    color="CoinName",
    tooltip=["CoinName", "TotalCoinsMined", "TotalCoinSupply"]
).properties(
    height=300,
    width=500,
    title="TotalCoinsMined versus TotalCoinSupply").interactive()
fig2<jupyter_output>C:\Users\gregg\Anaconda3\envs\pyvizenv\lib\site-packages\altair\utils\core.py:221: UserWarning:

I don't know how to infer vegalite type from 'empty'.  Defaulting to nominal.
{'fraction_non_alphanumeric': 0.11431656896019747, 'fraction_numerical': 0.006170934896636841, 'mean_word_length': 7.164987405541562, 'pattern_counts': {'":': 2, '<': 27, '<?xml version=': 0, '>': 28, 'https://': 1, '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': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '628160', 'license': 'Unlicense', 'n_tokens_mistral': 2333, 'n_tokens_neox': 2245, 'n_words': 529, 'path': 'ClusteringCrypto/.ipynb_checkpoints/crypto_clustering_sm-checkpoint.ipynb', 'repo_name': 'gsaldutti/unit13-challenge', 'size': '6482'}