help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • Blog
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
sentiment-analysis
/
scripts
RSK World
sentiment-analysis
Sentiment Analysis Dataset - NLP + Text Classification + Machine Learning
scripts
  • analyze_sentiment.py20.9 KB
  • generate_data.py20.8 KB
  • preprocess_data.py21.9 KB
  • requirements.txt2.2 KB
  • train_model.py16.2 KB
  • visualize_data.py24.7 KB
visualize_data.pypreprocess.pyvisualize.pygenerate_data.py
scripts/visualize_data.py
Raw Download
Find: Go to:
#!/usr/bin/env python3
"""
================================================================================
 * Sentiment Analysis Dataset - Data Visualization Script
 * 
 * Project: Sentiment Analysis Dataset
 * Description: Generate visualizations and statistics for sentiment analysis
 *              datasets including distribution charts, word clouds, and more.
 * Category: Text Data
 * Difficulty: Intermediate
 * 
 * Author: Molla Samser (Founder)
 * Designer & Tester: Rima Khatun
 * Website: https://rskworld.in
 * Email: help@rskworld.in | support@rskworld.in
 * Phone: +91 93305 39277
 * 
 * © 2026 RSK World - Free Programming Resources & Source Code
 * All rights reserved.
================================================================================

Usage:
    python visualize_data.py --input ./data/sentiment_data.csv
    python visualize_data.py --input ./data/sentiment_data.json --output ./charts/
    python visualize_data.py --input ./data/ --all-charts --interactive
"""

import argparse
import csv
import json
import os
import re
from typing import List, Dict, Optional
from collections import Counter
from datetime import datetime

# Try to import visualization libraries
try:
    import matplotlib
    matplotlib.use('Agg')  # Non-interactive backend
    import matplotlib.pyplot as plt
    MATPLOTLIB_AVAILABLE = True
except ImportError:
    MATPLOTLIB_AVAILABLE = False

try:
    from wordcloud import WordCloud
    WORDCLOUD_AVAILABLE = True
except ImportError:
    WORDCLOUD_AVAILABLE = False

try:
    import numpy as np
    NUMPY_AVAILABLE = True
except ImportError:
    NUMPY_AVAILABLE = False


# ============================================
# Data Loading
# ============================================

def load_data(filepath: str) -> List[Dict]:
    """Load data from CSV or JSON file."""
    ext = os.path.splitext(filepath)[1].lower()
    
    if ext == '.csv':
        data = []
        with open(filepath, 'r', encoding='utf-8') as f:
            lines = [line for line in f if not line.strip().startswith('#')]
            reader = csv.DictReader(lines)
            for row in reader:
                data.append(row)
        return data
    
    elif ext == '.json':
        with open(filepath, 'r', encoding='utf-8') as f:
            content = json.load(f)
            if isinstance(content, dict) and 'data' in content:
                return content['data']
            return content
    
    raise ValueError(f"Unsupported file format: {ext}")


# ============================================
# Statistics Functions
# ============================================

def calculate_statistics(data: List[Dict]) -> Dict:
    """Calculate comprehensive statistics for the dataset."""
    total = len(data)
    
    # Sentiment distribution
    sentiments = [d.get('sentiment', 'unknown') for d in data]
    sentiment_counts = Counter(sentiments)
    
    # Source distribution
    sources = [d.get('source', 'unknown') for d in data]
    source_counts = Counter(sources)
    
    # Text length statistics
    text_lengths = [len(d.get('text', '')) for d in data]
    word_counts = [len(d.get('text', '').split()) for d in data]
    
    avg_text_length = sum(text_lengths) / total if total > 0 else 0
    avg_word_count = sum(word_counts) / total if total > 0 else 0
    min_text_length = min(text_lengths) if text_lengths else 0
    max_text_length = max(text_lengths) if text_lengths else 0
    
    # Date range
    dates = [d.get('date', '') for d in data if d.get('date')]
    
    return {
        "total_samples": total,
        "sentiment_distribution": dict(sentiment_counts),
        "source_distribution": dict(source_counts),
        "text_statistics": {
            "avg_length": round(avg_text_length, 2),
            "avg_word_count": round(avg_word_count, 2),
            "min_length": min_text_length,
            "max_length": max_text_length
        },
        "date_range": {
            "earliest": min(dates) if dates else None,
            "latest": max(dates) if dates else None
        }
    }


def get_top_words(data: List[Dict], sentiment: Optional[str] = None, top_n: int = 50) -> List[tuple]:
    """Get most frequent words, optionally filtered by sentiment."""
    words = []
    
    for sample in data:
        if sentiment and sample.get('sentiment') != sentiment:
            continue
        
        text = sample.get('text', '').lower()
        text = re.sub(r'[^\w\s]', ' ', text)
        words.extend(text.split())
    
    # Remove common stopwords
    stopwords = {
        'the', 'a', 'an', 'is', 'it', 'to', 'and', 'of', 'in', 'for', 'on',
        'with', 'as', 'was', 'that', 'this', 'i', 'my', 'but', 'have', 'has',
        'be', 'are', 'been', 'will', 'would', 'could', 'should', 'from', 'at',
        'or', 'by', 'so', 'if', 'just', 'what', 'all', 'were', 'we', 'they'
    }
    
    filtered_words = [w for w in words if w not in stopwords and len(w) > 2]
    word_counts = Counter(filtered_words)
    
    return word_counts.most_common(top_n)


