<jupyter_start><jupyter_text>A partir del trabajo de https://github.com/PacktPublishing/Hands-On-Data-Science-for-Marketing Segmentación de Clientes basada en datos o en evidencia.la segmentación de la base de clientes puede ayudar a los especialistas en marketing a comprender mejor a sus clientes y desarrollar estrategias de marketing más eficientes.En marketing, a menudo tratamos de comprender el comportamiento de ciertos subgrupos de la base de clientes. Especialmente en el marketing dirigido, los especialistas en marketing intentan segmentar la base de clientes de determinadas formas y centrarse en cada segmento o grupo de clientes objetivo. Esta concentración en ciertos segmentos de clientes objetivo da como resultado un mejor desempeño, ya que las necesidades e intereses de esos clientes en el grupo objetivo se alinean y coinciden mejor con los productos, servicios o contenido de la empresa.La importancia y los beneficios de tener una buena comprensión de los diferentes segmentos de la base de clientes y cómo utilizar los resultados del análisis de segmentos de clientes para diferentes estrategias de marketing. Además de una forma más tradicional de segmentar la base de clientes, que implica observar las estadísticas clave de ciertos atributos de los clientes y cortar manualmente la base de clientes en segmentos, también podemos utilizar el aprendizaje automático para que las máquinas encuentren las mejores formas de dividir al cliente. base en el número deseado de segmentos. En este capítulo, aprenderemos cómo podemos usar el algoritmo de agrupamiento en clústeres de k-medias para construir segmentos de clientes basados ​​en los datos históricos.* Segmentación de clientes* Algoritmos de agrupamiento* Segmentar clientes con PythonEste es un método de aprendizaje no supervisado que aprende los puntos en común entre los grupos a partir de los datos. A diferencia del aprendizaje supervisado, donde hay un objetivo y una variable etiquetada que le gustaría predecir, el aprendizaje no supervisado aprende de los datos sin ningún objetivo o variable etiquetada. Entre muchos otros algoritmos de agrupamiento, vamos a explorar el uso del algoritmo de agrupamiento de k-mean.Para agrupar registros similares, el algoritmo de agrupamiento de k-medias intenta encontrar los centroides, que son los centros o medios de los grupos , para minimizar las distancias entre los puntos de datos y los centroides dentro de los grupos.Una desventaja o dificultad de usar la agrupación en clústeres de k-medias para la segmentación de clientes es el hecho de que necesita conocer la cantidad de clústeres de antemano. Sin embargo, con bastante frecuencia, no sabe cuál es el número óptimo de clústeres para crear. El coeficiente de silueta se puede utilizar para evaluar y ayudarlo a tomar decisiones sobre cuál será el mejor número de clústeres para su problema de segmentación. En pocas palabras, el coeficiente de silueta mide qué tan cerca están los puntos de datos de sus grupos en comparación con otros grupos .<jupyter_code>%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np<jupyter_output><empty_output><jupyter_text>UTILIZAR ESTA PARTE SI ESTAS EN GOOGLE COLAB<jupyter_code>import sys
assert sys.version_info >= (3, 5)
import os
RETAIL_PATH = "https://github.com/hcgalvan/UNSAM-Machine-Learning-on-Economics/raw/main/data/"
if 'google.colab' in sys.modules:
  def load_datasets_h1(datasets_path=RETAIL_PATH):
    #retail_ol_h1 = pd.read_csv('./data/Year 2009-2010_train.csv',  encoding= 'unicode_escape')
    # retail_ol_h2 = pd.read_csv('./data/Year 2010-2011_train.csv',  encoding= 'unicode_escape')
    csv_path = os.path.join(datasets_path, "Year 2009-2010_train.csv")
    return pd.read_csv(csv_path, encoding= 'unicode_escape')

  # The function loads the data as a Pandas DataFrame instance.
  retail_ol_h1 = load_datasets_h1()
  def load_datasets_h2(datasets_path=RETAIL_PATH):
      #xlsx_path = os.path.join(datasets_path, "online_retail_II.xlsx")
      #return pd.read_excel(xlsx_path,1)
      csv_path = os.path.join(datasets_path, "Year 2010-2011_train.csv")
      return pd.read_csv(csv_path, encoding= 'unicode_escape')

  # The function loads the data as a Pandas DataFrame instance.
  retail_ol_h2 = load_datasets_h2()<jupyter_output><empty_output><jupyter_text>1. Load Data UTILIZAR ESTE PARTE DEL CODIGO SOLO SI DESCARGASTE EN PC<jupyter_code># Loading online retailer data
