<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 os
# import libraries
from sqlalchemy import create_engine
import pandas as pd
# nltk
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
# scikit-learn
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.multioutput import MultiOutputClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
# pickle 
import pickle
# load data from database
path = os.path.abspath(os.getcwd())
#print(path)
#tmp_str = 'sqlite:///{}'.format(path + database_filepath[7:])
engine = create_engine('sqlite:///{}'.format(path+'/DisasterResponse.db'))
df = pd.read_sql('SELECT * FROM {}'.format('DisasterResponse'), engine)
X = df.message
Y = df.drop(columns=['id','message','original','genre'])
category_names = Y.columns
X.head(10)<jupyter_output><empty_output><jupyter_text>2. Write a tokenization function to process your text data<jupyter_code>def tokenize(text):
    # tokenize text
    tokens = word_tokenize(text)
    
    # initiate lemmatizer
    lemmatizer = WordNetLemmatizer()

    # iterate through each token
    clean_tokens = []
    for tok in tokens:
        
        # lemmatize, normalize case, and remove leading/trailing white space
        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(LogisticRegression(random_state=42, max_iter = 500)))
                         ])<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, random_state=42)
pipeline.fit(X_train, y_train)<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># predict on test data
y_pred = pipeline.predict(X_test)
for idx, col in enumerate(category_names):
    print('For category {}:'.format(col))
    print(classification_report(y_test[col], y_pred[:,idx]))<jupyter_output>For category related:
              precision    recall  f1-score   support

           0       0.70      0.45      0.55      1563
           1       0.84      0.94      0.89      4944
           2       0.00      0.00      0.00        47

    accuracy                           0.82      6554
   macro avg       0.51      0.46      0.48      6554
weighted avg       0.80      0.82      0.80      6554

For category request:
              precision    recall  f1-score   support

           0       0.91      0.98      0.95      5443
           1       0.84      0.55      0.67      1111

    accuracy                           0.91      6554
   macro avg       0.88      0.77      0.81      6554
weighted avg       0.90      0.91      0.90      6554

For category offer:
              precision    recall  f1-score   support

           0       0.99      1.00      1.00      6521
           1       0.00      0.00      0.00        33

    accuracy                           0.99      6554
   macro a[...]<jupyter_text>6. Improve your modelUse grid search to find better parameters.<jupyter_code># specify parameters for grid search
parameters = {'vect__ngram_range' : [(1,1), (1,2)],
              'tfidf__use_idf': [True, False]
             }


# create grid search object
pipeline_cv = GridSearchCV(pipeline, parameters, n_jobs=-1, cv=3, verbose=1)
pipeline_cv.fit(X_train, y_train)
print(pipeline_cv.best_params_)<jupyter_output>{'tfidf__use_idf': True, 'vect__ngram_range': (1, 1)}<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># predict on test data
y_pred = pipeline_cv.predict(X_test)
for idx,col in enumerate(category_names):
    print('For category {}:'.format(col))
    print(classification_report(y_test[col], y_pred[:,idx]))<jupyter_output>For category related:
              precision    recall  f1-score   support

           0       0.70      0.45      0.55      1563
           1       0.84      0.94      0.89      4944
           2       0.00      0.00      0.00        47

    accuracy                           0.82      6554
   macro avg       0.51      0.46      0.48      6554
weighted avg       0.80      0.82      0.80      6554

For category request:
              precision    recall  f1-score   support

           0       0.91      0.98      0.95      5443
           1       0.84      0.55      0.67      1111

    accuracy                           0.91      6554
   macro avg       0.88      0.77      0.81      6554
weighted avg       0.90      0.91      0.90      6554

For category offer:
              precision    recall  f1-score   support

           0       0.99      1.00      1.00      6521
           1       0.00      0.00      0.00        33

    accuracy                           0.99      6554
   macro a[...]<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># done via trial and error above<jupyter_output><empty_output><jupyter_text>9. Export your model as a pickle file<jupyter_code>model_filepath = './models/classifier_notebook.pkl'
outfile = open(model_filepath,'wb')
pickle.dump(pipeline, outfile)
outfile.close()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08059873344847437, 'fraction_numerical': 0.05339666090961428, 'mean_word_length': 2.4641076769690926, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 34, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '312910', 'license': 'FTL', 'n_tokens_mistral': 2242, 'n_tokens_neox': 2078, 'n_words': 602, 'path': 'ML Pipeline Preparation.ipynb', 'repo_name': 'larpal/DisasterResponse', 'size': '6948'}