<jupyter_start><jupyter_text>Import Libraries<jupyter_code>#import linear algebra and data manipulation libraries


#import standard visualization libraries


#import machine learning model libraries




#library to split dataset

#library for metrics

#tools for hyperparameters search<jupyter_output><empty_output><jupyter_text>Import Data First of all to perform the analysis, we have to import the data:<jupyter_code>#import dataset


#display first 5 rows of dataset<jupyter_output><empty_output><jupyter_text>Data Exploration After we imported the dataset, we have to look at the total number of rows in the dataset and analyze the number of missing values.<jupyter_code># number of rows in dataset


#find percentage of missing values for each column<jupyter_output><empty_output><jupyter_text>Categorical columns exploration In the dataset we have both categorical and numerical columns. Let's look at the values of categorical columns first.<jupyter_code>cat_columns =                                                              #List of categorical columns

fig, axs = plt.subplots(3, 3, sharex=False, sharey=False, figsize=(20, 15))

counter = 0
for cat_column in cat_columns:
    value_counts = df[cat_column].value_counts()
    
    trace_x = counter // 3
    trace_y = counter % 3
    x_pos = np.arange(0, len(value_counts))
    
    axs[trace_x, trace_y].bar(x_pos, value_counts.values, tick_label = value_counts.index)
    
    axs[trace_x, trace_y].set_title(cat_column)
    
    for tick in axs[trace_x, trace_y].get_xticklabels():
        tick.set_rotation(90)
    
    counter += 1

plt.show()<jupyter_output><empty_output><jupyter_text>Numerical columns exploration Now let's look at the numerical columns' values. The most convenient way to look at the numerical values is plotting histograms.<jupyter_code>num_columns =                                                                   #List of Numerical Columns

fig, axs = plt.subplots(2, 3, sharex=False, sharey=False, figsize=(20, 15))

counter = 0
for num_column in num_columns:
    
    trace_x = counter // 3
    trace_y = counter % 3
    
    axs[trace_x, trace_y].hist(df[num_column])
    
    axs[trace_x, trace_y].set_title(num_column)
    
    counter += 1

plt.show()
# Explore variables 'pdays','campaign' & 'previous' in greater detail using describe function

#Variable Analysis

len (df[df['pdays'] > 400] ) / len(df) * 100<jupyter_output><empty_output><jupyter_text>'pdays' holds the number of days that passed by after the client was last contacted from a previous campaignLooking closer into 'pdays' data we can see that:* only 1.2% of values above 400. They are possibly outliers, so we should consider imputing something (possibly mean value) instead of these values.* -1 possibly means that the client wasn't contacted before or stands for missing data.Since we are not sure exactly what -1 means I suggest to drop this column, because -1 makes more than 50% of the values of the column. Percentage of 'campaign' values above 20:<jupyter_code>#Apply similar analysis to variable 'campaign'
#Apply similar analysis to variable 'previous'<jupyter_output><empty_output><jupyter_text>Analysis of the response column It is very important to look at the response column, which holds the information, which we are going to predict. In our case we should look at 'deposit' column and compare its values to other columns.  First of all we should look at the number of 'yes' and 'no' values in the response column 'deposit'.<jupyter_code>#Calculate value_counts for variable 'deposit'

value_counts = 

# Plot value_counts<jupyter_output><empty_output><jupyter_text>Let's see how 'deposit' column value varies depending on other categorical columns' values:<jupyter_code>#job and deposit
j_df = pd.DataFrame()

j_df['yes'] = df[df['deposit'] == 'yes']['job'].value_counts()
j_df['no'] = df[df['deposit'] == 'no']['job'].value_counts()

j_df.plot.bar(title = 'Job and deposit')
#marital status and deposit

#education and deposit

#type of contact and deposit<jupyter_output><empty_output><jupyter_text>Now let's look how numerical columns affect term deposit subscription.<jupyter_code>#balance and deposit

b_df = pd.DataFrame()
b_df['balance_yes'] = (df[df['deposit'] == 'yes'][['deposit','balance']].describe())['balance']
b_df['balance_no'] = (df[df['deposit'] == 'no'][['deposit','balance']].describe())['balance']

b_df
#plot
b_df.drop(['count', '25%', '50%', '75%']).plot.bar(title = 'Balance and deposit statistics')
#age and deposit


#plot

#number of contacts performed during this campaign ('campaign') and deposit

#plot
#number of contacts performed during previous campaign ('previous') and deposit

#plot<jupyter_output><empty_output><jupyter_text>Data Cleaning Before we will be able to apply machine learning techniques, we should prepare the dataset for processing:1. Convert columns with 'yes' and 'no' values to boolean columns;2. Convert categorical columns into dummy variables.<jupyter_code>def get_dummy_from_bool(row, column_name):
    ''' Returns 0 if value in column_name is no, returns 1 if value in column_name is yes'''
    #Type Code Here

