input: Write a function to perform sentiment analysis on product reviews using natural language processing techniques. The function should tokenize the reviews, remove stop words, normalize the words, generate features using CountVectorizer, and train a Multinomial Naive Bayes classification model to assign sentiments to the reviews. The function should return the classification report of the model's predictions.
  
  assert perform_sentiment_analysis(pd.DataFrame({'review': ["Great product!", "Awful experience."], 'sentiment': ["Positive", "Negative"]})) == classification_report(y_test, predictions)
output: def perform_sentiment_analysis(df):
      from sklearn.feature_extraction.text import CountVectorizer
      from sklearn.naive_bayes import MultinomialNB
      from sklearn.model_selection import train_test_split
      from sklearn.metrics import classification_report
      from nltk.corpus import stopwords
      from nltk.tokenize import word_tokenize
      from nltk.stem import WordNetLemmatizer
      import string
  
      stop_words = set(stopwords.words('english'))
      lemmatizer = WordNetLemmatizer()
  
      def preprocess(text):
          tokens = word_tokenize(text.lower())
          tokens = [lemmatizer.lemmatize(word) for word in tokens if word.isalpha() and word not in stop_words]
          return ' '.join(tokens)
  
      df['review'] = df['review'].apply(preprocess)
      X_train, X_test, y_train, y_test = train_test_split(df['review'], df['sentiment'], test_size=0.2, random_state=42)
  
      vectorizer = CountVectorizer()
      X_train_vec = vectorizer.fit_transform(X_train)
      X_test_vec = vectorizer.transform(X_test)
  
      model = MultinomialNB()
      model.fit(X_train_vec, y_train)
      predictions = model.predict(X_test_vec)
  
      return classification_report(y_test, predictions)