please, let the output lemmatized file to order the keywords based on their counter in descending order. 

import csv
import re
import os
import nltk
import pandas as pd
from collections import defaultdict, Counter
from nltk.stem import WordNetLemmatizer
from gensim.models import KeyedVectors, FastText
from sklearn.cluster import KMeans
import numpy as np

# ------------------------------#
#           Setup               #
# ------------------------------#

# Download NLTK data files (only need to run once)
# nltk.download('wordnet')
# nltk.download('omw-1.4')

# Initialize the lemmatizer
lemmatizer = WordNetLemmatizer()

# Function to load the appropriate word embedding model
def load_model(model_type, model_path):
    if model_type == 'word2vec':
        print("Loading Word2Vec model. This may take a few minutes...")
        model = KeyedVectors.load_word2vec_format(model_path, binary=True)
        print("Word2Vec model loaded successfully.")
    elif model_type == 'glove':
        print("Loading GloVe model. This may take a few minutes...")
        model = {}
        with open(model_path, 'r', encoding='utf-8') as f:
            for line in f:
                values = line.split()
                word = values[0]
                vector = np.asarray(values[1:], dtype='float32')
                model[word] = vector
        print("GloVe model loaded successfully.")
    elif model_type == 'fasttext':
        print("Loading FastText model. This may take a few minutes...")
        model = FastText.load_fasttext_format(model_path)
        print("FastText model loaded successfully.")
    else:
        raise ValueError(f"Unsupported model type: {model_type}")
    return model

# Function to get the vector for a word/phrase
def get_word_vector(word, model, model_type):
    if model_type in ['word2vec', 'fasttext']:
        if word in model:
            return model[word]
    elif model_type == 'glove':
        if word in model:
            return model[word]
    # Handle multi-word phrases by averaging their word vectors
    words = word.split()
    vectors = []
    for w in words:
        if model_type in ['word2vec', 'fasttext'] and w in model:
            vectors.append(model[w])
        elif model_type == 'glove' and w in model:
            vectors.append(model[w])
    if vectors:
        return np.mean(vectors, axis=0)
    else:
        return None

# Function to lemmatize a keyword
def lemmatize_keyword(keyword):
    return lemmatizer.lemmatize(keyword.lower())

# Function to process the CSV file and lemmatize keywords
def lemmatize_keywords(input_file, output_file):
    # Read the CSV file using pandas
    df = pd.read_csv(input_file)
    
    # Assuming the CSV has columns: Object, Adjective, Activity, Place, Feeling
    categories = defaultdict(list)
    keyword_counts = Counter()
    
    # Iterate through each row and category to extract and lemmatize keywords
    for index, row in df.iterrows():
        for category in ['Object', 'Adjective', 'Activity', 'Place', 'Feeling']:
            keywords_str = row.get(category, '')
            if pd.isna(keywords_str):
                continue
            # Split keywords by comma and strip whitespace
            extracted = [kw.strip() for kw in keywords_str.split(',')]
            lemmatized = [lemmatize_keyword(kw) for kw in extracted if kw]
            categories[category].extend(lemmatized)
            keyword_counts.update(lemmatized)
    
    # Write the lemmatized keywords and their counts to the output CSV
    with open(output_file, 'w', newline='', encoding='utf-8') as outfile:
        writer = csv.writer(outfile)
        writer.writerow(['Category', 'Lemmatized Keyword', 'Count'])
        for category, keywords in categories.items():
            keyword_counter = Counter(keywords)
            for keyword, count in keyword_counter.items():
                writer.writerow([category, keyword, count])
    
    print(f"\nLemmatization completed. Lemmatized keywords and counts saved to '{output_file}'.")
    return categories, keyword_counts, output_file

# Function to cluster infrequent keywords (count <= threshold)
def cluster_infrequent_keywords(keywords, keyword_counts, model, model_type, num_clusters=5):
    vectors = []
    valid_keywords = []
    for keyword in keywords:
        vector = get_word_vector(keyword, model, model_type)
        if vector is not None:
            vectors.append(vector)
            valid_keywords.append(keyword)
    
    if not vectors:
        print("No valid vectors found for clustering.")
        return {}
    
    vectors = np.array(vectors)
    
    # Perform K-Means clustering
    kmeans = KMeans(n_clusters=num_clusters, random_state=42)
    labels = kmeans.fit_predict(vectors)
    
    # Organize keywords by clusters
    clusters = defaultdict(list)
    for label, keyword in zip(labels, valid_keywords):
        clusters[label].append(keyword)
    
    # Select the most frequent keyword in each cluster as the representative
    representative_keywords = {}
    for label, words in clusters.items():
        most_frequent = max(words, key=lambda w: keyword_counts[w])
        representative_keywords[label] = most_frequent
    
    # Create a mapping from keyword to representative
    keyword_to_representative = {}
    for label, words in clusters.items():
        rep = representative_keywords[label]
        for word in words:
            keyword_to_representative[word] = rep
    
    return keyword_to_representative