def get_correct_values(row, column_name, threshold, df):
    ''' Returns mean value if value in column_name is above threshold'''
    #Type Code Here

def clean_data(df):
    '''
    INPUT
    df - pandas dataframe containing bank marketing campaign dataset
    
    OUTPUT
    df - cleaned dataset:
    1. columns with 'yes' and 'no' values are converted into boolean variables;
    2. categorical columns are converted into dummy variables;
    3. drop irrelevant columns.
    4. impute incorrect values
    '''
    
    cleaned_df = df.copy()
    
    #convert columns containing 'yes' and 'no' values to boolean variables and drop original columns
    #Type Code Here 
    
    #convert categorical columns to dummies
    cat_columns = ['job', 'marital', 'education', 'contact', 'month', 'poutcome']
    
    #Type Code Here
    
    #drop irrelevant columns
    cleaned_df = cleaned_df.drop(columns = ['pdays'])
    
    #impute incorrect values and drop original columns
    cleaned_df['campaign_cleaned'] = df.apply(lambda row: get_correct_values(row, 'campaign', 34, cleaned_df),axis=1)
    cleaned_df['previous_cleaned'] = df.apply(lambda row: get_correct_values(row, 'previous', 34, cleaned_df),axis=1)
    
    cleaned_df = cleaned_df.drop(columns = ['campaign', 'previous'])
    
    return cleaned_df
#clean the dataset
cleaned_df = clean_data(df)
cleaned_df.head()<jupyter_output><empty_output><jupyter_text>Machine Learning for prediction of campaign outcome  Classification model for the campaign outcome prediction Use cleaned datasets for prediction of campaign outcome with help of machine learning classification models. Implement [XGBoost](https://xgboost.readthedocs.io/en/latest/)__, which is one of the most common machine learning libraries for modelling.Also, find feature importances. Create X and y datasets for training the model and split into train and test datasets.<jupyter_code>#Split data into X and y 

TEST_SIZE = 0.3
RAND_STATE = 42
#Split data into train and test 
X_train, X_test, y_train, y_test =<jupyter_output><empty_output><jupyter_text>Train XGBoost classifier model:<jupyter_code>#train XGBoost model
xgb = #import XGBoost Classifier 


#fit model to X_train.y_train
\

#calculate and print scores for the model for top 15 features
y_train_preds = 
y_test_preds = 

print('XGB accuracy score for train: %.3f: test: %.3f' % (
        accuracy_score(y_train, y_train_preds),
        accuracy_score(y_test, y_test_preds)))<jupyter_output><empty_output><jupyter_text>Get the feature importances from the trained model:<jupyter_code>#get feature importances from the model
headers = ["name", "score"]
values = sorted(zip(X_train.columns, xgb.feature_importances_), key=lambda x: x[1] * -1)
xgb_feature_importances = pd.DataFrame(values, columns = headers)

#plot feature importances<jupyter_output><empty_output><jupyter_text>1. Find out account balance, which marketing campaign should focus on:<jupyter_code>df_new = cleaned_df.copy()

#introduce new column 'balance_buckets' to  ''
df_new['balance_buckets'] = pd.qcut(df_new['balance'], 50, labels=False, duplicates = 'drop')

#group by 'balance_buckets' and find average campaign outcome per balance bucket


#plot

df_new[df_new['balance_buckets'] == 34]['balance'].min()
#introduce new column 'age_buckets' to  ''
df_new['age_buckets'] = pd.qcut(df_new['age'], 20, labels=False, duplicates = 'drop')

#group by 'balance_buckets' and find average campaign outcome per balance bucket

#plot

df_new[df_new['age_buckets'] == 3]['age'].max()
df_new[df_new['age_buckets'] == 17]['age'].min()<jupyter_output><empty_output><jupyter_text>2. Find out appropriate number of contacts with the customer during campaign:<jupyter_code>#introduce new column 'age_buckets' to  ''
df_new['campaign_buckets'] = pd.qcut(df_new['campaign_cleaned'], 20, labels=False, duplicates = 'drop')

#group by 'balance_buckets' and find average campaign outcome per balance bucket

#plot average campaign outcome per bucket 

df_new[df_new['campaign_buckets'] == 2]['campaign_cleaned'].min()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09776143614145129, 'fraction_numerical': 0.00930031361522656, 'mean_word_length': 4.88295165394402, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 62, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '199603', 'license': 'MIT', 'n_tokens_mistral': 2908, 'n_tokens_neox': 2761, 'n_words': 930, 'path': 'Bank Marketing/Template.ipynb', 'repo_name': 'abhisngh/Data-Science', 'size': '9247'}