================================================================================
  Question 49: Wine Quality Regression with Dataset Integration
================================================================================

FULL QUESTION:
Task:
Integrate Red and White wine datasets and build regression models to predict
wine quality:
1. Load both datasets (winequality-red.csv and winequality-white.csv).
2. Data Integration:
   - Add a column 'wine_type': value 'red' for red wine, 'white' for white wine.
   - Concatenate both datasets into a single DataFrame.
3. Exploratory Analysis:
   - Display shape, column names, head, and class distributions.
4. Model Training:
   - Train Linear Regression, Decision Tree Regressor, and Random Forest Regressor.
5. Evaluation:
   - Evaluate using MSE, MAE, and R^2 Score.
   - Compare model performance.

SHORT QUESTION:
Integrates red and white wine datasets and trains regression models (Linear, Decision Tree, Random Forest) to predict quality.

================================================================================
README & SETUP INSTRUCTIONS:
================================================================================
# Question 49: Wine Quality Regression with Dataset Integration

- Prerequisites: Python 3.x, Pandas, NumPy, Scikit-Learn (pip install pandas numpy scikit-learn).
- Setup: Uses 'winequality-red.csv' and 'winequality-white.csv'.
- How to Run: python question_49.py
- Expected Behavior: Integrates red and white wine data, trains regression models, and outputs evaluation metrics (R2, MAE, MSE, RMSE).

================================================================================
SOURCE CODE FILES:
================================================================================

1. question_49.py
--------------------------------------------------------------------------------
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

df_red = pd.read_csv('winequality-red.csv', sep=';')
df_white = pd.read_csv('winequality-white.csv', sep=';')

print("--- RED WINE DATASET ---")
print("Shape:", df_red.shape)
print("Columns:")
co=0
for c in df_red.columns:
    if co == 5:
      print()
    print(f"{c}", end=",")
    co+=1

print("\nFirst 5 rows:\n", df_red.head(), "\n")

print("--- WHITE WINE DATASET ---")
print("Shape:", df_white.shape)
print("Columns:")
co=0
for c in df_white.columns:
    if co == 5:
      print()
    co+=1
    print(f"{c}", end=",")

print("\nFirst 5 rows:\n", df_white.head(), "\n")

are_columns_identical = list(df_red.columns) == list(df_white.columns)
print(f"Are column names identical before merging? {are_columns_identical}")

df_red['wine_type'] = 'red'
df_white['wine_type'] = 'white'

df_wine = pd.concat([df_red, df_white], ignore_index=True)

print("Unique values in wine_type:", df_wine['wine_type'].unique())

df_wine.to_csv("winequality-integrated.csv", index=False)
print("Saved integrated dataset as 'winequality-integrated.csv'\n")

print("Missing values per column:\n", df_wine.isnull().sum())
print("Duplicate rows count:", df_wine.duplicated().sum())

df_wine = df_wine.drop_duplicates().reset_index(drop=True)
print("Shape after removing duplicates:", df_wine.shape, "\n")

X = df_wine.drop(columns=['quality'])
y = df_wine['quality']

le = LabelEncoder()
X['wine_type'] = le.fit_transform(X['wine_type'])

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.20, random_state=42
)

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

fig, axes = plt.subplots(2, 2, figsize=(14, 10))

sns.countplot(x='quality', data=df_wine, ax=axes[0, 0], palette='viridis')
axes[0, 0].set_title('Overall Quality Score Distribution')

sns.countplot(x='quality', hue='wine_type', data=df_wine, ax=axes[0, 1], palette=['red', 'blue'])
axes[0, 1].set_title('Quality Score Distribution by Wine Type')

avg_quality = df_wine.groupby('wine_type')['quality'].mean().reset_index()
sns.barplot(x='wine_type', y='quality', data=avg_quality, ax=axes[1, 0], palette=['red', 'blue'])
axes[1, 0].set_title('Average Quality: Red vs White')
axes[1, 0].set_ylim(0, 10)

sns.scatterplot(x='alcohol', y='quality', hue='wine_type', data=df_wine, alpha=0.5, ax=axes[1, 1])
axes[1, 1].set_title('Alcohol vs Quality (Colored by Wine Type)')

plt.tight_layout()
plt.show()

plt.figure(figsize=(12, 8))
numeric_df = df_wine.copy()
numeric_df['wine_type'] = le.fit_transform(numeric_df['wine_type'])
corr_matrix = numeric_df.corr()
sns.heatmap(corr_matrix, annot=True, fmt=".2f", cmap='coolwarm', square=True)
plt.title("Correlation Heatmap")
plt.show()

top3_corr = corr_matrix['quality'].drop('quality').abs().nlargest(3)
print("Top 3 features most correlated with quality:")
print(top3_corr, "\n")

models = {
    "Linear Regression": LinearRegression(),
    "Decision Tree": DecisionTreeRegressor(random_state=42),
    "Random Forest": RandomForestRegressor(n_estimators=100, random_state=42)
}

results = []

for name, model in models.items():
    model.fit(X_train_scaled, y_train)
    y_pred = model.predict(X_test_scaled)

    r2 = r2_score(y_test, y_pred)
    mae = mean_absolute_error(y_test, y_pred)
    mse = mean_squared_error(y_test, y_pred)
    rmse = np.sqrt(mse)

    results.append({
        "Model": name,
        "R² Score": r2,
        "MAE": mae,
        "MSE": mse,
        "RMSE": rmse
    })

df_results = pd.DataFrame(results)
print("--- MODEL EVALUATION METRICS ---")
print(df_results.to_string(index=False))
--------------------------------------------------------------------------------
