#uber

import pandas as pd
import numpy as np
import seaborn as sns

df=pd.read_csv("uber.csv")
df.head()

df.dtypes

df.describe()

#proprocessing
df.isnull().sum()
#latitude and longitude having single null value hence drop it
df.dropna(inplace=True)

df.drop(['Unnamed: 0','key'],axis=1,inplace=True)

#remove date from pickup_datetime columns and keep only hour of the day
df["pickup_datetime"] = pd.to_datetime(df["pickup_datetime"]).dt.strftime("%H").astype('float32')

df = df.rename(columns={"pickup_datetime": "time"})

#distance between pickup location and dropoff location
import math

def euclidean_distance(lat1,lon1,lat2,lon2):
    dlat=lat2-lat1
    dlon=lon2-lon1
    distance=math.sqrt(dlat**2+dlon**2)
    return distance
df['distance']=df.apply(
    lambda row:euclidean_distance(
        row['pickup_latitude'],
        row['pickup_longitude'],
        row['dropoff_latitude'],
        row['dropoff_longitude']
    ),axis=1
)

#outliers analysis
#remove outliers passenger_cout>100
sns.scatterplot(df,y="fare_amount",x="passenger_count")
df=df[df["passenger_count"]<150]

columns = ['pickup_latitude', 'pickup_longitude',
           'dropoff_latitude', 'dropoff_longitude']

for col in columns:
    Q1 = df[col].quantile(0.25)
    Q3 = df[col].quantile(0.75)
    IQR = Q3 - Q1

    lower = Q1 - 1.5 * IQR
    upper = Q3 + 1.5 * IQR

    df = df[(df[col] >= lower) & (df[col] <= upper)]

print("Outliers removed successfully!")
print("Remaining rows:", len(df))

#correlation analysis
df.corr(method="pearson")

#Linear regression

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

#train-test
X=df.drop('fare_amount',axis=1)
y=df['fare_amount']
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)
#standardize split
scaler=StandardScaler()
X_train_scaled=scaler.fit_transform(X_train)
# We cannot use the fit() method on the test dataset, because
# it could introduce bias to the testing dataset. So, we apply the transform() 
# method directly on the test dataset.
X_test_scaled=scaler.transform(X_test)

from sklearn.linear_model import LinearRegression
model=LinearRegression()
model.fit(X_train_scaled,y_train)

y_pred=model.predict(X_test_scaled)


from sklearn.metrics import r2_score
from sklearn.metrics import root_mean_squared_error
print("R2 score: ",r2_score(y_test,y_pred))
print("RMSE: ",root_mean_squared_error(y_test,y_pred))

from sklearn.ensemble import RandomForestRegressor

model=RandomForestRegressor()
model.fit(X_train_scaled,y_train)
y_pred=model.predict(X_test_scaled)

from sklearn.metrics import r2_score
from sklearn.metrics import root_mean_squared_error
print("R2 score: ",r2_score(y_test,y_pred))
print("RMSE: ",root_mean_squared_error(y_test,y_pred))

comparison = pd.DataFrame({
    'Actual Price': y_test.values,
    'Predicted Price': y_pred
})

print(comparison.head(10))