# Function to perform clustering on categorized keywords with frequency threshold
def perform_clustering_with_threshold(lemmatized_categories, lemmatized_keyword_counts, model, model_type, threshold=5, num_clusters=5):
    clustered_categories = {}
    
    for category, keywords in lemmatized_categories.items():
        print(f"\nProcessing category: {category}")
        # Separate frequent and infrequent keywords
        frequent_keywords = [kw for kw in set(keywords) if lemmatized_keyword_counts[kw] > threshold]
        infrequent_keywords = [kw for kw in set(keywords) if lemmatized_keyword_counts[kw] <= threshold]
        
        print(f"Number of frequent keywords (> {threshold}): {len(frequent_keywords)}")
        print(f"Number of infrequent keywords (<= {threshold}): {len(infrequent_keywords)}")
        
        # Keep frequent keywords as-is
        clustered = {kw: kw for kw in frequent_keywords}
        
        # Cluster infrequent keywords and map them to their representatives
        if infrequent_keywords:
            mapping = cluster_infrequent_keywords(infrequent_keywords, lemmatized_keyword_counts, model, model_type, num_clusters)
            clustered.update(mapping)
            print(f"Number of cluster representatives: {len(set(mapping.values()))}")
        else:
            print("No infrequent keywords to cluster.")
        
        clustered_categories[category] = clustered
    
    return clustered_categories

# Function to replace keywords in the original CSV with clustered keywords
def replace_keywords(input_file, clustered_categories, output_file):
    # Read the original CSV
    df = pd.read_csv(input_file)
    
    # Function to replace keywords based on category mappings
    def replace_row_keywords(row):
        new_keywords = []
        for category in ['Object', 'Adjective', 'Activity', 'Place', 'Feeling']:
            keywords_str = row.get(category, '')
            if pd.isna(keywords_str):
                continue
            keywords = [kw.strip() for kw in keywords_str.split(',')]
            # Lemmatize keywords
            lemmatized = [lemmatize_keyword(kw) for kw in keywords if kw]
            # Replace with clustered keywords
            clustered = [clustered_categories[category].get(kw, kw) for kw in lemmatized]
            new_keywords.append(f"{category}: " + ', '.join(clustered))
        return '; '.join(new_keywords)
    
    # Apply the replacement to each row
    df['Clustered Keywords'] = df.apply(replace_row_keywords, axis=1)
    
    # Save the updated CSV
    df.to_csv(output_file, index=False)
    print(f"\nReplacement completed. Clustered keywords saved to '{output_file}'.")

# ------------------------------#
#             Main               #
# ------------------------------#

def main():
    # File paths (replace these with your actual file paths)
    original_input_file = '/home/danilo/Projects/IR_MD/cleaned_/home/danilo/Projects/IR_MD/TESTING/categorized_keywords_cleaned_graffe_better_prompt_KeyExt_Qwen2VL7B_20240912-131955_.csv'
    lemmatized_output_file = '/home/danilo/Projects/IR_MD/TESTING/_tempcategorized_keywords_lemmatized.csv'
    clustered_output_file = '/home/danilo/Projects/IR_MD/TESTING/_tempcategorized_keywords_clustered.csv'
    
    # Clustering parameters
    model_type = 'glove'  # Choose from 'word2vec', 'glove', 'fasttext'
    model_path = '/home/danilo/Projects/IR_MD/models/glove.6B.300d.txt'  # Path to the model file
    frequency_threshold = 5  # Keywords with count >5 are kept as-is
    num_clusters = 5  # Number of clusters for infrequent keywords
    
    # Step 1-3: Lemmatization
    lemmatized_categories, lemmatized_keyword_counts, lemmatized_file = lemmatize_keywords(original_input_file, lemmatized_output_file)
    
    # Step 4: Load the appropriate model
    model = load_model(model_type, model_path)
    
    # Step 5: Perform clustering on infrequent keywords
    clustered_categories = perform_clustering_with_threshold(lemmatized_categories, lemmatized_keyword_counts, model, model_type, threshold=frequency_threshold, num_clusters=num_clusters)
    
    # Step 6: Replace keywords in the original CSV with clustered keywords
    replace_keywords(original_input_file, clustered_categories, clustered_output_file)

if __name__ == "__main__":
    main()