# onlineRetailer_df = pd.read_csv('online_retail_II.csv', encoding= 'ISO-8859-1')
#retail_ol_h1= pd.read_excel(io='./data/online_retail_II.xlsx', sheet_name='Year 2010-2011')
#retail_ol_h2= pd.read_excel(io='./data/online_retail_II.xlsx', sheet_name='Year 2009-2010')
retail_ol_h1 = pd.read_csv('./data/Year 2009-2010_train.csv',  encoding= 'unicode_escape')
retail_ol_h2 = pd.read_csv('./data/Year 2010-2011_train.csv',  encoding= 'unicode_escape')<jupyter_output><empty_output><jupyter_text>LO QUE SIGUE ES PARTE COMUN.Para trabajar en googlecolab como para los que hemos descargado en PC.<jupyter_code>frames = [retail_ol_h1, retail_ol_h2]
results = pd.concat(frames)
df = results.copy()
df.shape
df.head()<jupyter_output><empty_output><jupyter_text>2. Data Clean-Up 1. Eliminación de pedidos cancelados.2. Eliminando registros sin Customer ID.3. Excluimos meses incompletos.4. Calcular las ventas totales de las columnas Cantidad y Precio unitario.5. Datos por cliente : para analizar segmentos de clientes, necesitamos transformar nuestros datos, de modo que cada registro represente el historial de compras de clientes individuales.  - Cantidades Negativas Manejo de cantidad negativa : Existen transacciones con Quantityvalor negativo , que representan pedidos cancelados. Vamos a ignorar esos pedidos cancelados para este ejercicio, por lo que tendremos que excluirlos de nuestro pandas DataFrame. El código para excluir estos valores negativos en la Quantity columna tiene el siguiente aspecto:<jupyter_code>df.loc[df['Quantity'] <= 0].shape
df.shape
df = df.loc[df['Quantity'] > 0]
df.shape<jupyter_output><empty_output><jupyter_text>- Registros sin Customer ID Dejar caer  NaN  registros :  Tenemos que dejar sin registros CustomerID. Dado que vamos a crear un modelo de aprendizaje automático para predecir el valor del cliente de 3 meses, necesitamos agrupar los datos por CustomerID<jupyter_code>pd.isnull(df['Customer ID']).sum()
df.shape
df = df[pd.notnull(df['Customer ID'])]
df.shape
df.head()<jupyter_output><empty_output><jupyter_text>- Excluyendo meses incompletos<jupyter_code>print('Date Range: %s ~ %s' % (df['InvoiceDate'].min(), df['InvoiceDate'].max()))
df.loc[df['InvoiceDate'] >= '2011-12-01'].shape
df.shape
df = df.loc[df['InvoiceDate'] < '2011-12-01']
df.shape<jupyter_output><empty_output><jupyter_text>- Total de ventas<jupyter_code>df.head
df['Sales'] = df['Quantity'] * df['Price']
df.head()<jupyter_output><empty_output><jupyter_text>- Datos por cliente<jupyter_code>customer_df = df.groupby('Customer ID').agg({
    'Sales': sum,
    'Invoice': lambda x: x.nunique()
})

customer_df.columns = ['TotalSales', 'OrderCount']
customer_df['AvgOrderValue'] = customer_df['TotalSales']/customer_df['OrderCount']
customer_df.head(15)
customer_df.describe()
rank_df = customer_df.rank(method='first')
rank_df.head(15)
rank_df.describe()
normalized_df = (rank_df - rank_df.mean()) / rank_df.std()
normalized_df.head(15)
normalized_df.describe()<jupyter_output><empty_output><jupyter_text>3. Segmentación de Clientes via K-Means Clustering<jupyter_code>from sklearn.cluster import KMeans<jupyter_output><empty_output><jupyter_text>- K-Means Clustering<jupyter_code>kmeans = KMeans(n_clusters=4).fit(normalized_df[['TotalSales', 'OrderCount', 'AvgOrderValue']])
kmeans
kmeans.labels_<jupyter_output><empty_output><jupyter_text>Lo primero que veremos son los centros de cada grupo. Puede obtener los centros de clústeres utilizando el siguiente código:<jupyter_code>kmeans.cluster_centers_<jupyter_output><empty_output><jupyter_text>El tercer  grupo tiene los números más bajos para los tres atributos. Esto sugiere que el tercer  grupo contiene clientes con la menor cantidad de ventas, menor número de pedidos y menor valor promedio por pedido. Este grupo de clientes es uno de los clientes de bajo valor. Por otro lado, el primer  grupo tiene los números más altos para los tres atributos. Los clientes del primer  grupo tienen la mayor cantidad de ventas, la mayor cantidad de pedidos y el valor promedio por pedido más alto. Entonces, estos clientes en el primer  grupo compra artículos caros y proporcione a la empresa los mayores ingresos. Por lo general, querrá centrar sus esfuerzos de marketing en este segmento de clientes, ya que dará como resultado el mayor rendimiento.Los clientes del segundo  grupo son interesantes. Realizan compras con relativa frecuencia, ya que tienen un valor de centro de grupo de medio a alto , pero su valor promedio por pedido es bajo, ya que el centro de grupo de es bajo. Estos son los clientes que realizan compras frecuentes de artículos de bajo valor. Por lo tanto, sería perfecto comercializar artículos con precios bajos por artículo para este segmento de clientes. Los clientes del primer  grupo también son interesantes. Sus contribuciones a los ingresos y al número de pedidos son de medianas a bajas, observando los centros de este clúster. OrderCount AvgOrderValue. Sin embargo, su valor promedio por pedido es alto. Estos son los clientes que compran artículos caros con poca frecuencia. Por lo tanto, sería perfecto comercializar artículos costosos para este segmento de clientes.Como puede ver en este ejemplo, observar los centros de los clústeres nos ayuda a comprender los diferentes tipos y segmentos de clientes y cómo orientarlos de manera diferente. Por último, también podemos conocer cuáles son los artículos más vendidos para cada segmento de clientes. Como se puede ver en el código, estamos ajustando un modelo k-means clustering con 4 racimos, basado en tres atributos:  TotalSales, OrderCount, y AvgOrderValue. A continuación, almacenamos la información de la etiqueta de clúster en una trama de datos, four_cluster_df.<jupyter_code>four_cluster_df = normalized_df[['TotalSales', 'OrderCount', 'AvgOrderValue']].copy(deep=True)
four_cluster_df['Cluster'] = kmeans.labels_
four_cluster_df.head()
four_cluster_df.groupby('Cluster').count()['TotalSales']
plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 0]['OrderCount'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 0]['TotalSales'],
    c='blue'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 1]['OrderCount'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 1]['TotalSales'],
    c='red'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 2]['OrderCount'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 2]['TotalSales'],
    c='orange'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 3]['OrderCount'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 3]['TotalSales'],
    c='green'
)

