<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
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from nltk.tokenize import word_tokenize
import numpy as np
import pandas as pd
import pickle
from pprint import pprint
import re
import sys
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.metrics import f1_score, accuracy_score, precision_score, recall_score
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.metrics import classification_report
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.multiclass import OneVsRestClassifier
from sklearn.multioutput import MultiOutputClassifier
from sklearn.metrics import precision_recall_fscore_support
from sklearn.pipeline import Pipeline
from sklearn.svm import LinearSVC
from sqlalchemy import create_engine
import time
import warnings
warnings.filterwarnings('ignore')
# load data from database
engine = create_engine('sqlite:///DisasterMessages.db')
df = pd.read_sql_table("DisasterMessages", con=engine)
df.head()
X = df['message']
Y = df.iloc[:, 4:]
df['related'].value_counts()
Y.shape<jupyter_output><empty_output><jupyter_text>2. Write a tokenization function to process your text data<jupyter_code>def tokenize(text):
    
    # normalize text
    text = re.sub(r"[^\w]", " ", text.lower())
    
    # tokenize text
    words = word_tokenize(text)
    
    # remove stopwords
    stopwords_ = stopwords.words("english")
    words = [word for word in words if word not in stopwords_]
    
    # extract root form of words
    words = [WordNetLemmatizer().lemmatize(word, pos='v') for word in words]
    
    return words<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(OneVsRestClassifier(LinearSVC())))
])<jupyter_output><empty_output><jupyter_text>4. Train pipeline- Split data into train and test sets- Train pipeline<jupyter_code>X_test, X_train, Y_test, Y_train = train_test_split(X, Y)
# train classifier
pipeline.fit(X_train, Y_train)

# predict on test data
Y_pred = pipeline.predict(X_test)
Y_pred<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 col in range(36):
    print(Y_test.columns[col])
    print(classification_report(Y_test.iloc[:,col], Y_pred[:,col]))
    print('-----------------------------------------------------')

print('Accuracy: {}'.format(np.mean(Y_test.values == Y_pred)))<jupyter_output>Accuracy: 0.9465409871268888<jupyter_text>6. Improve your modelUse grid search to find better parameters.<jupyter_code>parameters = {'vect__ngram_range': ((1, 1), (1, 2)),
                  'vect__max_df': (0.75, 1.0)
                  }
model = GridSearchCV(estimator=pipeline, param_grid=parameters, cv=5)

model<jupyter_output><empty_output><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>model.fit(X_train, Y_train)
Y_pred = model.predict(X_test)
for col in range(36):
    print(Y_test.columns[col])
    print(classification_report(Y_test.iloc[:,col], Y_pred[:,col]))
    print('-----------------------------------------------------')
print('Accuracy: {}'.format(np.mean(Y_test.values == Y_pred)))<jupyter_output>Accuracy: 0.9482193514845331<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>pipeline = Pipeline([
    ('vect', CountVectorizer(tokenizer=tokenize)),
    ('tfidf', TfidfTransformer()),
    ('clf', MultiOutputClassifier(AdaBoostClassifier()))])
# train classifier
pipeline.fit(X_train, Y_train)

# predict on test data
Y_pred = pipeline.predict(X_test)
for col in range(36):
    print(Y_test.columns[col])
    print(classification_report(Y_test.iloc[:,col], Y_pred[:,col]))
    print('-----------------------------------------------------')
print('Accuracy: {}'.format(np.mean(Y_test.values == Y_pred)))<jupyter_output>Accuracy: 0.9437889216650278<jupyter_text>9. Export your model as a pickle file<jupyter_code>filename = 'classifier.sav'
pickle.dump(model, open(filename, 'wb'))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12675286832999455, 'fraction_numerical': 0.014751411400473502, 'mean_word_length': 4.930885529157667, '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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '641544', 'license': 'FTL', 'n_tokens_mistral': 1729, 'n_tokens_neox': 1663, 'n_words': 460, 'path': 'ML Pipeline Preparation.ipynb', 'repo_name': 'shabrown/Disaster-Response-Pipeline', 'size': '5491'}