Importation Et Configuration: Nous Allons Importer Les Bibliothèques Nécessaires Et Créer Une Session Spark
Importation Et Configuration: Nous Allons Importer Les Bibliothèques Nécessaires Et Créer Une Session Spark
Nous allons importer les bibliothèques nécessaires et créer une session Spark.
spark
<[Link] at 0x6b4e888>
schema = StructType([
StructField("num_crypted", StringType(), True),
StructField("class_client", IntegerType(), True),
StructField("subclass_client", IntegerType(), True),
StructField("class_service", IntegerType(), True),
StructField("life_time", IntegerType(), True),
StructField("type_sim", IntegerType(), True),
StructField("nb_transaction", IntegerType(), True),
StructField("sum_achat", StringType(), True)
])
+--------------------+------------+---------------+-------------
+---------+--------+--------------+-----------------+
| num_crypted|class_client|subclass_client|class_service|
life_time|type_sim|nb_transaction| sum_achat|
+--------------------+------------+---------------+-------------
+---------+--------+--------------+-----------------+
|sMpp-SPJ3ntR6gwVx...| 70.0| 124.0| 1.0|
47.0| 2.0| 14.0| 0,01860905175236|
|s3BXUpS8y13Ndw-4l...| 70.0| 124.0| 1.0|
98.0| 1.0| 3.0|0,007096672450206|
|sPRMtjQIwjc9gaEyo...| 70.0| 107.0| 2.0|
97.0| 1.0| 42.0|0,033117804767628|
|s4dty8t1voRaK26tS...| 70.0| 108.0| 1.0|
85.0| 2.0| 3.0|0,004258003357523|
|sHYErfG0V5Mz2C4Gd...| 70.0| 106.0| 1.0|
2.0| 2.0| 2.0| 0,00378489193591|
|sJcB3ghy-_rXyw3kU...| 70.0| 149.0| 1.0|
27.0| 2.0| 5.0|0,006465856971165|
|sN95eGT40RNqPSIDM...| 70.0| 108.0| 1.0|
90.0| 2.0| 2.0| 0,06308153289072|
|s_lLRC-rom-lpQHoR...| 95.0| 106.0| 1.0|
83.0| 2.0| 2.0|0,002838668905015|
|scShyyISHjAZi8-j1...| 70.0| 106.0| 1.0|
34.0| 2.0| 5.0|0,006150449419312|
|s4ncCIj4xmG6kHCM8...| 70.0| 108.0| 1.0|
102.0| 2.0| 17.0| 0,03926825418694|
|ssHO6SlHyi0fsttq6...| 95.0| 106.0| 1.0|
27.0| 2.0| 4.0|0,008516006902714|
|sYHzC8oJeyQiUxUbr...| 70.0| 124.0| 1.0|
68.0| 2.0| 2.0| 0,00378489193591|
|s8P2ZU86X8S3UwPUb...| 70.0| 106.0| 1.0|
15.0| 2.0| 31.0|0,053461598149014|
|sl_BWYrdjdafuZ6EV...| 70.0| 20.0| 1.0|
107.0| 2.0| 1.0|0,001419334452508|
|sJ6AjDgT6EEsUXZG2...| 81.0| 124.0| 1.0|
65.0| 2.0| 1.0|0,001419334452508|
|szOqfiSwSonBdhhTA...| 70.0| 124.0| 1.0|
70.0| 2.0| 24.0|0,150449455906833|
|sZxtoMoqoJ1zk65oj...| 70.0| 106.0| 1.0|
62.0| 2.0| 3.0| 0,00513325973157|
|sG556qd0kNgoC2e5E...| 70.0| 106.0| 1.0|
10.0| 2.0| 3.0|0,006150449419312|
|s5fPNQ8t-bw12vBWW...| 70.0| 108.0| 1.0|
99.0| 1.0| 8.0|0,044551332604071|
|s0yu8uU19_LQW7pA5...| 70.0| 106.0| 1.0|
1.0| 2.0| 3.0|0,005992745643385|
+--------------------+------------+---------------+-------------
+---------+--------+--------------+-----------------+
only showing top 20 rows
# Supprimer les lignes avec des valeurs manquantes dans des colonnes
spécifiques
df = [Link](subset=['num_crypted'])
Aggregated results:
+-------------+-------------+-------------+-------------+
|sum_sum_achat|avg_sum_achat|max_sum_achat|min_sum_achat|
+-------------+-------------+-------------+-------------+
| 0.0| 0.0| unknown| 0|
+-------------+-------------+-------------+-------------+
User segments:
+---------------+----------+-------------+
|subclass_client|user_count|avg_sum_achat|
+---------------+----------+-------------+
| 150.0| 801| null|
| 137.0| 683| 0.0|
| 235.0| 313| 0.0|
| 113.0| 115| null|
| 124.0| 37| null|
| 106.0| 32| null|
| 36.0| 22| null|
| 34.0| 16| null|
| null| 4| null|
| 126.0| 2| null|
| 102.0| 1| null|
| 33.0| 1| null|
| 93.0| 1| null|
| 105.0| 1| null|
| 61.0| 1| null|
| 57.0| 1| null|
| 11.0| 1| null|
| 341.0| 1| null|
| 119.0| 1| null|
| 127.0| 1| null|
+---------------+----------+-------------+
only showing top 20 rows
EDA
[Link]()
+--------------------+------------+---------------+-------------
+---------+--------+--------------+-----------------+
| num_crypted|class_client|subclass_client|class_service|
life_time|type_sim|nb_transaction| sum_achat|
+--------------------+------------+---------------+-------------
+---------+--------+--------------+-----------------+
|sMpp-SPJ3ntR6gwVx...| 70.0| 124.0| 1.0|
47.0| 2.0| 14.0| 0,01860905175236|
|s3BXUpS8y13Ndw-4l...| 70.0| 124.0| 1.0|
98.0| 1.0| 3.0|0,007096672450206|
|sPRMtjQIwjc9gaEyo...| 70.0| 107.0| 2.0|
97.0| 1.0| 42.0|0,033117804767628|
|s4dty8t1voRaK26tS...| 70.0| 108.0| 1.0|
85.0| 2.0| 3.0|0,004258003357523|
|sHYErfG0V5Mz2C4Gd...| 70.0| 106.0| 1.0|
2.0| 2.0| 2.0| 0,00378489193591|
|sJcB3ghy-_rXyw3kU...| 70.0| 149.0| 1.0|
27.0| 2.0| 5.0|0,006465856971165|
|sN95eGT40RNqPSIDM...| 70.0| 108.0| 1.0|
90.0| 2.0| 2.0| 0,06308153289072|
|s_lLRC-rom-lpQHoR...| 95.0| 106.0| 1.0|
83.0| 2.0| 2.0|0,002838668905015|
|scShyyISHjAZi8-j1...| 70.0| 106.0| 1.0|
34.0| 2.0| 5.0|0,006150449419312|
|s4ncCIj4xmG6kHCM8...| 70.0| 108.0| 1.0|
102.0| 2.0| 17.0| 0,03926825418694|
|ssHO6SlHyi0fsttq6...| 95.0| 106.0| 1.0|
27.0| 2.0| 4.0|0,008516006902714|
|sYHzC8oJeyQiUxUbr...| 70.0| 124.0| 1.0|
68.0| 2.0| 2.0| 0,00378489193591|
|s8P2ZU86X8S3UwPUb...| 70.0| 106.0| 1.0|
15.0| 2.0| 31.0|0,053461598149014|
|sl_BWYrdjdafuZ6EV...| 70.0| 20.0| 1.0|
107.0| 2.0| 1.0|0,001419334452508|
|sJ6AjDgT6EEsUXZG2...| 81.0| 124.0| 1.0|
65.0| 2.0| 1.0|0,001419334452508|
|szOqfiSwSonBdhhTA...| 70.0| 124.0| 1.0|
70.0| 2.0| 24.0|0,150449455906833|
|sZxtoMoqoJ1zk65oj...| 70.0| 106.0| 1.0|
62.0| 2.0| 3.0| 0,00513325973157|
|sG556qd0kNgoC2e5E...| 70.0| 106.0| 1.0|
10.0| 2.0| 3.0|0,006150449419312|
|s5fPNQ8t-bw12vBWW...| 70.0| 108.0| 1.0|
99.0| 1.0| 8.0|0,044551332604071|
|s0yu8uU19_LQW7pA5...| 70.0| 106.0| 1.0|
1.0| 2.0| 3.0|0,005992745643385|
+--------------------+------------+---------------+-------------
+---------+--------+--------------+-----------------+
only showing top 20 rows
149700
+-----------+------------+---------------+-------------+---------
+--------+--------------+---------+
|num_crypted|class_client|subclass_client|class_service|life_time|
type_sim|nb_transaction|sum_achat|
+-----------+------------+---------------+-------------+---------
+--------+--------------+---------+
| 147151| 12| 58| 5| 154|
2| 145| 16251|
+-----------+------------+---------------+-------------+---------
+--------+--------------+---------+
+-------+--------------------+-----------------+------------------
+------------------+-----------------+------------------
+------------------+--------------------+
|summary| num_crypted| class_client| subclass_client|
class_service| life_time| type_sim| nb_transaction|
sum_achat|
+-------+--------------------+-----------------+------------------
+------------------+-----------------+------------------
+------------------+--------------------+
| count| 149700| 149699| 149549|
149699| 149698| 149699| 148199|
149700|
| mean| null|72.80275753345046|121.27822319106113|
1.0619443015651406|42.95799543080068| 1.927360904214457|
5.6130068354037475|0.021739130434782608|
| stddev| null|7.741232839293571| 41.03937782912098|
0.2961201559040936|38.06135589803621|0.2595440377650119|
9.128476387018598| 0.14744195615489714|
| min|---ZgNYsEeuL_qp5s...| 70.0| 11.0|
1.0| 1.0| 1.0| 1.0| -
0,13625610743506|
| max|zzyZmxQGvcbFndkp-...| 103.0| 341.0|
5.0| 154.0| 2.0| 1344.0|
unknown|
+-------+--------------------+-----------------+------------------
+------------------+-----------------+------------------
+------------------+--------------------+
Columns classification :
We concluded that :
+------------+------+
|class_client| count|
+------------+------+
| 70.0|128579|
| 95.0| 10575|
| 81.0| 4732|
| 102.0| 2011|
| 96.0| 1270|
| 72.0| 1133|
| 71.0| 1032|
| 73.0| 282|
| 82.0| 45|
| 103.0| 27|
| 83.0| 10|
| 92.0| 3|
| null| 1|
+------------+------+
+------------+------+--------------------+
|class_client| count| percentage|
+------------+------+--------------------+
| 70.0|128579| 85.89111556446227|
| 95.0| 10575| 7.064128256513026|
| 81.0| 4732| 3.1609886439545756|
| 102.0| 2011| 1.3433533734134937|
| 96.0| 1270| 0.8483633934535738|
| 72.0| 1133| 0.7568470273881096|
| 71.0| 1032| 0.6893787575150301|
| 73.0| 282| 0.18837675350701402|
| 82.0| 45| 0.03006012024048096|
| 103.0| 27|0.018036072144288578|
| 83.0| 10|0.006680026720106881|
| 92.0| 3|0.002004008016032064|
| null| 1| 6.68002672010688E-4|
+------------+------+--------------------+
We concluded that class 70 is dominant amongst the class_client classes distribution with an
occurance of 85%
[Link](df['class_client'].isNull()).count()
subclass_client cloumn
# Classes distribution
[Link]('subclass_client').count().orderBy('count',
ascending=False).show()
+---------------+-----+
|subclass_client|count|
+---------------+-----+
| 106.0|59954|
| 124.0|34510|
| 108.0| 9994|
| 137.0| 7936|
| 109.0| 7884|
| 116.0| 3863|
| 127.0| 3746|
| 341.0| 3047|
| 126.0| 2674|
| 149.0| 2531|
| 111.0| 2053|
| 113.0| 1657|
| 147.0| 1517|
| 107.0| 1104|
| 105.0| 1085|
| 338.0| 956|
| 150.0| 801|
| 85.0| 593|
| 20.0| 488|
| 98.0| 402|
+---------------+-----+
only showing top 20 rows
+---------------+-----+------------------+
|subclass_client|count| percentage|
+---------------+-----+------------------+
| 106.0|59954| 40.04943219772879|
| 124.0|34510|23.052772211088847|
| 108.0| 9994| 6.676018704074817|
| 137.0| 7936| 5.30126920507682|
| 109.0| 7884| 5.266533066132265|
| 116.0| 3863|2.5804943219772882|
| 127.0| 3746|2.5023380093520373|
| 341.0| 3047|2.0354041416165662|
| 126.0| 2674| 1.78623914495658|
| 149.0| 2531|1.6907147628590513|
| 111.0| 2053|1.3714094856379426|
| 113.0| 1657|1.1068804275217101|
| 147.0| 1517|1.0133600534402138|
| 107.0| 1104|0.7374749498997996|
| 105.0| 1085|0.7247828991315965|
| 338.0| 956|0.6386105544422178|
| 150.0| 801|0.5350701402805611|
| 85.0| 593| 0.396125584502338|
| 20.0| 488|0.3259853039412158|
| 98.0| 402|0.2685370741482966|
+---------------+-----+------------------+
only showing top 20 rows
We concluded that subclass 106 and 124 are dominant amongst the subclass_client classes
distribution with an occurance of 40% and 22% respectively.
[Link](df['subclass_client'].isNull()).count()
151
We noticed that the dominant (over 85% of rows) class in class_client 70 has 42 subclasses / 57
+---------------+-----+-------------------+
|subclass_client|count| percentage|
+---------------+-----+-------------------+
| 106.0|55501| 43.16490251129655|
| 124.0|33045| 25.700153213199666|
| 108.0| 9733| 7.569665341929864|
| 109.0| 7643| 5.944205507897869|
| 116.0| 3755| 2.920383577411552|
| 127.0| 3491| 2.715062335218037|
| 126.0| 2519| 1.9591068525964581|
| 149.0| 2503| 1.9466631409483663|
| 341.0| 2158| 1.6783456085363861|
| 111.0| 1909| 1.484690346012957|
| 107.0| 1048| 0.8150631129500152|
| 105.0| 931| 0.7240684715233436|
| 338.0| 919| 0.7147356877872747|
| 85.0| 583| 0.4534177431773462|
| 20.0| 481| 0.3740890814207608|
| 98.0| 379| 0.2947604196641753|
| 339.0| 324|0.25198516087385964|
| 119.0| 293| 0.2278754695556817|
| 11.0| 232|0.18043381889733162|
| 143.0| 167|0.12988124032695852|
+---------------+-----+-------------------+
only showing top 20 rows
We concluded that there is no clear dominant subclass_client class to use as a replacement for
the missing subclass_client values. Nor is there any strong correlation between class_client and
subclass_client that can help us fill those missing values. Seeing that 146 (number of rows of
missing subclass_client) is negligeable compared with the total number of rows (approxiamtely
150 000) we decided that these rows will be simply dropped in the data cleaning phase.
class_service column
# Classes distribution
[Link]('class_service').count().orderBy('count',
ascending=False).show()
+-------------+------+
|class_service| count|
+-------------+------+
| 1.0|141940|
| 2.0| 6934|
| 4.0| 667|
| 3.0| 147|
| 5.0| 11|
| null| 1|
+-------------+------+
+-------------+------+--------------------+
|class_service| count| percentage|
+-------------+------+--------------------+
| 1.0|141940| 94.81629926519706|
| 2.0| 6934| 4.631930527722111|
| 4.0| 667| 0.4455577822311289|
| 3.0| 147| 0.09819639278557116|
| 5.0| 11|0.007348029392117568|
| null| 1| 6.68002672010688E-4|
+-------------+------+--------------------+
We concluded that class 1 is dominant amongst the class_service classes distribution with an
occurance of 94%
[Link](df['class_service'].isNull()).count()
type_sim column
# Classes distribution
[Link]('type_sim').count().orderBy('count',
ascending=False).show()
+--------+------+
|type_sim| count|
+--------+------+
| 2.0|138825|
| 1.0| 10874|
| null| 1|
+--------+------+
+--------+------+-------------------+
|type_sim| count| percentage|
+--------+------+-------------------+
| 2.0|138825| 92.73547094188376|
| 1.0| 10874| 7.263861055444222|
| null| 1|6.68002672010688E-4|
+--------+------+-------------------+
We concluded that class 2 is dominant amongst the type_sim classes distribution with an
occurance of 92%
[Link](df['type_sim'].isNull()).count()
1
EDA Numerical Columns
life_time column
[Link]('life_time').describe().show()
+-------+-----------------+
|summary| life_time|
+-------+-----------------+
| count| 149698|
| mean|42.95799543080068|
| stddev|38.06135589803621|
| min| 1.0|
| max| 154.0|
+-------+-----------------+
This high value indicates a significant spread in the life_time values, meaning there is
considerable variability around the mean.
Outliers analysis
pdf = [Link]()
The presence of high values (e.g., 154 days) suggests potential outliers or a long-tail
distribution.n
threshold = pdf['life_time'].quantile(0.90)
# Filter the data to include only the tail end (values greater than
the threshold)
tail_data = pdf[pdf['life_time'] > threshold]
Missing values
from [Link] import isnan, col
[Link](col('life_time').isNull() | isnan(col('life_time'))).count()
There seems to be 1 only row with a missing life time, we'll be dropping it
nb_transaction Column
[Link]('nb_transaction').describe().show()
+-------+------------------+
|summary| nb_transaction|
+-------+------------------+
| count| 148199|
| mean|5.6130068354037475|
| stddev| 9.128476387018598|
| min| 1.0|
| max| 1344.0|
+-------+------------------+
This high value indicates a significant spread in the nb_transaction values, meaning there is
considerable variability around the mean.
Outliers analysis
import [Link] as plt
pdf = [Link](subset=['nb_transaction'])
[Link](figsize=(10, 6))
[Link](pdf['nb_transaction'], vert=False)
[Link]('Number of transactions')
[Link]('Box Plot of Number of transactions')
[Link]()
The box plot indicates that some of the transaction counts display as a discontinuous tail due to
extreme outliers. The Q1-Q3 box is barely visible because of these outliers. We conclude that we
will cut off the data at transaction counts less than 200 and redo the box plot to see if further
reduction is needed.
The tail seems continuous enough to consider that this data is now free of outliers.
The Q1-Q3 range is relatively small, suggesting that the majority of the number of transactions
data is compact.
Missing values
from [Link] import isnan, col
[Link](col('nb_transaction').isNull() |
isnan(col('nb_transaction'))).count()
1501
There are 1472 rows with missing number of transactions. Since sum_achat is most likely
strongly correlated to number of transactions, we'll most likely replace the missing number of
transaction with sum_achat
Sum_achat Colmun
[Link]('sum_achat').describe().show()
+-------+--------------------+
|summary| sum_achat|
+-------+--------------------+
| count| 149700|
| mean|0.021739130434782608|
| stddev| 0.14744195615489714|
| min| -0,13625610743506|
| max| unknown|
+-------+--------------------+
df = [Link](df['sum_achat'] != 'V_8')
[Link]('sum_achat').describe().show()
+-------+--------------------+
|summary| sum_achat|
+-------+--------------------+
| count| 149700|
| mean|0.021739130434782608|
| stddev| 0.14744195615489714|
| min| -0,13625610743506|
| max| unknown|
+-------+--------------------+
[Link](col('sum_achat').desc()).first()
Row(num_crypted=u"tBlcyAYmF6gu3gD9d4wYlOH9x1KmgcIV1zD-
rgU3NPOgyOJtE_SVytEvvd13rJtonbLarfzCNPHaizNZXomgRww=='",
class_client=70.0, subclass_client=106.0, class_service=1.0,
life_time=1.0, type_sim=2.0, nb_transaction=1.0, sum_achat=u'unknown')
[Link]('sum_achat').describe().show()
+-------+--------------------+
|summary| sum_achat|
+-------+--------------------+
| count| 145352|
| mean| 0.02064955400476394|
| stddev|0.027451362598597866|
| min| -0.13625611|
| max| 1.0|
+-------+--------------------+
This high value indicates a significant spread in the sum_achat values, meaning there is
considerable variability around the mean.
There seems to be negative values in the sum_achat column that needs to be dropped kno<ing
that the sum_achat can only be positive.
Outliers analysis
from [Link] import col, regexp_replace
df = [Link]("sum_achat", regexp_replace(col("sum_achat"), ",",
"."))
pdf = [Link]()
pdf['sum_achat'] = pdf['sum_achat'].astype(float)
The plot shows a long tail extending from the box to higher values, indicating that there are
numerous data points that are significantly larger than the majority.
The tail becomes discontinuous around the 0.5 mark, meaning that the values beyond 0.5 can be
considered as outliers. We’ll be droping the rows with sum_achat > 0.5
Missing values
from [Link] import isnan, col
[Link](col('sum_achat').isNull() | isnan(col('sum_achat'))).count()
4348
Data Cleaning
df_cleaned = [Link]("Desktop/PFE/Services/[Link]",
schema=schema, header=False, sep=',')
# drop title row
df_cleaned = df_cleaned.filter(df_cleaned.num_crypted != "Achat
Service OTN")
# Missing values
df_cleaned = df_cleaned.dropna(subset=['subclass_client', 'life_time',
'nb_transaction'])
# Outliers removal
df_cleaned = df_cleaned.filter(col("nb_transaction") <= 200)
df_cleaned = df_cleaned.filter(col("sum_achat") <= 0.5)
Data Transformation
Normalize the Numerical Columns
from [Link] import StandardScaler
stages = []
for column in numerical_columns:
assembler = VectorAssembler(inputCols=[column], outputCol=column +
"_vec")
scaler = StandardScaler(inputCol=column + "_vec", outputCol=column
+ "_scaled")
stages += [assembler, scaler]
pipeline = Pipeline(stages=stages)
df_encoded = [Link](df_cleaned).transform(df_cleaned)
assembler = VectorAssembler(inputCols=feature_columns,
outputCol="features")
df_features = [Link](df_encoded)
df_features.show()
+--------------------+------------+---------------+-------------
+---------+--------+--------------+------------+-------------
+--------------------+------------------+---------------------
+--------------------+--------------------+------------------
+--------------------+---------------------+-----------------------
+-------------------+---------------------+--------------
+----------------+--------------------+
| num_crypted|class_client|subclass_client|class_service|
life_time|type_sim|nb_transaction| sum_achat|life_time_vec|
life_time_scaled|nb_transaction_vec|nb_transaction_scaled|
sum_achat_vec| sum_achat_scaled|class_client_index|
class_client_encoded|subclass_client_index|subclass_client_encoded|
class_service_index|class_service_encoded|type_sim_index|
type_sim_encoded| features|
+--------------------+------------+---------------+-------------
+---------+--------+--------------+------------+-------------
+--------------------+------------------+---------------------
+--------------------+--------------------+------------------
+--------------------+---------------------+-----------------------
+-------------------+---------------------+--------------
+----------------+--------------------+
|cXHXGWtboQO3-UtA9...| 70| 124| 1|
47| 2| 1|0.0070966724| [47.0]|
[1.234824130535631]| [1.0]| [0.11982080568581...|
[0.00709667243063...|[0.2617748998764478]| 0.0|
(11,[0],[1.0])| 1.0| (56,[1],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,12,67,71,7...|
|TQgqROQQmRYzbFBQ6...| 70| 106| 1|
11| 2| 1|0.0023655575| [11.0]|
[0.28900139225302]| [1.0]| [0.11982080568581...|
[0.00236555747687...|[0.08725829995881...| 0.0|
(11,[0],[1.0])| 0.0| (56,[0],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,11,67,71,7...|
|qdWT1RW43fvrO-eyS...| 70| 109| 1|
88| 2| 9| 0.029806023| [88.0]|
[2.31201113802416]| [9.0]| [1.078387251172312]|
[0.02980602346360...| [1.09945455199813]| 0.0|
(11,[0],[1.0])| 4.0| (56,[4],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,15,67,71,7...|
|mn-xISgfFqf7Yx4X-...| 70| 124| 1|
47| 2| 10| 0.014193345| [47.0]|
[1.234824130535631]| [10.0]| [1.1982080568581246]|
[0.01419334486126...|[0.5235497997528956]| 0.0|
(11,[0],[1.0])| 1.0| (56,[1],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,12,67,71,7...|
|xgTk1_o9FTP5fddPZ...| 70| 85| 1|
142| 1| 1|7.8851916E-4| [142.0]|
[3.7307452454480763]| [1.0]| [0.11982080568581...|
[7.88519158959388...|[0.02908609998627...| 0.0|
(11,[0],[1.0])| 17.0| (56,[17],[1.0])|
0.0| (4,[0],[1.0])| 1.0| (1,[],[])|(75,
[0,28,67,72,7...|
|C5Zv431UiQZaXLXBl...| 70| 106| 1|
3| 2| 4|0.0048888186| [3.0]|
[0.0788185615235509]| [4.0]| [0.4792832227432498]|
[0.00488881859928...|[0.18033381304414...| 0.0|
(11,[0],[1.0])| 0.0| (56,[0],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,11,67,71,7...|
|JCnEAQKbI7iMqTBou...| 70| 106| 1|
13| 2| 28| 0.15423435| [13.0]|
[0.34154709993538...| [28.0]| [3.3549825592027487]|
[0.15423434972763...| [5.689241239763652]| 0.0|
(11,[0],[1.0])| 0.0| (56,[0],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,11,67,71,7...|
|A3-Y0rOfzmvuIMF9R...| 70| 126| 1|
76| 2| 3|0.0070966724| [76.0]|
[1.9967368919299564]| [3.0]| [0.35946241705743...|
[0.00709667243063...|[0.2617748998764478]| 0.0|
(11,[0],[1.0])| 8.0| (56,[8],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,19,67,71,7...|
|GFm2TAh3yr0la30Lv...| 70| 106| 1|
1| 2| 1|0.0013483678| [1.0]|
[0.02627285384118...| [1.0]| [0.11982080568581...|
[0.00134836777579...|[0.04973723149183...| 0.0|
(11,[0],[1.0])| 0.0| (56,[0],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,11,67,71,7...|
|XTsoXXs6bjggR2_G5...| 70| 108| 1|
100| 1| 8|0.0113546755| [100.0]|
[2.6272853841183634]| [8.0]| [0.9585664454864996]|
[0.01135467551648...|[0.41883982606084...| 0.0|
(11,[0],[1.0])| 2.0| (56,[2],[1.0])|
0.0| (4,[0],[1.0])| 1.0| (1,[],[])|(75,
[0,13,67,72,7...|
|NMLfEprQR47HEwLy5...| 70| 106| 1|
1| 2| 1|0.0014193344| [1.0]|
[0.02627285384118...| [1.0]| [0.11982080568581...|
[0.00141933443956...|[0.05235497825760...| 0.0|
(11,[0],[1.0])| 0.0| (56,[0],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,11,67,71,7...|
|zNhfpnL1mpeUrfTGG...| 70| 108| 1|
83| 2| 1|0.0070966724| [83.0]|
[2.1806468688182417]| [1.0]| [0.11982080568581...|
[0.00709667243063...|[0.2617748998764478]| 0.0|
(11,[0],[1.0])| 2.0| (56,[2],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,13,67,71,7...|
|IqY_nsyMG3fbFXvs1...| 70| 106| 1|
13| 2| 1|0.0014193344| [13.0]|
[0.34154709993538...| [1.0]| [0.11982080568581...|
[0.00141933443956...|[0.05235497825760...| 0.0|
(11,[0],[1.0])| 0.0| (56,[0],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,11,67,71,7...|
|KLwD9dDXfDO2_2HAY...| 70| 106| 1|
20| 2| 1|6.3081534E-4| [20.0]|
[0.5254570768236727]| [1.0]| [0.11982080568581...|
[6.30815338809043...|[0.02326888041843...| 0.0|
(11,[0],[1.0])| 0.0| (56,[0],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,11,67,71,7...|
|CTzoQ0AritYwGnixA...| 95| 137| 1|
67| 2| 1|7.8851916E-4| [67.0]|
[1.7602812073593035]| [1.0]| [0.11982080568581...|
[7.88519158959388...|[0.02908609998627...| 1.0|
(11,[1],[1.0])| 3.0| (56,[3],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[1,14,67,71,7...|
|59R3KaAWVWU4Hr6iQ...| 70| 108| 1|
85| 2| 4| 0.052830786| [85.0]|
[2.233192576500609]| [4.0]| [0.4792832227432498]|
[0.05283078551292...|[1.9487687677875996]| 0.0|
(11,[0],[1.0])| 2.0| (56,[2],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,13,67,71,7...|
|ZwZzZrlJZx1Y0w4aw...| 70| 106| 1|
26| 2| 3|0.0070966724| [26.0]|
[0.6830941998707745]| [3.0]| [0.35946241705743...|
[0.00709667243063...|[0.2617748998764478]| 0.0|
(11,[0],[1.0])| 0.0| (56,[0],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,11,67,71,7...|
|T9OPU9EQd5CTwXWnP...| 70| 109| 1|
93| 1| 4| 0.00946223| [93.0]|
[2.443375407230078]| [4.0]| [0.4792832227432498]|
[0.00946222990751...|[0.34903319983526...| 0.0|
(11,[0],[1.0])| 4.0| (56,[4],[1.0])|
0.0| (4,[0],[1.0])| 1.0| (1,[],[])|(75,
[0,15,67,72,7...|
|8lni8H4V6Zav6NnNe...| 103| 113| 1|
28| 2| 16| 0.042719264| [28.0]|
[0.7356399075531418]| [16.0]| [1.9171328909729992]|
[0.04271926358342...| [1.575785138267396]| 9.0|
(11,[9],[1.0])| 11.0| (56,[11],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[9,22,67,71,7...|
|dLVzZxwaSHtr9zIV1...| 70| 108| 1|
100| 2| 5| 0.091862485| [100.0]|
[2.6272853841183634]| [5.0]| [0.5991040284290623]|
[0.09186248481273...| [3.388530751461751]| 0.0|
(11,[0],[1.0])| 2.0| (56,[2],[1.0])|
0.0| (4,[0],[1.0])| 0.0| (1,[0],[1.0])|(75,
[0,13,67,71,7...|
+--------------------+------------+---------------+-------------
+---------+--------+--------------+------------+-------------
+--------------------+------------------+---------------------
+--------------------+--------------------+------------------
+--------------------+---------------------+-----------------------
+-------------------+---------------------+--------------
+----------------+--------------------+
only showing top 20 rows
Clustering
Elbow method
import [Link] as plt
wcss = []
range_clusters = range(2, 15) # Define the range for k
for k in range_clusters:
kmeans = KMeans(k=k, seed=1)
model = [Link](df_features)
[Link]([Link])
import numpy as np
# Function to calculate the distance from a point to a line
def distance_to_line(point, line_start, line_end):
point = [Link](point)
line_start = [Link](line_start)
line_end = [Link](line_end)
return [Link]([Link](line_end-line_start, line_start-point) /
[Link](line_end-line_start))
# Compute the distances from the line connecting the first and last
points
line_start = [range_clusters[0], wcss[0]]
line_end = [range_clusters[-1], wcss[-1]]
distances = [distance_to_line([k, wcss[i]], line_start, line_end) for
i, k in enumerate(range_clusters)]
# Find the optimal number of clusters as the one with the maximum
distance
optimal_k = range_clusters[[Link](distances)]
optimal_k
distances
[0.0,
3.1902479135290926,
4.22021843795659,
3.5852288854481835,
4.57261642372215,
4.421662828553438,
4.078817689014636,
3.3117429661876425,
2.4228863848843774,
1.973793520961397,
1.3512932673014124,
0.4361865166906377,
0.0]
The optimal number of clusters is 6 since its the furthest from the red line.
We'll cluster the Data into 6 groups in an attempt of building/identifying better user
profile/personas groups.
from [Link] import KMeans
kmeans = KMeans(k=optimal_k, seed=1)
model = [Link](df_features)
predictions = [Link](df_features)
+------------+---------------+-------------+--------+---------
+--------------+------------+----------+
|class_client|subclass_client|class_service|type_sim|life_time|
nb_transaction| sum_achat|prediction|
+------------+---------------+-------------+--------+---------
+--------------+------------+----------+
| 70| 124| 1| 2| 47|
1|0.0070966724| 1|
| 70| 106| 1| 2| 11|
1|0.0023655575| 0|
| 70| 109| 1| 2| 88|
9| 0.029806023| 2|
| 70| 124| 1| 2| 47|
10| 0.014193345| 1|
| 70| 85| 1| 1| 142|
1|7.8851916E-4| 2|
| 70| 106| 1| 2| 3|
4|0.0048888186| 0|
| 70| 106| 1| 2| 13|
28| 0.15423435| 5|
| 70| 126| 1| 2| 76|
3|0.0070966724| 2|
| 70| 106| 1| 2| 1|
1|0.0013483678| 0|
| 70| 108| 1| 1| 100|
8|0.0113546755| 2|
| 70| 106| 1| 2| 1|
1|0.0014193344| 0|
| 70| 108| 1| 2| 83|
1|0.0070966724| 2|
| 70| 106| 1| 2| 13|
1|0.0014193344| 0|
| 70| 106| 1| 2| 20|
1|6.3081534E-4| 0|
| 95| 137| 1| 2| 67|
1|7.8851916E-4| 4|
| 70| 108| 1| 2| 85|
4| 0.052830786| 2|
| 70| 106| 1| 2| 26|
3|0.0070966724| 0|
| 70| 109| 1| 1| 93|
4| 0.00946223| 2|
| 103| 113| 1| 2| 28|
16| 0.042719264| 4|
| 70| 108| 1| 2| 100|
5| 0.091862485| 5|
+------------+---------------+-------------+--------+---------
+--------------+------------+----------+
only showing top 20 rows
df_summary = df_cleaned.describe()
cluster_0_summary = cluster_0_df.describe()
common_columns = ["summary", "life_time", "nb_transaction",
"sum_achat"]
df_summary_selected =
df_summary.select(common_columns).withColumn("source",
lit("original"))
cluster_0_summary_selected =
cluster_0_summary.select(common_columns).withColumn("source",
lit("cluster_0"))
comparison_summary =
df_summary_selected.union(cluster_0_summary_selected)
comparison_summary_pd = comparison_summary.toPandas()
cols = ['source'] + [col for col in comparison_summary_pd.columns if
col != 'source']
comparison_summary_pd = comparison_summary_pd[cols]
comparison_summary_pd =
comparison_summary_pd.sort_values(by=['summary', 'source'])
comparison_summary_pd
sum_achat
5 55128
0 141307
9 0.06134679
4 0.46104714
6 0.013819638618474076
1 0.020591187240199666
8 0.0
3 0.0
7 0.014885433804150553
2 0.027109827695412994
df_class_percentage = df_cleaned.groupBy(column_name).count() \
.withColumn('percentage', (col('count') / total_count_df) *
100) \
.orderBy(col('percentage'), ascending=False)
cluster_class_percentage = cluster_df.groupBy(column_name).count()
\
.withColumn('percentage', (col('count') / total_count_cluster)
* 100) \
.orderBy(col('percentage'), ascending=False)
df_class_percentage =
df_class_percentage.withColumnRenamed('count', 'total_count') \
.withColumnRenamed('percentage', 'total_percentage')
cluster_class_percentage =
cluster_class_percentage.withColumnRenamed('count', 'cluster_count') \
.withColumnRenamed('percentage', 'cluster_percentage')
comparison_df = df_class_percentage.join(cluster_class_percentage,
on=column_name, how='outer')
return comparison_df.toPandas()
cluster_percentage
0 4.917646
1 NaN
2 0.108838
3 0.001814
4 0.009070
5 0.029023
6 0.014512
7 0.070744
8 94.804818
9 NaN
10 NaN
11 0.043535
cluster_percentage
0 0.001814
1 0.003628
2 NaN
3 0.041721
4 0.078000
5 NaN
6 NaN
7 0.085256
8 NaN
9 NaN
10 0.007256
11 NaN
12 1.440284
13 NaN
14 0.003628
15 0.052605
16 0.005442
17 0.001814
18 NaN
19 0.266652
20 NaN
21 NaN
22 NaN
23 5.588811
24 NaN
25 0.007256
26 NaN
27 0.003628
28 NaN
29 NaN
30 0.012698
31 NaN
32 0.232187
33 0.195908
34 0.977725
35 0.001814
36 4.672762
37 0.001814
38 0.041721
39 0.025395
40 0.087070
41 0.016326
42 NaN
43 NaN
44 82.246771
45 0.056233
46 NaN
47 NaN
48 0.132419
49 0.012698
50 3.508199
51 0.016326
52 NaN
53 0.001814
54 0.136047
55 0.034465
56 0.001814
cluster_percentage
0 94.801190
1 0.201350
2 0.009070
3 0.522421
4 4.465970
Conclusion
The most notable changes in the cluster include the complete absence of class_client
95 and type_sim 1, as well as the dramatic increase in subclass_client 106 from 40%
to 82%. These shifts highlight specific trends and associations within the clustered
group that could inform targeted strategies and [Link]:emainrventions.
Cluster 0 Persona/Behavior:
Persona: Cluster 0 comprises clients predominantly characterized by their membership in
subclass_client 106, who are new or exhibit minimal engagement with the service. They do not
belong to class_client 95 or use type_sim 1.
Behavior: These clients likely exhibit a cautious approach to using the service, exploring without
full commitment or having budget constraints. Their lower transaction counts and purchase
amounts further emphasize this cautious and budget-conscious behavior.
Cluster 1
cluster_1_df = [Link]([Link] == 1)
df_summary = df_cleaned.describe()
cluster_1_summary = cluster_1_df.describe()
common_columns = ["summary", "life_time", "nb_transaction",
"sum_achat"]
df_summary_selected =
df_summary.select(common_columns).withColumn("source",
lit("original"))
cluster_1_summary_selected =
cluster_1_summary.select(common_columns).withColumn("source",
lit("cluster_0"))
comparison_summary =
df_summary_selected.union(cluster_1_summary_selected)
comparison_summary_pd = comparison_summary.toPandas()
cols = ['source'] + [col for col in comparison_summary_pd.columns if
col != 'source']
comparison_summary_pd = comparison_summary_pd[cols]
comparison_summary_pd =
comparison_summary_pd.sort_values(by=['summary', 'source'])
comparison_summary_pd
source summary life_time nb_transaction \
5 cluster_0 count 28829 28829
0 original count 141307 141307
9 cluster_0 max 97 22
4 original max 154 174
6 cluster_0 mean 54.877623226612094 4.694335564882583
1 original mean 42.89374907117128 5.589871697792749
8 cluster_0 min 4 1
3 original min 1 1
7 cluster_0 stddev 14.500714391696485 4.403776291908017
2 original stddev 38.0621003734457 8.345795993244655
sum_achat
5 28829
0 141307
9 0.06134679
4 0.46104714
6 0.014255520952511175
1 0.020591187240199666
8 0.0
3 0.0
7 0.0146081887161619
2 0.027109827695412994
cluster_percentage
0 2.303236
1 NaN
2 0.128343
3 NaN
4 0.024281
5 0.097124
6 0.010406
7 0.107531
8 96.680426
9 0.641715
10 NaN
11 0.006937
cluster_percentage
0 0.093656
1 0.010406
2 NaN
3 0.076312
4 0.110999
5 0.006937
6 NaN
7 3.506885
8 NaN
9 NaN
10 0.038156
11 0.006937
12 1.661521
13 NaN
14 0.013875
15 NaN
16 0.006937
17 0.010406
18 0.010406
19 NaN
20 NaN
21 NaN
22 NaN
23 0.149155
24 NaN
25 0.017344
26 NaN
27 0.003469
28 0.003469
29 NaN
30 0.055500
31 NaN
32 NaN
33 NaN
34 NaN
35 0.010406
36 0.003469
37 NaN
38 0.114468
39 0.489091
40 0.204655
41 0.069375
42 NaN
43 NaN
44 0.489091
45 0.072843
46 NaN
47 NaN
48 0.221999
49 0.031219
50 0.048562
51 92.452045
52 NaN
53 NaN
54 NaN
55 0.010406
56 NaN
class_client Distribution:
• Class 95: Previously represented 7.10% of the total population but is now completely
absent in the cluster, indicating a significant exclusion of this class from the cluster's
composition.
subclass_client Distribution:
• Subclass 106: Previously constituted 40.20% of the total population and now stands at
0.49% in the cluster, showing a dramatic decrease and less association with the cluster.
class_service Distribution:
• No notable changes were observed, indicating that the distribution of class_service
remains relatively consistent between the total population and the cluster.
type_sim Distribution:
• Type Sim 1: Previously made up 7.26% of the total population but is now completely
absent in the cluster, suggesting a significant shift away from this type within the cluster.
Conclusion
The most notable changes in the cluster include the complete absence of class_client 95
and type_sim 1, as well as the dramatic decrease in subclass_client 106 from 40.20% to
0.49%. These shifts highlight specific trends and associations within the clustered group that
could inform targeted strategies and interventions. Understanding these changes can guide
efforts to tailor marketing strategies or service offerings to better align with the characteristics
of the clustered group.
Cluster 1 Persona/Behavior:
Persona:
Cluster 1 consists of customers who exhibit longer engagement periods compared to the entire
dataset. They show variability in their categorical profiles, particularly in class_client and
subclass_client, suggesting diverse customer segments within the cluster.
Behavior:
These customers demonstrate longer engagement with the service but lower transaction counts
and spending amounts compared to the overall dataset. They are characterized by consistent
but moderate engagement levels, indicating a stable relationship with the service offerings.
Despite spending less and making fewer transactions on average, their extended engagement
suggests loyalty and continued interest in the service.
Cluster 2
cluster_2_df = [Link]([Link] == 2)
df_summary = df_cleaned.describe()
cluster_2_summary = cluster_2_df.describe()
common_columns = ["summary", "life_time", "nb_transaction",
"sum_achat"]
df_summary_selected =
df_summary.select(common_columns).withColumn("source",
lit("original"))
cluster_2_summary_selected =
cluster_2_summary.select(common_columns).withColumn("source",
lit("cluster_2"))
comparison_summary =
df_summary_selected.union(cluster_2_summary_selected)
comparison_summary_pd = comparison_summary.toPandas()
cols = ['source'] + [col for col in comparison_summary_pd.columns if
col != 'source']
comparison_summary_pd = comparison_summary_pd[cols]
comparison_summary_pd =
comparison_summary_pd.sort_values(by=['summary', 'source'])
comparison_summary_pd
sum_achat
5 28142
0 141307
9 0.08476581
4 0.46104714
6 0.014659374975396287
1 0.020591187240199666
8 0.0
3 0.0
7 0.014796826469914143
2 0.027109827695412994
cluster_percentage
0 2.554900
1 NaN
2 0.195437
3 NaN
4 0.550778
5 0.031981
6 0.074622
7 0.344681
8 95.622202
9 0.309146
10 0.014214
11 0.302040
cluster_percentage
0 0.106602
1 1.805131
2 0.458390
3 NaN
4 30.147111
5 0.074622
6 NaN
7 3.517874
8 0.255845
9 0.017767
10 0.135029
11 0.014214
12 1.034042
13 0.003553
14 NaN
15 NaN
16 0.060408
17 1.456897
18 0.081728
19 NaN
20 NaN
21 0.003553
22 0.003553
23 0.213204
24 0.024874
25 3.329543
26 0.003553
27 NaN
28 NaN
29 0.010660
30 0.188331
31 0.426409
32 NaN
33 NaN
34 NaN
35 1.218819
36 NaN
37 NaN
38 23.861133
39 2.306162
40 0.337574
41 0.035534
42 NaN
43 0.024874
44 12.579063
45 11.779547
46 0.049748
47 0.007107
48 0.366001
49 NaN
50 0.063961
51 3.791486
52 NaN
53 NaN
54 NaN
55 0.159903
56 0.046194
cluster_percentage
0 90.174828
1 0.063961
2 0.017767
3 0.294933
4 9.448511
subclass_client Distribution:
• Subclass 106: Previously constituted 40.20% of the total population and now stands at
12.58% in the cluster, showing a notable decrease in representation within the cluster.
• Subclass 109: Increased significantly from 5.27% to 23.86%, indicating a strong
presence and association with the cluster.
• Subclass 108: Maintains a high presence, representing 6.67% of the total population and
30.15% in the cluster, showing consistency across the dataset and the cluster.
class_service Distribution:
• No notable changes were observed, indicating that the distribution of class_service
remains relatively consistent between the total population and the cluster.
type_sim Distribution:
• Type Sim 1: Previously made up 7.26% of the total population but is now completely
absent in the cluster, suggesting a significant shift away from this type within the cluster.
• Type Sim 2: Represents 92.74% of the total population and 67.21% in the cluster,
indicating a lower representation in the cluster compared to the total population.
Conclusion
The most notable changes in the cluster include the absence of class_client 95 and
type_sim 1, as well as significant shifts in subclass_client distributions. Specifically,
subclass_client 106 saw a decrease, while subclass_client 109 showed a notable
increase, reflecting specific trends and associations within the clustered group. These insights
can inform targeted strategies and interventions tailored to the characteristics of each cluster.
Cluster 2 Persona/Behavior:
Persona:
Behavior:
Cluster 2 likely represents a segment of clients who have a significantly longer lifetime
engagement with the service compared to the overall dataset. They exhibit lower transaction
counts and spending amounts despite their extended engagement periods. This behavior
suggests a cautious or less frequent purchasing pattern, possibly indicating a focus on long-
term relationship building with the service provider. The cluster's composition indicates a mix of
consistent and varied categorical preferences, highlighting a complex customer profile with
potential opportunities for targeted engagement strategies to enhance transaction frequency
and spending levels.
Cluster 3
cluster_3_df = [Link]([Link] == 3)
df_summary = df_cleaned.describe()
cluster_3_summary = cluster_3_df.describe()
common_columns = ["summary", "life_time", "nb_transaction",
"sum_achat"]
df_summary_selected =
df_summary.select(common_columns).withColumn("source",
lit("original"))
cluster_3_summary_selected =
cluster_3_summary.select(common_columns).withColumn("source",
lit("cluster_3"))
comparison_summary =
df_summary_selected.union(cluster_3_summary_selected)
comparison_summary_pd = comparison_summary.toPandas()
cols = ['source'] + [col for col in comparison_summary_pd.columns if
col != 'source']
comparison_summary_pd = comparison_summary_pd[cols]
comparison_summary_pd =
comparison_summary_pd.sort_values(by=['summary', 'source'])
comparison_summary_pd
source summary life_time nb_transaction \
5 cluster_3 count 6725 6725
0 original count 141307 141307
9 cluster_3 max 154 174
4 original max 154 174
6 cluster_3 mean 42.39375464684015 33.96104089219331
1 original mean 42.89374907117128 5.589871697792749
8 cluster_3 min 1 17
3 original min 1 1
7 cluster_3 stddev 35.21880560084209 15.844799554426414
2 original stddev 38.0621003734457 8.345795993244655
sum_achat
5 6725
0 141307
9 0.40119854
4 0.46104714
6 0.05003317081363401
1 0.020591187240199666
8 6.3081534E-4
3 0.0
7 0.031060748769071393
2 0.027109827695412994
Their behavior shows significantly higher transaction counts averaging around 34 transactions
and a slightly higher spending amount compared to the overall dataset.
cluster_percentage
0 1.174721
1 NaN
2 0.386617
3 NaN
4 0.342007
5 0.758364
6 0.044610
7 0.104089
8 93.011152
9 3.776952
10 NaN
11 0.401487
cluster_percentage
0 NaN
1 0.579926
2 2.453532
3 0.014870
4 5.903346
5 NaN
6 NaN
7 2.542751
8 0.059480
9 NaN
10 0.029740
11 NaN
12 1.115242
13 NaN
14 NaN
15 NaN
16 NaN
17 0.535316
18 NaN
19 NaN
20 0.118959
21 NaN
22 NaN
23 2.007435
24 NaN
25 0.698885
26 NaN
27 NaN
28 NaN
29 NaN
30 0.014870
31 0.386617
32 NaN
33 NaN
34 0.118959
35 0.223048
36 0.951673
37 NaN
38 4.475836
39 0.758364
40 0.163569
41 NaN
42 0.312268
43 NaN
44 40.401487
45 1.992565
46 0.118959
47 NaN
48 0.342007
49 NaN
50 2.513011
51 30.959108
52 NaN
53 NaN
54 0.029740
55 0.059480
56 0.118959
Class 95: Previously represented 7% of the total population but is now completely absent in the
cluster, indicating a significant shift away from this class.
Subclass 106: Previously constituted 40% of the total population and now stands at 82% in the
cluster, showing a dramatic increase and strong association with the cluster. Subclass 107:
Previously represented 40% of the total population but now stands at 40% in the cluster,
showing a moderate decrease and moderate association with the cluster. Subclass 72:
Previously constituted 40% of the total population and now stands at 40% in the cluster,
showing a dramatic increase and strong association with the cluster.
No notable changes were observed, indicating that the distribution of class_service remains
relatively consistent between the total population and the cluster.
Type Sim Distribution: Type Sim 1: Previously made up 7% of the total population but is now
completely absent in the cluster, suggesting a significant shift away from this type within the
cluster.
Conclusion
The most notable changes in the cluster include the complete absence of class_client 95 and
type_sim 1, as well as the dramatic increase in subclass_client 106 from 40% to 82%. These
shifts highlight specific trends and associations within the clustered group that could inform
targeted strategies and interventions.
Cluster 3 Persona/Behavior:
Persona: Cluster 3 represents clients characterized by a predominant membership in
subclass_client 106, showing a moderate engagement level with the service. They largely
belong to class_client 70 and predominantly use type_sim 2.
Behavior: These clients tend to have moderate transaction counts and purchase amounts,
indicating a balanced engagement with the service. They exhibit a preference for consistent
usage without extremely high or low activity levels. Understanding this cluster can help tailor
strategies to maintain their moderate engagement and potentially increase their participation
through targeted loyalty programs or personalized offers.
Cluster 4
cluster_4_df = [Link]([Link] == 4)
df_summary = df_cleaned.describe()
cluster_4_summary = cluster_4_df.describe()
common_columns = ["summary", "life_time", "nb_transaction",
"sum_achat"]
df_summary_selected =
df_summary.select(common_columns).withColumn("source",
lit("original"))
cluster_4_summary_selected =
cluster_4_summary.select(common_columns).withColumn("source",
lit("cluster_4"))
comparison_summary =
df_summary_selected.union(cluster_4_summary_selected)
comparison_summary_pd = comparison_summary.toPandas()
cols = ['source'] + [col for col in comparison_summary_pd.columns if
col != 'source']
comparison_summary_pd = comparison_summary_pd[cols]
comparison_summary_pd =
comparison_summary_pd.sort_values(by=['summary', 'source'])
comparison_summary_pd
sum_achat
5 13664
0 141307
9 0.06308153
4 0.46104714
6 0.011601299268702505
1 0.020591187240199666
8 0.0
3 0.0
7 0.013173007050880654
2 0.027109827695412994
cluster_percentage
0 1.522248
1 0.146370
2 6.857436
3 0.007319
4 6.059719
5 12.478044
6 0.029274
7 0.395199
8 NaN
9 66.766686
10 0.029274
11 5.708431
cluster_percentage
0 0.014637
1 NaN
2 51.156323
3 0.065867
4 0.021956
5 0.175644
6 0.007319
7 0.600117
8 NaN
9 NaN
10 0.021956
11 0.007319
12 0.680621
13 NaN
14 0.036593
15 NaN
16 0.109778
17 NaN
18 0.014637
19 0.021956
20 2.027225
21 NaN
22 NaN
23 0.131733
24 0.036593
25 0.007319
26 0.014637
27 NaN
28 NaN
29 NaN
30 0.029274
31 9.492096
32 NaN
33 NaN
34 0.146370
35 0.007319
36 0.043911
37 0.029274
38 0.007319
39 0.709895
40 0.080504
41 0.007319
42 5.137588
43 0.007319
44 14.988290
45 NaN
46 10.121487
47 0.007319
48 0.051230
49 0.065867
50 0.161007
51 1.968677
52 NaN
53 0.541569
54 NaN
55 0.007319
56 1.236827
cluster_percentage
0 95.169789
1 0.021956
2 NaN
3 0.446429
4 4.361827
# Type sim Distribution
compare_percentage_distribution(df_cleaned, cluster_4_df, "type_sim")
Class 95: Previously represented 7.10% of the total population but now only 0.64% in the
cluster, suggesting a notable decrease. Class 103: Previously represented 0.016% of the total
population but now accounts for 0.15% in the cluster, indicating a slight increase. Class 96, 72,
102, 73, 71: These classes show varying degrees of representation in the cluster compared to the
total population, with notable shifts in their percentages.
subclass_client Distribution:
Subclass 106: Previously constituted 40.20% of the total population and now stands at 14.99%
in the cluster, showing a dramatic decrease and association with the cluster. Subclass 137:
Previously made up 5.33% of the total population but is now completely absent in the cluster,
indicating a significant shift. Subclass 107, 150, 147: These subclasses show significant
representation in the cluster compared to the total population, with notable increases in their
percentages.
class_service Distribution:
No notable changes were observed, indicating that the distribution of class_service remains
relatively consistent between the total population and the cluster. The majority class (class 1)
continues to dominate both in the total population (94.83%) and the cluster (95.17%).
type_sim Distribution:
Type Sim 1: Previously made up 7.26% of the total population but now only 1.18% in the cluster,
suggesting a significant shift away from this type within the cluster. Type Sim 2: Previously
constituted 92.74% of the total population and now stands at 98.82% in the cluster, indicating a
strong association and near exclusivity within the cluster.
Conclusion
The most notable changes in Cluster 4 include the dramatic decrease in subclass_client 106
from 40.20% to 14.99%, the significant decrease of class_client 95 from 7.10% to 0.64%, and
the shift away from type_sim 1, which previously made up 7.26% of the total population. These
shifts highlight specific trends and associations within the clustered group that could inform
targeted strategies and interventions aimed at addressing the preferences and behaviors of
these segments.
Cluster 4 Persona/Behavior:
Persona:
Cluster 4 represents a diverse group of clients characterized by their significant association with
subclasses like 107, 150, and 147, which have seen substantial increases in representation within
the cluster. This cluster shows a notable shift away from type_sim 1 and a strong preference for
type_sim 2, indicating a clear preference for a specific type within the service offerings.
Behavior:
These clients exhibit a varied engagement pattern across different classes and subclasses. They
show a decreased presence of class_client 95 and an increased presence of subclass_client 107,
150, and 147. Their behavior suggests a focused interest in specific service types (type_sim 2)
while showing reduced interest in others (type_sim 1). This segmentation could imply different
usage patterns or needs within this cluster, highlighting opportunities for targeted service
enhancements or tailored marketing strategies to further engage and retain these clients.
Cluster 5
cluster_5_df = [Link]([Link] == 5)
df_summary = df_cleaned.describe()
cluster_5_summary = cluster_5_df.describe()
common_columns = ["summary", "life_time", "nb_transaction",
"sum_achat"]
df_summary_selected =
df_summary.select(common_columns).withColumn("source",
lit("original"))
cluster_5_summary_selected =
cluster_5_summary.select(common_columns).withColumn("source",
lit("cluster_5"))
comparison_summary =
df_summary_selected.union(cluster_5_summary_selected)
comparison_summary_pd = comparison_summary.toPandas()
cols = ['source'] + [col for col in comparison_summary_pd.columns if
col != 'source']
comparison_summary_pd = comparison_summary_pd[cols]
comparison_summary_pd =
comparison_summary_pd.sort_values(by=['summary', 'source'])
comparison_summary_pd
sum_achat
5 8819
0 141307
9 0.46104714
4 0.46104714
6 0.09403788259041486
1 0.020591187240199666
8 0.050701782
3 0.0
7 0.03577127354465978
2 0.027109827695412994
This cluster shows variability in their engagement levels, indicating that they may be exploring
the service with varying levels of commitment or budget constraints.
cluster_percentage
0 1.304003
1 0.034017
2 0.986506
3 0.011339
4 0.623653
5 0.725706
6 0.034017
7 0.362853
8 90.917338
9 4.365574
10 0.022678
11 0.612314
cluster_percentage
0 0.113392
1 0.136070
2 2.744075
3 0.124731
4 5.363420
5 0.124731
6 NaN
7 2.573988
8 0.045357
9 NaN
10 0.068035
11 0.090713
12 2.313187
13 NaN
14 0.022678
15 0.090713
16 0.045357
17 0.113392
18 0.124731
19 1.780247
20 0.090713
21 0.011339
22 NaN
23 2.392562
24 0.034017
25 0.634993
26 0.011339
27 0.011339
28 NaN
29 NaN
30 0.056696
31 1.394716
32 0.147409
33 0.578297
34 3.685225
35 0.181426
36 2.562649
37 0.068035
38 4.172809
39 0.725706
40 0.170087
41 0.192766
42 0.192766
43 NaN
44 34.210228
45 1.496768
46 0.521601
47 NaN
48 0.158748
49 0.079374
50 2.823449
51 27.236648
52 0.011339
53 0.056696
54 0.022678
55 0.113392
56 0.079374
class_client Distribution:
• Class 95: Previously represented 7% of the total population but is now completely
absent in the cluster, indicating a significant shift.
• Class 109: Decreased from 7.1% to 4.37% in the cluster, suggesting a slight decrease in
representation.
• Class 8: Maintained a high presence, decreasing slightly from 85.85% to 90.92%,
indicating consistency as the dominant class.
subclass_client Distribution:
• Subclass 106: Previously constituted 40.2% of the total population and now stands at
34.21% in the cluster, showing a decrease in representation but still prominent.
• Subclass 38: Decreased from 5.27% to 4.17% in the cluster, indicating a slight decrease
in representation.
• Subclass 3: Increased significantly from 0.02% to 1.5% in the cluster, showing a notable
shift in representation.
class_service Distribution:
• No notable changes were observed, indicating that the distribution of class_service
remains relatively consistent between the total population and the cluster.
type_sim Distribution:
• Type Sim 1: Previously made up 7.26% of the total population but is now completely
absent in the cluster, suggesting a significant shift away from this type within the cluster.
• Type Sim 2: Increased from 92.74% to 97.07% in the cluster, indicating a strong
association with this type within the cluster.
Conclusion
The most notable changes in the cluster include the complete absence of class_client 95
and type_sim 1, as well as the significant decrease in representation of subclass_client
106 and increase in subclass_client 3. These shifts highlight specific trends and
associations within the clustered group that could inform targeted strategies and interventions.
Understanding these changes can guide personalized approaches and optimizations tailored to
different client and service types within the cluster.
Cluster 5 Persona/Behavior:
Persona:
Cluster 5 comprises clients who exhibit moderate engagement levels with the service. They
show variability in their categorical profiles, indicating diverse preferences across different client
and service type categories.
Behavior:
These clients demonstrate a consistent pattern of moderate engagement with the service. They
are characterized by a balanced approach in their interaction, reflecting a mix of exploration and
commitment to the service offerings.