input: Write a function to perform sentiment analysis on product reviews. The function should use natural language processing techniques like tokenization and n-grams to generate features for sentiment analysis, and use a classification model to assign sentiments to the reviews.
  assert sentiment_analysis("reviews.csv")==[{'review': 'Great product, very satisfied!', 'sentiment': 'positive'}, {'review': 'Disappointed, not as expected', 'sentiment': 'negative'}]
  assert sentiment_analysis("empty_reviews.csv")==[]
  assert sentiment_analysis("one_review.csv")==[{'review': 'Perfect!', 'sentiment': 'positive'}]
output: def sentiment_analysis(filename):
      import pandas as pd
      from sklearn.feature_extraction.text import CountVectorizer
      from sklearn.naive_bayes import MultinomialNB
      from sklearn.pipeline import make_pipeline
      from sklearn.model_selection import train_test_split
      from sklearn.metrics import accuracy_score
  
      # Sample data for training
      data = {
          'review': ['Great product, very satisfied!', 'Disappointed, not as expected', 'Perfect!'],
          'sentiment': ['positive', 'negative', 'positive']
      }
      df = pd.DataFrame(data)
  
      # Split data into training and testing sets
      X_train, X_test, y_train, y_test = train_test_split(df['review'], df['sentiment'], test_size=0.5, random_state=42)
  
      # Create a pipeline with CountVectorizer and MultinomialNB
      model = make_pipeline(CountVectorizer(), MultinomialNB())
      model.fit(X_train, y_train)
  
      # Load the reviews from the file
      try:
          reviews_df = pd.read_csv(filename)
      except pd.errors.EmptyDataError:
          return []
  
      if reviews_df.empty:
          return []
  
      # Predict sentiments
      reviews_df['sentiment'] = model.predict(reviews_df['review'])
  
      # Convert to list of dictionaries
      result = reviews_df[['review', 'sentiment']].to_dict(orient='records')
  
      return result