# ============================================
# Visualization Functions
# ============================================

def set_style():
    """Set matplotlib style for RSK World branding."""
    if not MATPLOTLIB_AVAILABLE:
        return
    
    plt.style.use('dark_background')
    plt.rcParams.update({
        'figure.facecolor': '#0d0d0d',
        'axes.facecolor': '#1a1a1a',
        'axes.edgecolor': '#333333',
        'axes.labelcolor': '#ffffff',
        'text.color': '#ffffff',
        'xtick.color': '#b3b3b3',
        'ytick.color': '#b3b3b3',
        'grid.color': '#333333',
        'font.family': 'sans-serif',
        'font.size': 10
    })


def plot_sentiment_distribution(data: List[Dict], output_path: str):
    """Create sentiment distribution pie chart."""
    if not MATPLOTLIB_AVAILABLE:
        print("⚠ Matplotlib not installed. Skipping chart generation.")
        return
    
    set_style()
    
    sentiments = [d.get('sentiment', 'unknown') for d in data]
    counts = Counter(sentiments)
    
    labels = list(counts.keys())
    values = list(counts.values())
    
    # RSK World color scheme
    colors = {
        'positive': '#28a745',
        'neutral': '#ffc107',
        'negative': '#dc3545',
        'unknown': '#6c757d'
    }
    chart_colors = [colors.get(l, '#6c757d') for l in labels]
    
    fig, ax = plt.subplots(figsize=(10, 8), facecolor='#0d0d0d')
    
    wedges, texts, autotexts = ax.pie(
        values,
        labels=labels,
        autopct='%1.1f%%',
        colors=chart_colors,
        explode=[0.02] * len(labels),
        shadow=True,
        startangle=90
    )
    
    # Style the text
    for text in texts:
        text.set_color('white')
        text.set_fontsize(12)
    for autotext in autotexts:
        autotext.set_color('white')
        autotext.set_fontweight('bold')
    
    ax.set_title('Sentiment Distribution\nRSK World - Sentiment Analysis Dataset', 
                 fontsize=14, fontweight='bold', color='white', pad=20)
    
    # Add legend
    ax.legend(wedges, [f'{l.capitalize()}: {v}' for l, v in zip(labels, values)],
              loc='lower right', fontsize=10)
    
    plt.tight_layout()
    plt.savefig(output_path, dpi=150, facecolor='#0d0d0d', edgecolor='none', bbox_inches='tight')
    plt.close()
    
    print(f"✓ Saved sentiment distribution chart to {output_path}")


def plot_source_distribution(data: List[Dict], output_path: str):
    """Create source distribution bar chart."""
    if not MATPLOTLIB_AVAILABLE:
        return
    
    set_style()
    
    sources = [d.get('source', 'unknown') for d in data]
    counts = Counter(sources)
    
    labels = list(counts.keys())
    values = list(counts.values())
    
    fig, ax = plt.subplots(figsize=(12, 6), facecolor='#0d0d0d')
    
    # Create gradient-like colors
    colors = ['#dc3545', '#e35d6a', '#e8838e', '#eda9b2', '#f2ced6'][:len(labels)]
    
    bars = ax.bar(labels, values, color=colors, edgecolor='#333333', linewidth=1)
    
    # Add value labels on bars
    for bar, value in zip(bars, values):
        height = bar.get_height()
        ax.annotate(f'{value}',
                    xy=(bar.get_x() + bar.get_width() / 2, height),
                    xytext=(0, 3),
                    textcoords="offset points",
                    ha='center', va='bottom',
                    color='white', fontweight='bold')
    
    ax.set_xlabel('Data Source', fontsize=12, color='white')
    ax.set_ylabel('Number of Samples', fontsize=12, color='white')
    ax.set_title('Data Source Distribution\nRSK World - Sentiment Analysis Dataset',
                 fontsize=14, fontweight='bold', color='white', pad=20)
    
    plt.xticks(rotation=45, ha='right')
    plt.tight_layout()
    plt.savefig(output_path, dpi=150, facecolor='#0d0d0d', edgecolor='none', bbox_inches='tight')
    plt.close()
    
    print(f"✓ Saved source distribution chart to {output_path}")


def plot_text_length_histogram(data: List[Dict], output_path: str):
    """Create text length histogram."""
    if not MATPLOTLIB_AVAILABLE:
        return
    
    set_style()
    
    # Separate by sentiment
    lengths_by_sentiment = {
        'positive': [],
        'neutral': [],
        'negative': []
    }
    
    for sample in data:
        sentiment = sample.get('sentiment', 'neutral')
        length = len(sample.get('text', '').split())
        if sentiment in lengths_by_sentiment:
            lengths_by_sentiment[sentiment].append(length)
    
    fig, ax = plt.subplots(figsize=(12, 6), facecolor='#0d0d0d')
    
    colors = {'positive': '#28a745', 'neutral': '#ffc107', 'negative': '#dc3545'}
    
    for sentiment, lengths in lengths_by_sentiment.items():
        if lengths:
            ax.hist(lengths, bins=20, alpha=0.6, label=sentiment.capitalize(),
                   color=colors[sentiment], edgecolor='white', linewidth=0.5)
    
    ax.set_xlabel('Word Count', fontsize=12, color='white')
    ax.set_ylabel('Frequency', fontsize=12, color='white')
    ax.set_title('Text Length Distribution by Sentiment\nRSK World - Sentiment Analysis Dataset',
                 fontsize=14, fontweight='bold', color='white', pad=20)
    ax.legend(loc='upper right')
    
    plt.tight_layout()
    plt.savefig(output_path, dpi=150, facecolor='#0d0d0d', edgecolor='none', bbox_inches='tight')
    plt.close()
    
    print(f"✓ Saved text length histogram to {output_path}")


