<jupyter_start><jupyter_text>ML Pipeline PreparationFollow the instructions below to help you create your ML pipeline. 1. Import libraries and load data from database.- Import Python libraries- Load dataset from database with [`read_sql_table`](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_sql_table.html)- Define feature and target variables X and Y<jupyter_code># import libraries
import re
import pandas as pd
import nltk
nltk.download(['punkt', 'wordnet'])
from sqlalchemy import create_engine
from sklearn.multioutput import MultiOutputClassifier
from sklearn.ensemble import AdaBoostClassifier,BaggingClassifier
from sklearn.neural_network import MLPClassifier
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer,HashingVectorizer,TfidfVectorizer
from sklearn.multioutput import MultiOutputClassifier
from sklearn.metrics import classification_report,accuracy_score
import pickle
# load data from database
engine = create_engine('sqlite:///cleanDatabase.db')
df = pd.read_sql_table('cleanData',engine)
df['related']=df['related'].replace(2,0)
X = df[['message']].values
Y = df.loc[:,'related':'direct_report'].values<jupyter_output><empty_output><jupyter_text>2. Write a tokenization function to process your text data<jupyter_code>def tokenize(text):
    regex_express='http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
    detected_urls = re.findall(regex_express, text)
    for url in detected_urls:
        text =text.replace(url,'url_link')
        
    regex_express='^[a-zA-Z0-9]'
    detected_spc = re.findall(regex_express, text)
    for spc in detected_spc:
        text =text.replace(spc,' ')
        
    tokens = nltk.tokenize.word_tokenize(text)
    lemmatizer =  nltk.stem.WordNetLemmatizer() 
    
    clean_tokens = []
    for tok in tokens:
        clean_tok =lemmatizer.lemmatize(tok).lower().strip()
        clean_tokens.append(clean_tok)
        
    return clean_tokens<jupyter_output><empty_output><jupyter_text>3. Build a machine learning pipelineThis machine pipeline should take in the `message` column as input and output classification results on the other 36 categories in the dataset. You may find the [MultiOutputClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.multioutput.MultiOutputClassifier.html) helpful for predicting multiple target variables.<jupyter_code>pipeline = Pipeline([
        ('vect', CountVectorizer(tokenizer=tokenize)),
        ('tfidf', TfidfTransformer()),
        ('clf', MultiOutputClassifier(BaggingClassifier()))
    ])<jupyter_output><empty_output><jupyter_text>4. Train pipeline- Split data into train and test sets- Train pipeline<jupyter_code>X_train, X_test, Y_train, Y_test = train_test_split(X, Y,test_size=0.15, random_state=42)
pipeline.fit(X.ravel(), Y)
y_pred=pipeline.predict(X_test.ravel())
ypred=pd.DataFrame(y_pred,columns=df.loc[:,'related':'direct_report'].columns)
yreal=pd.DataFrame(Y_test,columns=df.loc[:,'related':'direct_report'].columns)<jupyter_output><empty_output><jupyter_text>5. Test your modelReport the f1 score, precision and recall for each output category of the dataset. You can do this by iterating through the columns and calling sklearn's `classification_report` on each.<jupyter_code>for coll in ypred.columns:
    print('-----'+coll+'-----')
    print(classification_report(yreal[coll], ypred[coll]))
    print('Accuracy score : {}'.format(accuracy_score(yreal[coll], ypred[coll])))<jupyter_output>-----related-----
              precision    recall  f1-score   support

           0       0.99      0.95      0.97       972
           1       0.98      1.00      0.99      2960

   micro avg       0.98      0.98      0.98      3932
   macro avg       0.99      0.97      0.98      3932
weighted avg       0.98      0.98      0.98      3932

Accuracy score : 0.9847405900305188
-----request-----
              precision    recall  f1-score   support

           0       0.97      1.00      0.98      3283
           1       0.99      0.85      0.91       649

   micro avg       0.97      0.97      0.97      3932
   macro avg       0.98      0.92      0.95      3932
weighted avg       0.97      0.97      0.97      3932

