<jupyter_start><jupyter_text>RFM Analysis- RFM (Recency, Frequency, Monetary) analysis =     + A marketing technique used to determine which customers are the best ones + RFM examines     + **Recency**: how recently a customer has purchased (recency)    + **Frequency**: how often they purchase (frequency)    + **Monetary**: how much the customer spends (monetary)- Customers are assigned a ranking score of 1,2,3, or 4 (4 = highest) for each RFM parameter<jupyter_code>df = pd.read_csv('./datasets/sales_data.csv')
df = df[['CUSTOMERNAME','ORDERNUMBER','ORDERDATE','SALES']]

df.head(3)<jupyter_output><empty_output><jupyter_text>Recency- Recency = how recently a customer has purchased a product- Algorithm: **recency(x) = recent date(x) - most recent date**    + **recent date(x)**: the date of the last order of customer x    + **most recent date**: the most recent order in the dataset    - smaller recency = higher score<jupyter_code># Convert Date to Datetime type 
df['ORDERDATE'] = pd.to_datetime(df['ORDERDATE'])

# Algorithms
recent_dates_df = df[['CUSTOMERNAME', 'ORDERDATE']] \
    .groupby(['CUSTOMERNAME'])['ORDERDATE'] \
    .max()

most_recent_date= df['ORDERDATE'].max()

recency = recent_dates_df.apply(
    lambda x: (most_recent_date-x).days)
recency.head(3)<jupyter_output><empty_output><jupyter_text>Frequency- Frequency = A measure of how often a customer purchases a product- Algorithm    + Calculate the total number of times a customer has made an order<jupyter_code>############ Note: We have to group 2 times #########
# 1 customer make multiple order
# 1 order has multiple products
frequency = df[['CUSTOMERNAME', 'ORDERNUMBER']] \
    .groupby(['CUSTOMERNAME', 'ORDERNUMBER']) \
    .size()

frequency.head(10)
frequency = frequency \
    .groupby(['CUSTOMERNAME']) \
    .size()

frequency.head(10)<jupyter_output><empty_output><jupyter_text>Monetary- measure of how much the customer spent<jupyter_code>monetary = df[['CUSTOMERNAME', 'SALES']] \
    .groupby(['CUSTOMERNAME'])['SALES'] \
    .sum()

monetary.head()<jupyter_output><empty_output><jupyter_text>Summary<jupyter_code>rfm_table = pd.DataFrame()
rfm_table['recency'] = recency
rfm_table['frequency'] = frequency
rfm_table['monetary'] = monetary

rfm_table.head()<jupyter_output><empty_output><jupyter_text>Assign scores<jupyter_code>def assign_score(x, quantile_values, attribute):
    '''
    recency: lower = higher score
    Frequency and Monetary: higher = higher score

    Input: 
        attribute = 'recency', 'frequency', or 'monetary'
    '''
    # recency
    if attribute == 'recency':
        if x <= quantile_values.loc[0.25,attribute]:
            return 4
        elif x >= quantile_values.loc[0.25,attribute] and x <= quantile_values.loc[0.5,attribute]:
            return 3
        elif x >= quantile_values.loc[0.5,attribute] and x <= quantile_values.loc[0.75,attribute]:
            return 2
        else:
            return 1

    # frequency and frequency
    elif attribute == 'frequency' or attribute == 'monetary':
        if x <= quantile_values.loc[0.25,attribute]:
            return 1
        elif x >= quantile_values.loc[0.25,attribute] and x <= quantile_values.loc[0.5,attribute]:
            return 2
        elif x >= quantile_values.loc[0.5,attribute] and x <= quantile_values.loc[0.75,attribute]:
            return 3
        else:
            return 4


# Caculate quantiles
quantile_df = rfm_table.quantile(q=[0.25,0.5,0.75])

# Assign scores using quantiles
rfm_table['r_score'] = rfm_table['recency'] \
    .apply(assign_score, args=(quantile_df,'recency'))
rfm_table['f_score'] = rfm_table['frequency'] \
    .apply(assign_score, args=(quantile_df,'frequency'))
rfm_table['m_score'] = rfm_table['monetary'] \
    .apply(assign_score, args=(quantile_df,'monetary'))

# Summarize score
rfm_table['rfm_score'] = rfm_table['r_score'] + rfm_table['f_score'] + rfm_table['m_score']

# Sort
rfm_table = rfm_table[['r_score', 'f_score', 'm_score', 'rfm_score']] \
    .sort_values(by='rfm_score',ascending=False)
rfm_table.head(10)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14034229828850855, 'fraction_numerical': 0.014180929095354523, 'mean_word_length': 4.368766404199475, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 29, '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': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '606962', 'license': 'Unlicense', 'n_tokens_mistral': 1406, 'n_tokens_neox': 1356, 'n_words': 312, 'path': 'Problems/RFM_Business_Analysis/rfm_analysis.ipynb', 'repo_name': 'dangkhoa1992/Advanced-Machine-Learning-Specialization', 'size': '4090'}