input: Write a function to perform sentiment analysis on product reviews using natural language processing techniques like tokenization and n-grams. The function should generate features for sentiment analysis and use a classification model to assign sentiments to the reviews. The function should return a classification report of the predictions. If no reviews are provided, the function should return an empty string.
  def sentiment_analysis(reviews, sentiments):
      import numpy as np
      import pandas as pd
      import nltk
      from nltk.tokenize import word_tokenize
      import matplotlib.pyplot as plt
      from nltk.corpus import stopwords
      from nltk.stem import WordNetLemmatizer 
      from sklearn.feature_extraction.text import CountVectorizer
      from sklearn.model_selection import train_test_split
      from sklearn.naive_bayes import MultinomialNB
      from sklearn.metrics import classification_report
  
      if len(reviews) == 0:
          return ""
  
      data = pd.DataFrame({'review': reviews, 'sentiment': sentiments})
  
      data['tokenised'] = data['review'].apply(word_tokenize)
      stop_words = set(stopwords.words('english'))
      data['filtered'] = data['tokenised'].apply(lambda x: [val for val in x if val not in stop_words])
      wordnet_lemmatizer = WordNetLemmatizer()
      data['normalised'] = data['filtered'].apply(lambda x: [wordnet_lemmatizer.lemmatize(val) for val in x])
      cv = CountVectorizer()
      data['features'] = cv.fit_transform(data['normalised'].astype('str')).toarray()
      X = data['features']
      y = data['sentiment']
      X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
      model = MultinomialNB(alpha=0.1)
      model.fit(X_train, y_train)
      predictions = model.predict(X_test)
      report = classification_report(y_test, predictions)
      return report
  
  assert sentiment_analysis([], []) == ""
  assert sentiment_analysis(["The product is fantastic", "I didn't like the product at all"], ['positive', 'negative']) == "              precision    recall  f1-score   support\n\n   negative       1.00      1.00      1.00         1\n   positive       1.00      1.00      1.00         1\n\n    accuracy                           1.00         2\n   macro avg       1.00      1.00      1.00         2\nweighted avg       1.00      1.00      1.00         2\n"
  assert sentiment_analysis(["The product is great", "The product is terrible"], ['positive', 'negative']) == "              precision    recall  f1-score   support\n\n   negative       1.00      1.00      1.00         1\n   positive       1.00      1.00      1.00         1\n\n    accuracy                           1.00         2\n   macro avg       1.00      1.00      1.00         2\nweighted avg       1.00      1.00      1.00         2\n"
  assert sentiment_analysis(["The product is excellent"], ['positive']) == "              precision    recall  f1-score   support\n\n   positive       1.00      1.00      1.00         1\n\n    accuracy                           1.00         1\n   macro avg       1.00      1.00      1.00         1\nweighted avg       1.00      1.00      1.00         1\n"
  assert sentiment_analysis(["I hated this product", "I loved this product"], ['negative', 'positive']) == "              precision    recall  f1-score   support\n\n   negative       1.00      1.00      1.00         1\n   positive       1.00      1.00      1.00         1\n\n    accuracy                           1.00         2\n   macro avg       1.00      1.00      1.00         2\nweighted avg       1.00      1.00      1.00         2\n"
output: def sentiment_analysis(reviews, sentiments):
      import numpy as np
      import pandas as pd
      import nltk
      from nltk.tokenize import word_tokenize
      from nltk.corpus import stopwords
      from nltk.stem import WordNetLemmatizer 
      from sklearn.feature_extraction.text import CountVectorizer
      from sklearn.model_selection import train_test_split
      from sklearn.naive_bayes import MultinomialNB
      from sklearn.metrics import classification_report
  
      if len(reviews) == 0:
          return ""
  
      data = pd.DataFrame({'review': reviews, 'sentiment': sentiments})
  
      data['tokenised'] = data['review'].apply(word_tokenize)
      stop_words = set(stopwords.words('english'))
      data['filtered'] = data['tokenised'].apply(lambda x: [val for val in x if val not in stop_words])
      wordnet_lemmatizer = WordNetLemmatizer()
      data['normalised'] = data['filtered'].apply(lambda x: [wordnet_lemmatizer.lemmatize(val) for val in x])
      cv = CountVectorizer()
      data['features'] = cv.fit_transform(data['normalised'].astype('str')).toarray()
      X = data['features']
      y = data['sentiment']
      X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
      model = MultinomialNB(alpha=0.1)
      model.fit(X_train, y_train)
      predictions = model.predict(X_test)
      report = classification_report(y_test, predictions)
      return report