Accuracy score : 0.9735503560528993
-----offer-----
              precision    recall  f1-score   support

           0       1.00      1.00      1.00      3910
           1       1.00      0.64      0.78        22

   micro avg       1.00      1.00      1.00      3932
   m[...]<jupyter_text>6. Improve your modelUse grid search to find better parameters.<jupyter_code>parameters = {
    'clf__estimator__max_features':[2,6,10,100]
}
cv = GridSearchCV(pipeline, parameters).fit(X_train.ravel(), Y_train)
print(cv.best_score_)    
print(cv.best_params_)<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\sklearn\model_selection\_split.py:2053: FutureWarning: You should specify a value for 'cv' instead of relying on the default value. The default value will change from 3 to 5 in version 0.22.
  warnings.warn(CV_WARNING, FutureWarning)<jupyter_text>7. Test your modelShow the accuracy, precision, and recall of the tuned model.  Since this project focuses on code quality, process, and  pipelines, there is no minimum performance metric needed to pass. However, make sure to fine tune your models for accuracy, precision and recall to make your project stand out - especially for your portfolio!<jupyter_code>pipeline = Pipeline([
        ('vect', CountVectorizer(tokenizer=tokenize)),
        ('tfidf', TfidfTransformer()),
        ('clf', MultiOutputClassifier(BaggingClassifier(max_features=2)))
    ])
X_train, X_test, Y_train, Y_test = train_test_split(X, Y,test_size=0.15, random_state=42)
pipeline.fit(X.ravel(), Y)
y_pred=pipeline.predict(X_test.ravel())
ypred=pd.DataFrame(y_pred,columns=df.loc[:,'related':'direct_report'].columns)
yreal=pd.DataFrame(Y_test,columns=df.loc[:,'related':'direct_report'].columns)
for coll in ypred.columns:
    print('-----'+coll+'-----')
    print(classification_report(yreal[coll], ypred[coll]))
    print('Accuracy score : {}'.format(accuracy_score(yreal[coll], ypred[coll])))<jupyter_output>-----related-----
              precision    recall  f1-score   support

           0       0.00      0.00      0.00       972
           1       0.75      1.00      0.86      2960

   micro avg       0.75      0.75      0.75      3932
   macro avg       0.38      0.50      0.43      3932
weighted avg       0.57      0.75      0.65      3932

Accuracy score : 0.7527975584944049
-----request-----
              precision    recall  f1-score   support

           0       0.83      1.00      0.91      3283
           1       0.00      0.00      0.00       649

   micro avg       0.83      0.83      0.83      3932
   macro avg       0.42      0.50      0.46      3932
weighted avg       0.70      0.83      0.76      3932

Accuracy score : 0.8349440488301119
-----offer-----
              precision    recall  f1-score   support

           0       0.99      1.00      1.00      3910
           1       0.00      0.00      0.00        22

   micro avg       0.99      0.99      0.99      3932
   m[...]<jupyter_text>8. Try improving your model further. Here are a few ideas:* try other machine learning algorithms* add other features besides the TF-IDF<jupyter_code>features=[TfidfVectorizer(tokenizer=tokenize)]
parameters = {
    'clf__estimator__learning_rate':[0.1,0.5,1]
}

for faet in features:
    pipeline = Pipeline([
    ('vect', faet),
    ('clf', MultiOutputClassifier(AdaBoostClassifier()))
    ])
    cv = GridSearchCV(pipeline, parameters).fit(X_train.ravel(), Y_train)
    print(cv.best_score_)    
    print(cv.best_params_)<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\sklearn\model_selection\_split.py:2053: FutureWarning: You should specify a value for 'cv' instead of relying on the default value. The default value will change from 3 to 5 in version 0.22.
  warnings.warn(CV_WARNING, FutureWarning)<jupyter_text>9. Export your model as a pickle file<jupyter_code>pickle.dump(pipeline, open('model_to_use.pkl', 'wb'))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11041841505814651, 'fraction_numerical': 0.05766694640930344, 'mean_word_length': 2.9256470588235293, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 27, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '582328', 'license': 'MIT', 'n_tokens_mistral': 2915, 'n_tokens_neox': 2686, 'n_words': 655, 'path': 'Disaster response pipeline notebooks/ML Pipeline Preparation.ipynb', 'repo_name': 'Savadogo/Disaster-responses-pipelines', 'size': '8341'}