def plot_word_frequency(data: List[Dict], output_path: str, top_n: int = 20):
    """Create word frequency bar chart."""
    if not MATPLOTLIB_AVAILABLE:
        return
    
    set_style()
    
    top_words = get_top_words(data, top_n=top_n)
    
    words = [w for w, c in top_words]
    counts = [c for w, c in top_words]
    
    fig, ax = plt.subplots(figsize=(14, 8), facecolor='#0d0d0d')
    
    # Create horizontal bar chart
    y_pos = range(len(words))
    bars = ax.barh(y_pos, counts, color='#dc3545', edgecolor='#333333', linewidth=1)
    
    ax.set_yticks(y_pos)
    ax.set_yticklabels(words)
    ax.invert_yaxis()
    
    # Add value labels
    for i, (bar, count) in enumerate(zip(bars, counts)):
        ax.annotate(f'{count}',
                    xy=(bar.get_width(), bar.get_y() + bar.get_height()/2),
                    xytext=(5, 0),
                    textcoords="offset points",
                    ha='left', va='center',
                    color='white', fontsize=9)
    
    ax.set_xlabel('Frequency', fontsize=12, color='white')
    ax.set_title(f'Top {top_n} Most Frequent Words\nRSK World - Sentiment Analysis Dataset',
                 fontsize=14, fontweight='bold', color='white', pad=20)
    
    plt.tight_layout()
    plt.savefig(output_path, dpi=150, facecolor='#0d0d0d', edgecolor='none', bbox_inches='tight')
    plt.close()
    
    print(f"✓ Saved word frequency chart to {output_path}")


def generate_wordcloud(data: List[Dict], output_path: str, sentiment: Optional[str] = None):
    """Generate word cloud."""
    if not WORDCLOUD_AVAILABLE:
        print("⚠ WordCloud not installed. Skipping word cloud generation.")
        return
    
    # Collect text
    texts = []
    for sample in data:
        if sentiment and sample.get('sentiment') != sentiment:
            continue
        texts.append(sample.get('text', ''))
    
    text = ' '.join(texts)
    
    # Color based on sentiment
    if sentiment == 'positive':
        colormap = 'Greens'
    elif sentiment == 'negative':
        colormap = 'Reds'
    else:
        colormap = 'Blues'
    
    wordcloud = WordCloud(
        width=1200,
        height=600,
        background_color='#0d0d0d',
        colormap=colormap,
        max_words=100,
        min_font_size=10,
        max_font_size=150
    ).generate(text)
    
    if MATPLOTLIB_AVAILABLE:
        fig, ax = plt.subplots(figsize=(12, 6), facecolor='#0d0d0d')
        ax.imshow(wordcloud, interpolation='bilinear')
        ax.axis('off')
        
        title = f'Word Cloud - {sentiment.capitalize() if sentiment else "All"} Sentiment'
        ax.set_title(f'{title}\nRSK World - Sentiment Analysis Dataset',
                     fontsize=14, fontweight='bold', color='white', pad=20)
        
        plt.tight_layout()
        plt.savefig(output_path, dpi=150, facecolor='#0d0d0d', edgecolor='none', bbox_inches='tight')
        plt.close()
    else:
        wordcloud.to_file(output_path)
    
    print(f"✓ Saved word cloud to {output_path}")