plt.title('TotalSales vs. OrderCount Clusters')
plt.xlabel('Order Count')
plt.ylabel('Total Sales')

plt.grid()
plt.show()


plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 0]['OrderCount'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 0]['AvgOrderValue'],
    c='blue'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 1]['OrderCount'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 1]['AvgOrderValue'],
    c='red'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 2]['OrderCount'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 2]['AvgOrderValue'],
    c='orange'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 3]['OrderCount'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 3]['AvgOrderValue'],
    c='green'
)

plt.title('AvgOrderValue vs. OrderCount Clusters')
plt.xlabel('Order Count')
plt.ylabel('Avg Order Value')

plt.grid()
plt.show()


plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 0]['TotalSales'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 0]['AvgOrderValue'],
    c='blue'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 1]['TotalSales'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 1]['AvgOrderValue'],
    c='red'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 2]['TotalSales'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 2]['AvgOrderValue'],
    c='orange'
)

plt.scatter(
    four_cluster_df.loc[four_cluster_df['Cluster'] == 3]['TotalSales'], 
    four_cluster_df.loc[four_cluster_df['Cluster'] == 3]['AvgOrderValue'],
    c='green'
)

plt.title('AvgOrderValue vs. TotalSales Clusters')
plt.xlabel('Total Sales')
plt.ylabel('Avg Order Value')

plt.grid()
plt.show()<jupyter_output><empty_output><jupyter_text>- Selecting the best number of clusters<jupyter_code>from sklearn.metrics import silhouette_score
for n_cluster in [4,5,6,7,8]:
    kmeans = KMeans(n_clusters=n_cluster).fit(
        normalized_df[['TotalSales', 'OrderCount', 'AvgOrderValue']]
    )
    silhouette_avg = silhouette_score(
        normalized_df[['TotalSales', 'OrderCount', 'AvgOrderValue']], 
        kmeans.labels_
    )
    
    print('Silhouette Score for %i Clusters: %0.4f' % (n_cluster, silhouette_avg))<jupyter_output>Silhouette Score for 4 Clusters: 0.4176
Silhouette Score for 5 Clusters: 0.3811
Silhouette Score for 6 Clusters: 0.3876
Silhouette Score for 7 Clusters: 0.3706
Silhouette Score for 8 Clusters: 0.3778<jupyter_text>- Interpreting Customer Segments<jupyter_code>kmeans = KMeans(n_clusters=4).fit(
    normalized_df[['TotalSales', 'OrderCount', 'AvgOrderValue']]
)
four_cluster_df = normalized_df[['TotalSales', 'OrderCount', 'AvgOrderValue']].copy(deep=True)
four_cluster_df['Cluster'] = kmeans.labels_
four_cluster_df.head(15)
kmeans.cluster_centers_
high_value_cluster = four_cluster_df.loc[four_cluster_df['Cluster'] == 3]
high_value_cluster.head()
customer_df.loc[high_value_cluster.index].describe()
pd.DataFrame(
    df.loc[
        df['Customer ID'].isin(high_value_cluster.index)
    ].groupby('Description').count()[
        'StockCode'
    ].sort_values(ascending=False).head()
)
pd.DataFrame(
    df.loc[
        df['Customer ID'].isin(
            four_cluster_df.loc[four_cluster_df['Cluster'] == 3].index
        )
    ].groupby('Description').count()[
        'StockCode'
    ].sort_values(ascending=False).head()
)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09736391646696337, 'fraction_numerical': 0.01280383430332078, 'mean_word_length': 5.690792487402657, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 63, 'https://': 2, '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': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '297634', 'license': 'MIT', 'n_tokens_mistral': 5116, 'n_tokens_neox': 4892, 'n_words': 1402, 'path': 'Procesados/4-CustomerSegmentation.ipynb', 'repo_name': 'hcgalvan/UNSAM-Machine-Learning-on-Economics', 'size': '14605'}