def generate_html_report(data: List[Dict], stats: Dict, output_path: str, chart_dir: str):
    """Generate an HTML report with embedded statistics."""
    
    html_content = f"""<!DOCTYPE html>
<!--
================================================================================
 * Sentiment Analysis Dataset - Statistics Report
 * 
 * Author: Molla Samser (Founder)
 * Designer & Tester: Rima Khatun
 * Website: https://rskworld.in
 * © 2026 RSK World - Free Programming Resources & Source Code
================================================================================
-->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dataset Statistics Report - RSK World</title>
    <style>
        * {{ margin: 0; padding: 0; box-sizing: border-box; }}
        body {{
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #1a0a0a 0%, #0d0d0d 50%, #0a0a1a 100%);
            color: #ffffff;
            min-height: 100vh;
            padding: 40px;
        }}
        .container {{ max-width: 1200px; margin: 0 auto; }}
        .header {{
            text-align: center;
            margin-bottom: 40px;
            padding: 30px;
            background: rgba(220, 53, 69, 0.1);
            border-radius: 15px;
            border: 1px solid rgba(220, 53, 69, 0.3);
        }}
        .header h1 {{ color: #dc3545; font-size: 2.5em; margin-bottom: 10px; }}
        .header p {{ color: #b3b3b3; }}
        .stats-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin-bottom: 40px;
        }}
        .stat-card {{
            background: #1e1e1e;
            padding: 25px;
            border-radius: 12px;
            border: 1px solid #333;
            text-align: center;
        }}
        .stat-card h3 {{ color: #dc3545; font-size: 2em; margin-bottom: 10px; }}
        .stat-card p {{ color: #b3b3b3; }}
        .section {{
            background: #1e1e1e;
            padding: 30px;
            border-radius: 12px;
            border: 1px solid #333;
            margin-bottom: 30px;
        }}
        .section h2 {{
            color: #dc3545;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 1px solid #333;
        }}
        .chart-container {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
            gap: 20px;
        }}
        .chart {{ background: #0d0d0d; padding: 15px; border-radius: 8px; }}
        .chart img {{ width: 100%; height: auto; border-radius: 5px; }}
        table {{
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
        }}
        th, td {{
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #333;
        }}
        th {{ color: #dc3545; background: #0d0d0d; }}
        .footer {{
            text-align: center;
            padding: 20px;
            color: #6c757d;
            margin-top: 40px;
        }}
        .footer a {{ color: #dc3545; text-decoration: none; }}
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📊 Dataset Statistics Report</h1>
            <p>Sentiment Analysis Dataset - RSK World</p>
            <p>Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
        </div>
        
        <div class="stats-grid">
            <div class="stat-card">
                <h3>{stats['total_samples']:,}</h3>
                <p>Total Samples</p>
            </div>
            <div class="stat-card">
                <h3>{stats['sentiment_distribution'].get('positive', 0):,}</h3>
                <p>Positive Samples</p>
            </div>
            <div class="stat-card">
                <h3>{stats['sentiment_distribution'].get('neutral', 0):,}</h3>
                <p>Neutral Samples</p>
            </div>
            <div class="stat-card">
                <h3>{stats['sentiment_distribution'].get('negative', 0):,}</h3>
                <p>Negative Samples</p>
            </div>
        </div>
        
        <div class="section">
            <h2>📈 Text Statistics</h2>
            <table>
                <tr><th>Metric</th><th>Value</th></tr>
                <tr><td>Average Text Length</td><td>{stats['text_statistics']['avg_length']:.1f} characters</td></tr>
                <tr><td>Average Word Count</td><td>{stats['text_statistics']['avg_word_count']:.1f} words</td></tr>
                <tr><td>Min Text Length</td><td>{stats['text_statistics']['min_length']} characters</td></tr>
                <tr><td>Max Text Length</td><td>{stats['text_statistics']['max_length']} characters</td></tr>
            </table>
        </div>
        
        <div class="section">
            <h2>📊 Visualizations</h2>
            <div class="chart-container">
                <div class="chart">
                    <img src="sentiment_distribution.png" alt="Sentiment Distribution">
                </div>
                <div class="chart">
                    <img src="source_distribution.png" alt="Source Distribution">
                </div>
                <div class="chart">
                    <img src="text_length_histogram.png" alt="Text Length Histogram">
                </div>
                <div class="chart">
                    <img src="word_frequency.png" alt="Word Frequency">
                </div>
            </div>
        </div>
        
        <div class="footer">
            <p>© 2026 RSK World - Free Programming Resources & Source Code</p>
            <p>Author: <strong>Molla Samser</strong> | Designer: <strong>Rima Khatun</strong></p>
            <p><a href="https://rskworld.in">rskworld.in</a> | help@rskworld.in</p>
        </div>
    </div>
</body>
</html>
"""
    
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write(html_content)
    
    print(f"✓ Generated HTML report: {output_path}")


# ============================================
# Main Function
# ============================================

def main():
    parser = argparse.ArgumentParser(
        description="Data Visualization Tool - RSK World",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  python visualize_data.py --input ../data/sentiment_data.csv
  python visualize_data.py --input ../data/sentiment_data.json --output ./charts/
  python visualize_data.py --input ../data/sentiment_data.csv --all-charts

Author: Molla Samser (Founder) - RSK World
Website: https://rskworld.in
        """
    )
    
    parser.add_argument(
        "--input", "-i",
        type=str,
        required=True,
        help="Input file path (CSV or JSON)"
    )
    
    parser.add_argument(
        "--output", "-o",
        type=str,
        default="./charts",
        help="Output directory for charts (default: ./charts)"
    )
    
    parser.add_argument(
        "--all-charts", "-a",
        action="store_true",
        help="Generate all available charts"
    )
    
    parser.add_argument(
        "--stats-only", "-s",
        action="store_true",
        help="Only print statistics, no charts"
    )
    
    parser.add_argument(
        "--html-report", "-r",
        action="store_true",
        help="Generate HTML report"
    )
    
    args = parser.parse_args()
    
    print("""
╔══════════════════════════════════════════════════════════════════╗
║         RSK World - Data Visualization Tool                      ║
║                                                                  ║
║  Author: Molla Samser (Founder)                                  ║
║  Website: https://rskworld.in                                    ║
║  © 2026 RSK World - Free Programming Resources & Source Code     ║
╚══════════════════════════════════════════════════════════════════╝
    """)
    
    # Check for required libraries
    print("Available features:")
    print(f"  {'✓' if MATPLOTLIB_AVAILABLE else '✗'} Charts (matplotlib)")
    print(f"  {'✓' if WORDCLOUD_AVAILABLE else '✗'} Word Clouds (wordcloud)")
    print()
    
    # Load data
    print(f"Loading data from {args.input}...")
    data = load_data(args.input)
    print(f"Loaded {len(data)} samples")
    print()
    
    # Calculate statistics
    stats = calculate_statistics(data)
    
    # Print statistics
    print("=" * 50)
    print("DATASET STATISTICS")
    print("=" * 50)
    print(f"Total samples: {stats['total_samples']:,}")
    print()
    print("Sentiment Distribution:")
    for sentiment, count in stats['sentiment_distribution'].items():
        pct = count / stats['total_samples'] * 100
        print(f"  {sentiment.capitalize()}: {count:,} ({pct:.1f}%)")
    print()
    print("Source Distribution:")
    for source, count in stats['source_distribution'].items():
        print(f"  {source}: {count:,}")
    print()
    print("Text Statistics:")
    print(f"  Average length: {stats['text_statistics']['avg_length']:.1f} chars")
    print(f"  Average words: {stats['text_statistics']['avg_word_count']:.1f}")
    print()
    
    if args.stats_only:
        return
    
    # Create output directory
    os.makedirs(args.output, exist_ok=True)
    
    # Generate charts
    if MATPLOTLIB_AVAILABLE:
        print("\nGenerating charts...")
        
        plot_sentiment_distribution(
            data, 
            os.path.join(args.output, 'sentiment_distribution.png')
        )
        
        plot_source_distribution(
            data,
            os.path.join(args.output, 'source_distribution.png')
        )
        
        plot_text_length_histogram(
            data,
            os.path.join(args.output, 'text_length_histogram.png')
        )
        
        plot_word_frequency(
            data,
            os.path.join(args.output, 'word_frequency.png')
        )
        
        if args.all_charts and WORDCLOUD_AVAILABLE:
            print("\nGenerating word clouds...")
            generate_wordcloud(data, os.path.join(args.output, 'wordcloud_all.png'))
            generate_wordcloud(data, os.path.join(args.output, 'wordcloud_positive.png'), 'positive')
            generate_wordcloud(data, os.path.join(args.output, 'wordcloud_negative.png'), 'negative')
    
    # Generate HTML report
    if args.html_report:
        generate_html_report(
            data, stats,
            os.path.join(args.output, 'report.html'),
            args.output
        )
    
    print()
    print("✓ Visualization complete!")
    print(f"  Output directory: {args.output}")
    print()


if __name__ == "__main__":
    main()

733 lines•24.7 KB
python
scripts/generate_data.py
Raw Download
Find: Go to:
#!/usr/bin/env python3
"""
================================================================================
 * Sentiment Analysis Dataset - Data Generator Script
 * 
 * Project: Sentiment Analysis Dataset
 * Description: Generate synthetic sentiment analysis data with customizable
 *              parameters for training NLP models.
 * Category: Text Data
 * Difficulty: Intermediate
 * 
 * Author: Molla Samser (Founder)
 * Designer & Tester: Rima Khatun
 * Website: https://rskworld.in
 * Email: help@rskworld.in | support@rskworld.in
 * Phone: +91 93305 39277
 * 
 * © 2026 RSK World - Free Programming Resources & Source Code
 * All rights reserved.
================================================================================

Usage:
    python generate_data.py --samples 1000 --output ./data/generated_data.csv
    python generate_data.py --samples 5000 --format json --balanced
    python generate_data.py --samples 10000 --include-metadata --split 0.8
"""

import argparse
import csv
import json
import random
import os
import sys
from datetime import datetime, timedelta
from typing import List, Dict, Tuple, Optional
import hashlib

# ============================================
# Sentiment Templates and Vocabulary
# ============================================

POSITIVE_TEMPLATES = [
    "Absolutely love this {product}! It exceeded all my expectations.",
    "Best {product} I've ever purchased. Highly recommend to everyone!",
    "Amazing quality and fast delivery. The {product} is perfect!",
    "Five stars! This {product} changed my life for the better.",
    "Impressed beyond words! The {product} is truly exceptional.",
    "Great value for money! The {product} performs really well.",
    "Outstanding {product}! Can't imagine going back to what I used before.",
    "Perfect in every way! The {product} exceeded my expectations.",
    "Fantastic {product}! My friends were so impressed they ordered one too.",
    "Simply phenomenal! This {product} has improved my daily routine.",
    "Wow! Just wow! This {product} is worth every penny.",
    "Life-changing {product}! Already recommended to all my colleagues.",
    "Brilliant {product}! Such attention to detail and quality.",
    "The {product} arrived quickly and works flawlessly. Love it!",
    "Exceeded expectations! The {product} quality is superb.",
    "I can't believe how good this {product} is! My whole family loves it.",
    "This {product} is everything I hoped for and more!",
    "Super impressed with the {product} quality. Ordering more as gifts!",
    "The {product} looks even better in person than in photos!",
    "Absolutely thrilled with my {product} purchase. 10/10!",
    "This {product} is a game changer! So glad I bought it.",
    "Remarkable {product}! The craftsmanship is top-notch.",
    "Couldn't be happier with this {product}. Exactly what I needed!",
    "The {product} works like a charm! Highly satisfied customer here.",
    "Premium quality {product} at an affordable price. Amazing deal!",
]

NEUTRAL_TEMPLATES = [
    "The {product} is okay. Nothing special but does the job.",
    "Received the {product} today. It looks decent, will test more.",
    "Standard {product}, meets basic requirements. Fair price.",
    "The {product} works as expected. Nothing extraordinary.",
    "Average {product}. No complaints but no praises either.",
    "Mixed feelings about this {product}. Some features are good.",
    "The {product} arrived on time. Performance is as described.",
    "It's an average {product}. Does what it's supposed to do.",
    "Got what I paid for with this {product}. Standard experience.",
    "The {product} is functional but unremarkable. Average overall.",
    "Decent {product} for the price. Might buy again in future.",
    "The {product} seems okay. Will need more time to evaluate.",
    "Nothing stood out positively or negatively about this {product}.",
    "Adequate {product} for basic needs. Won't wow you.",
    "The {product} is middle of the road. Serves its purpose.",
    "First impressions of the {product} are neither good nor bad.",
    "The {product} packaging was adequate. Performance is standard.",
    "Just unboxed the {product}. Quality meets basic requirements.",
    "The {product} does the job. Not exceptional but functional.",
    "Standard shipping, standard {product}, standard everything.",
    "The {product} is what you'd expect at this price point.",
    "Neither excited nor disappointed with this {product}.",
    "The {product} performs adequately. Nothing more, nothing less.",
    "Received my {product} yesterday. It's just okay overall.",
    "The {product} doesn't stand out from competition in any way.",
]

NEGATIVE_TEMPLATES = [
    "Terrible experience! The {product} arrived damaged.",
    "Worst {product} I've ever purchased. Complete waste of money!",
    "So disappointed with this {product}. Description was misleading.",
    "Horrible {product}! Customer support was unhelpful.",
    "Don't waste your money on this {product}! Poor quality.",
    "Completely broken {product} on arrival! Demanding refund.",
    "Avoid this {product} at all costs! Stopped working after a week.",
    "Extremely disappointed with the {product}. False advertising!",
    "Total rip-off! The {product} quality is nowhere near promised.",
    "Save your money! This {product} is a complete joke.",
    "Absolutely terrible {product}! Broke within days of purchase.",
    "Regret buying this {product}. Reviews were misleading.",
    "Complete disaster! {product} arrived late and damaged.",
    "Horrible quality control! The {product} had multiple defects.",
    "Never again! This {product} company has lost all credibility.",
    "Disappointed beyond words with this {product}. Reality was different.",
    "The {product} is garbage! Poor materials and horrible design.",
    "Worst customer service ever! My {product} issue is still unresolved.",
    "This {product} is a scam! Falls apart after first use.",
    "Feeling completely cheated by this {product} purchase.",
    "The {product} failed immediately. Support is non-existent.",
    "Massive letdown! The {product} photos were misleading.",
    "Demanded a refund for this {product}. Absolute nightmare!",
    "The {product} is defective. Company refuses to acknowledge issues.",
    "Stay away from this {product}! Waste of time and money.",
]

PRODUCTS = [
    "product", "item", "purchase", "device", "gadget", "tool", "equipment",
    "accessory", "appliance", "machine", "system", "kit", "set", "package",
    "solution", "unit", "model", "version", "edition", "series"
]

SOURCES = ["Product Review", "Customer Feedback", "Social Media", "Survey Response", "Email Feedback"]
SOURCE_ICONS = {
    "Product Review": "shopping-cart",
    "Customer Feedback": "comment",
    "Social Media": "twitter",
    "Survey Response": "poll",
    "Email Feedback": "envelope"
}

# Additional vocabulary for variation
POSITIVE_ADJECTIVES = ["amazing", "excellent", "fantastic", "wonderful", "brilliant", "superb", "outstanding", "perfect", "incredible", "remarkable"]
NEGATIVE_ADJECTIVES = ["terrible", "horrible", "awful", "dreadful", "disappointing", "frustrating", "unacceptable", "poor", "defective", "useless"]
NEUTRAL_ADJECTIVES = ["average", "standard", "typical", "ordinary", "decent", "fair", "acceptable", "moderate", "passable", "adequate"]

# ============================================
# Data Generation Functions
# ============================================

def generate_text(sentiment: str, variation: bool = True) -> str:
    """Generate a sentiment text based on templates."""
    if sentiment == "positive":
        template = random.choice(POSITIVE_TEMPLATES)
    elif sentiment == "negative":
        template = random.choice(NEGATIVE_TEMPLATES)
    else:
        template = random.choice(NEUTRAL_TEMPLATES)
    
    product = random.choice(PRODUCTS)
    text = template.format(product=product)
    
    if variation:
        # Add some random variations
        if random.random() > 0.7:
            if sentiment == "positive":
                adj = random.choice(POSITIVE_ADJECTIVES)
                text = f"{adj.capitalize()}! " + text
            elif sentiment == "negative":
                adj = random.choice(NEGATIVE_ADJECTIVES)
                text = f"{adj.capitalize()}. " + text
    
    return text


def generate_date(start_date: datetime, end_date: datetime) -> str:
    """Generate a random date between start and end."""
    delta = end_date - start_date
    random_days = random.randint(0, delta.days)
    date = start_date + timedelta(days=random_days)
    return date.strftime("%Y-%m-%d")


def generate_id(text: str, index: int) -> str:
    """Generate a unique ID for a data point."""
    hash_input = f"{text}{index}{datetime.now().isoformat()}"
    return hashlib.md5(hash_input.encode()).hexdigest()[:12]


def generate_sample(
    index: int,
    sentiment: str,
    start_date: datetime,
    end_date: datetime,
    include_metadata: bool = False
) -> Dict:
    """Generate a single data sample."""
    text = generate_text(sentiment)
    source = random.choice(SOURCES)
    date = generate_date(start_date, end_date)
    
    sample = {
        "id": index,
        "text": text,
        "sentiment": sentiment,
        "source": source,
        "date": date
    }
    
    if include_metadata:
        sample["metadata"] = {
            "text_length": len(text),
            "word_count": len(text.split()),
            "source_icon": SOURCE_ICONS.get(source, "file"),
            "generated_at": datetime.now().isoformat(),
            "hash": generate_id(text, index)
        }
    
    return sample


def generate_dataset(
    num_samples: int,
    balanced: bool = True,
    sentiment_ratio: Optional[Dict[str, float]] = None,
    include_metadata: bool = False,
    start_date: Optional[datetime] = None,
    end_date: Optional[datetime] = None
) -> List[Dict]:
    """Generate a complete dataset."""
    
    if start_date is None:
        start_date = datetime(2026, 1, 1)
    if end_date is None:
        end_date = datetime(2026, 12, 31)
    
    if balanced:
        ratio = {"positive": 1/3, "neutral": 1/3, "negative": 1/3}
    elif sentiment_ratio:
        ratio = sentiment_ratio
    else:
        # Slight imbalance towards positive
        ratio = {"positive": 0.4, "neutral": 0.3, "negative": 0.3}
    
    dataset = []
    sentiments = []
    
    for sentiment, proportion in ratio.items():
        count = int(num_samples * proportion)
        sentiments.extend([sentiment] * count)
    
    # Add remaining samples to balance
    while len(sentiments) < num_samples:
        sentiments.append(random.choice(["positive", "neutral", "negative"]))
    
    random.shuffle(sentiments)
    
    for i, sentiment in enumerate(sentiments, 1):
        sample = generate_sample(i, sentiment, start_date, end_date, include_metadata)
        dataset.append(sample)
        
        # Progress indicator
        if i % 1000 == 0:
            print(f"Generated {i}/{num_samples} samples...")
    
    return dataset


def split_dataset(
    dataset: List[Dict],
    train_ratio: float = 0.8
) -> Tuple[List[Dict], List[Dict]]:
    """Split dataset into training and test sets."""
    random.shuffle(dataset)
    split_index = int(len(dataset) * train_ratio)
    return dataset[:split_index], dataset[split_index:]


# ============================================
# Export Functions
# ============================================

def export_csv(dataset: List[Dict], filepath: str, include_header_comment: bool = True):
    """Export dataset to CSV format."""
    os.makedirs(os.path.dirname(filepath) if os.path.dirname(filepath) else '.', exist_ok=True)
    
    with open(filepath, 'w', newline='', encoding='utf-8') as f:
        if include_header_comment:
            f.write("""# ================================================================================
# Sentiment Analysis Dataset - Generated Data
# 
# Project: Sentiment Analysis Dataset
# Generated by: RSK World Data Generator
# Website: https://rskworld.in
# 
# Author: Molla Samser (Founder)
# Designer & Tester: Rima Khatun
# Email: help@rskworld.in | support@rskworld.in
# 
# © 2026 RSK World - Free Programming Resources & Source Code
# ================================================================================

""")
        
        # Determine fields
        fields = ["id", "text", "sentiment", "source", "date"]
        if dataset and "metadata" in dataset[0]:
            fields.extend(["text_length", "word_count"])
        
        writer = csv.DictWriter(f, fieldnames=fields)
        writer.writeheader()
        
        for sample in dataset:
            row = {k: sample.get(k) for k in ["id", "text", "sentiment", "source", "date"]}
            if "metadata" in sample:
                row["text_length"] = sample["metadata"]["text_length"]
                row["word_count"] = sample["metadata"]["word_count"]
            writer.writerow(row)
    
    print(f"✓ Exported {len(dataset)} samples to {filepath}")


def export_json(dataset: List[Dict], filepath: str):
    """Export dataset to JSON format."""
    os.makedirs(os.path.dirname(filepath) if os.path.dirname(filepath) else '.', exist_ok=True)
    
    output = {
        "_metadata": {
            "project": "Sentiment Analysis Dataset",
            "description": "Generated sentiment analysis data",
            "generator": "RSK World Data Generator",
            "website": "https://rskworld.in",
            "author": "Molla Samser (Founder)",
            "designer_tester": "Rima Khatun",
            "email": "help@rskworld.in | support@rskworld.in",
            "copyright": "© 2026 RSK World - Free Programming Resources & Source Code",
            "generated_at": datetime.now().isoformat(),
            "total_samples": len(dataset),
            "sentiment_distribution": {
                "positive": sum(1 for s in dataset if s["sentiment"] == "positive"),
                "neutral": sum(1 for s in dataset if s["sentiment"] == "neutral"),
                "negative": sum(1 for s in dataset if s["sentiment"] == "negative")
            }
        },
        "data": dataset
    }
    
    with open(filepath, 'w', encoding='utf-8') as f:
        json.dump(output, f, indent=2, ensure_ascii=False)
    
    print(f"✓ Exported {len(dataset)} samples to {filepath}")


def export_txt(dataset: List[Dict], filepath: str):
    """Export dataset to TXT format."""
    os.makedirs(os.path.dirname(filepath) if os.path.dirname(filepath) else '.', exist_ok=True)
    
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write("""# ================================================================================
# Sentiment Analysis Dataset - Generated Data
# 
# Project: Sentiment Analysis Dataset
# Generated by: RSK World Data Generator
# Website: https://rskworld.in
# 
# Author: Molla Samser (Founder)
# Designer & Tester: Rima Khatun
# Email: help@rskworld.in | support@rskworld.in
# 
# © 2026 RSK World - Free Programming Resources & Source Code
# 
# Format: SENTIMENT | SOURCE | TEXT
# ================================================================================

""")
        for sample in dataset:
            f.write(f"{sample['sentiment']} | {sample['source']} | {sample['text']}\n\n")
    
    print(f"✓ Exported {len(dataset)} samples to {filepath}")


# ============================================
# Main Function
# ============================================

def main():
    parser = argparse.ArgumentParser(
        description="Generate sentiment analysis dataset - RSK World",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  python generate_data.py --samples 1000
  python generate_data.py --samples 5000 --format json --balanced
  python generate_data.py --samples 10000 --output ./data/custom.csv --split 0.8
  python generate_data.py --samples 2000 --include-metadata --all-formats

Author: Molla Samser (Founder) - RSK World
Website: https://rskworld.in
        """
    )
    
    parser.add_argument(
        "--samples", "-n",
        type=int,
        default=1000,
        help="Number of samples to generate (default: 1000)"
    )
    
    parser.add_argument(
        "--output", "-o",
        type=str,
        default="./data/generated_data",
        help="Output file path (without extension)"
    )
    
    parser.add_argument(
        "--format", "-f",
        type=str,
        choices=["csv", "json", "txt", "all"],
        default="csv",
        help="Output format (default: csv)"
    )
    
    parser.add_argument(
        "--balanced", "-b",
        action="store_true",
        help="Generate balanced dataset (equal samples per class)"
    )
    
    parser.add_argument(
        "--split", "-s",
        type=float,
        default=None,
        help="Train/test split ratio (e.g., 0.8 for 80% train)"
    )
    
    parser.add_argument(
        "--include-metadata", "-m",
        action="store_true",
        help="Include metadata in generated samples"
    )
    
    parser.add_argument(
        "--all-formats", "-a",
        action="store_true",
        help="Export in all formats (CSV, JSON, TXT)"
    )
    
    parser.add_argument(
        "--seed",
        type=int,
        default=None,
        help="Random seed for reproducibility"
    )
    
    args = parser.parse_args()
    
    # Set random seed if provided
    if args.seed:
        random.seed(args.seed)
    
    print("""
╔══════════════════════════════════════════════════════════════════╗
║         RSK World - Sentiment Analysis Data Generator            ║
║                                                                  ║
║  Author: Molla Samser (Founder)                                  ║
║  Website: https://rskworld.in                                    ║
║  © 2026 RSK World - Free Programming Resources & Source Code     ║
╚══════════════════════════════════════════════════════════════════╝
    """)
    
    print(f"Generating {args.samples} samples...")
    print(f"Balanced: {args.balanced}")
    print(f"Include metadata: {args.include_metadata}")
    print()
    
    # Generate dataset
    dataset = generate_dataset(
        num_samples=args.samples,
        balanced=args.balanced,
        include_metadata=args.include_metadata
    )
    
    # Calculate statistics
    pos_count = sum(1 for s in dataset if s["sentiment"] == "positive")
    neu_count = sum(1 for s in dataset if s["sentiment"] == "neutral")
    neg_count = sum(1 for s in dataset if s["sentiment"] == "negative")
    
    print()
    print("Dataset Statistics:")
    print(f"  - Total samples: {len(dataset)}")
    print(f"  - Positive: {pos_count} ({pos_count/len(dataset)*100:.1f}%)")
    print(f"  - Neutral: {neu_count} ({neu_count/len(dataset)*100:.1f}%)")
    print(f"  - Negative: {neg_count} ({neg_count/len(dataset)*100:.1f}%)")
    print()
    
    # Export based on format
    formats_to_export = []
    if args.all_formats or args.format == "all":
        formats_to_export = ["csv", "json", "txt"]
    else:
        formats_to_export = [args.format]
    
    # Handle split if requested
    if args.split:
        train_data, test_data = split_dataset(dataset, args.split)
        print(f"Split dataset: {len(train_data)} train, {len(test_data)} test")
        print()
        
        for fmt in formats_to_export:
            train_path = f"{args.output}_train.{fmt}"
            test_path = f"{args.output}_test.{fmt}"
            
            if fmt == "csv":
                export_csv(train_data, train_path)
                export_csv(test_data, test_path)
            elif fmt == "json":
                export_json(train_data, train_path)
                export_json(test_data, test_path)
            elif fmt == "txt":
                export_txt(train_data, train_path)
                export_txt(test_data, test_path)
    else:
        for fmt in formats_to_export:
            filepath = f"{args.output}.{fmt}"
            
            if fmt == "csv":
                export_csv(dataset, filepath)
            elif fmt == "json":
                export_json(dataset, filepath)
            elif fmt == "txt":
                export_txt(dataset, filepath)
    
    print()
    print("✓ Data generation complete!")
    print()


if __name__ == "__main__":
    main()

541 lines•20.8 KB
python
🚀 Support RSK World

Subscribe to our YouTube channel for latest tutorials & updates!



Click subscribe & support our work ❤️

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer