├── README.md ├── File └── synthetic_ocean_current.csv /README.md: -------------------------------------------------------------------------------- 1 | # 🌊 Ocean Current Forecasting with Time Series ML Models 2 | 3 | This project simulates and forecasts ocean current speeds using synthetic time series data and machine learning models. It demonstrates how lag-based features and supervised ML can be used for environmental time series forecasting. 4 | 5 | --- 6 | 7 | ## 📌 Project Overview 8 | 9 | Ocean current forecasting is crucial for marine navigation, climate research, and coastal management. This project generates synthetic weekly ocean current speed data and applies machine learning models—Linear Regression and Random Forest—to predict future current speeds based on past observations. 10 | 11 | --- 12 | 13 | ## 🧪 Technologies Used 14 | 15 | - Python 3 16 | - NumPy 17 | - Pandas 18 | - Matplotlib / Seaborn 19 | - Scikit-learn 20 | 21 | --- 22 | 23 | ## 📁 Files 24 | 25 | ```bash 26 | . 27 | ├── synthetic_ocean_current.csv # Generated dataset (150 weekly samples) 28 | ├── ocean_current_forecasting.py # Python script for analysis and forecasting 29 | └── README.md # Project overview and usage instructions 30 | 📈 Features 31 | ✅ Synthetic data simulation with seasonality and trend 32 | 33 | 🔁 Lag-based time series to supervised transformation 34 | 35 | 🧠 ML models: Linear Regression and Random Forest 36 | 37 | 📉 Model evaluation using RMSE 38 | 39 | 📊 Visualization of forecast vs. actual values 40 | 41 | ⚙️ How to Run 42 | Clone the repository: 43 | 44 | bash 45 | Copy 46 | Edit 47 | git clone https://github.com/yourusername/ocean-current-forecasting.git 48 | cd ocean-current-forecasting 49 | Install dependencies: 50 | 51 | bash 52 | Copy 53 | Edit 54 | pip install -r requirements.txt 55 | Run the script: 56 | 57 | bash 58 | Copy 59 | Edit 60 | python ocean_current_forecasting.py 61 | 📂 Dataset Preview 62 | Date Current_Speed (m/s) 63 | 2015-01-04 1.62 64 | 2015-01-11 1.48 65 | ... ... 66 | 67 | 📜 License 68 | This project is licensed under the MIT License. 69 | 70 | 🙋‍♂️ Author 71 | Agbozu Ebingiye Nelvin 72 | 📧 nelvinebingiye@gmail.com 73 | 🔗 @nelvinebi 74 | -------------------------------------------------------------------------------- /File: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import matplotlib.pyplot as plt 4 | import seaborn as sns 5 | from sklearn.linear_model import LinearRegression 6 | from sklearn.ensemble import RandomForestRegressor 7 | from sklearn.metrics import mean_squared_error 8 | from sklearn.model_selection import train_test_split 9 | 10 | # 1. Generate Synthetic Ocean Current Speed Data 11 | np.random.seed(42) 12 | n_samples = 150 13 | dates = pd.date_range(start='2015-01-01', periods=n_samples, freq='W') # Weekly data 14 | seasonal = 0.5 * np.sin(2 * np.pi * np.arange(n_samples) / 26) # ~6-month seasonal cycle 15 | trend = 0.01 * np.arange(n_samples) # slow increasing trend 16 | noise = np.random.normal(0, 0.2, n_samples) 17 | current_speed = 1.5 + seasonal + trend + noise # in m/s 18 | 19 | # DataFrame 20 | df = pd.DataFrame({ 21 | 'Date': dates, 22 | 'Current_Speed': current_speed 23 | }) 24 | df.set_index('Date', inplace=True) 25 | 26 | # 2. Create Lag Features for Time Series Supervised Learning 27 | def create_lag_features(data, lags=5): 28 | df_lag = pd.DataFrame() 29 | for i in range(1, lags+1): 30 | df_lag[f'lag_{i}'] = data.shift(i) 31 | df_lag['target'] = data.values 32 | df_lag.dropna(inplace=True) 33 | return df_lag 34 | 35 | lags = 5 36 | data_supervised = create_lag_features(df['Current_Speed'], lags) 37 | 38 | # 3. Split Data into Train and Test 39 | X = data_supervised.drop('target', axis=1) 40 | y = data_supervised['target'] 41 | X_train, X_test, y_train, y_test = train_test_split(X, y, shuffle=False, test_size=0.2) 42 | 43 | # 4. Train ML Models 44 | # Linear Regression 45 | lr = LinearRegression() 46 | lr.fit(X_train, y_train) 47 | y_pred_lr = lr.predict(X_test) 48 | 49 | # Random Forest 50 | rf = RandomForestRegressor(n_estimators=100, random_state=42) 51 | rf.fit(X_train, y_train) 52 | y_pred_rf = rf.predict(X_test) 53 | 54 | # 5. Evaluate Models 55 | def evaluate(model_name, y_true, y_pred): 56 | rmse = np.sqrt(mean_squared_error(y_true, y_pred)) 57 | print(f"{model_name} RMSE: {rmse:.4f}") 58 | 59 | evaluate("Linear Regression", y_test, y_pred_lr) 60 | evaluate("Random Forest", y_test, y_pred_rf) 61 | 62 | # 6. Plot Forecast Results 63 | plt.figure(figsize=(12, 6)) 64 | plt.plot(df.index[-len(y_test):], y_test, label='Actual', marker='o') 65 | plt.plot(df.index[-len(y_test):], y_pred_lr, label='Linear Regression Forecast', linestyle='--') 66 | plt.plot(df.index[-len(y_test):], y_pred_rf, label='Random Forest Forecast', linestyle='--') 67 | plt.title('Ocean Current Speed Forecast (Synthetic Data)') 68 | plt.xlabel('Date') 69 | plt.ylabel('Current Speed (m/s)') 70 | plt.legend() 71 | plt.grid(True) 72 | plt.tight_layout() 73 | plt.show() 74 | -------------------------------------------------------------------------------- /synthetic_ocean_current.csv: -------------------------------------------------------------------------------- 1 | Date,Current_Speed 2 | 2015-01-04,1.5993428306022466 3 | 2015-01-11,1.602004971909542 4 | 2015-01-18,1.8818992936420227 5 | 2015-01-25,2.1661673004020026 6 | 2015-02-01,1.9046612580021611 7 | 2015-02-08,1.9706807299528712 8 | 2015-02-15,2.3721970001505053 9 | 2015-02-22,2.2198413828796086 10 | 2015-03-01,1.953613244155717 11 | 2015-03-08,2.1100039416640213 12 | 2015-03-15,1.8388777905579052 13 | 2015-03-22,1.7492156353078332 14 | 2015-03-29,1.7880502864569858 15 | 2015-04-05,1.2473439510684403 16 | 2015-04-12,1.1753586013536146 17 | 2015-04-19,1.3051809081299215 18 | 2015-04-26,1.1258724468127177 19 | 2015-05-03,1.3213575335722265 20 | 2015-05-10,1.0308870635530505 21 | 2015-05-17,0.9111848226839148 22 | 2015-05-24,1.4967753167352837 23 | 2015-05-31,1.1973366185599854 24 | 2015-06-07,1.3220137079907561 25 | 2015-06-14,1.1134890336369108 26 | 2015-06-21,1.3987618690730792 27 | 2015-06-28,1.6525266857981944 28 | 2015-07-05,1.5298012845155395 29 | 2015-07-12,1.964797435812913 30 | 2015-07-19,1.8922338480381227 31 | 2015-07-26,2.0632225791617422 32 | 2015-08-02,2.0911506105009483 33 | 2015-08-09,2.6479637582444946 34 | 2015-08-16,2.3136549921014398 35 | 2015-08-23,2.114812251257847 36 | 2015-08-30,2.472017103763345 37 | 2015-09-06,2.0173232029526242 38 | 2015-09-13,2.233334048121349 39 | 2015-09-20,1.710427561245929 40 | 2015-09-27,1.734020622364093 41 | 2015-10-04,1.9293722471738248 42 | 2015-10-11,1.928035483855303 43 | 2015-10-18,1.7119120702161104 44 | 2015-10-25,1.5653090144019541 45 | 2015-11-01,1.4582873279353143 46 | 2015-11-08,1.1767874805838074 47 | 2015-11-15,1.3096767212720313 48 | 2015-11-22,1.3715178087590156 49 | 2015-11-29,1.7139163239010757 50 | 2015-12-06,1.6372317249668642 51 | 2015-12-13,1.3058306398070554 52 | 2015-12-20,1.8324552078570746 53 | 2015-12-27,1.813325711772957 54 | 2016-01-03,1.8846155999388088 55 | 2016-01-10,2.2719930899119527 56 | 2016-01-17,2.478561490521074 57 | 2016-01-24,2.567817352943637 58 | 2016-01-31,2.3036484283022998 59 | 2016-02-07,2.475665646172464 60 | 2016-02-14,2.6426071233297397 61 | 2016-02-21,2.7814634624734986 62 | 2016-02-28,2.47167327377365 63 | 2016-03-06,2.4843601376140647 64 | 2016-03-13,2.230294334319192 65 | 2016-03-20,2.12312026120575 66 | 2016-03-27,2.4221629966226192 67 | 2016-04-03,2.421248005714165 68 | 2016-04-10,2.0259401435401543 69 | 2016-04-17,2.13834499355652 70 | 2016-04-24,1.9207658758891295 71 | 2016-05-01,1.6494841161321474 72 | 2016-05-08,1.804770999758976 73 | 2016-05-15,2.021252876244167 74 | 2016-05-22,1.7164803551289827 75 | 2016-05-29,2.0754206098200934 76 | 2016-06-05,1.3045590462352228 77 | 2016-06-12,2.0828191717546467 78 | 2016-06-19,2.0450478276257487 79 | 2016-06-26,2.090540697763048 80 | 2016-07-03,2.2983521553071 81 | 2016-07-10,2.0121440492236013 82 | 2016-07-17,2.4884272084543824 83 | 2016-07-24,2.7129838434227467 84 | 2016-07-31,3.0270707418951313 85 | 2016-08-07,2.6938540776879782 86 | 2016-08-14,2.6746557164703892 87 | 2016-08-21,2.7460030283321197 88 | 2016-08-28,3.0105885448831224 89 | 2016-09-04,2.847242154878766 90 | 2016-09-11,2.605609288366992 91 | 2016-09-18,2.725015072644555 92 | 2016-09-25,2.539073342013387 93 | 2016-10-02,2.6037289981065785 94 | 2016-10-09,2.1599315490807514 95 | 2016-10-16,2.1321059846585633 96 | 2016-10-23,2.030017040253171 97 | 2016-10-30,1.7458050774267488 98 | 2016-11-06,2.0517159340702076 99 | 2016-11-13,2.025856617386951 100 | 2016-11-20,1.9846682542794651 101 | 2016-11-27,1.9755744519822633 102 | 2016-12-04,1.805433918643089 103 | 2016-12-11,2.0943096063265303 104 | 2016-12-18,2.219095510672761 105 | 2016-12-25,2.249886714011896 106 | 2017-01-01,2.5077428576667997 107 | 2017-01-08,2.750468003506687 108 | 2017-01-15,3.1695987662639906 109 | 2017-01-22,2.9364768916867656 110 | 2017-01-29,3.0430020110913807 111 | 2017-02-05,3.0426189381894733 112 | 2017-02-12,2.7126001939892186 113 | 2017-02-19,3.1010516619591835 114 | 2017-02-26,3.099554163330913 115 | 2017-03-05,3.5341403554438857 116 | 2017-03-12,2.9330891361641735 117 | 2017-03-19,2.9426710544886063 118 | 2017-03-26,2.7727154782027306 119 | 2017-04-02,2.436264392476094 120 | 2017-04-09,2.7889067307592263 121 | 2017-04-16,2.6080250205154716 122 | 2017-04-23,2.526645060288213 123 | 2017-04-30,2.1166305760942232 124 | 2017-05-07,2.5330507408445126 125 | 2017-05-14,1.9532753503925169 126 | 2017-05-21,2.361016981711027 127 | 2017-05-28,2.720583003819288 128 | 2017-06-04,2.150400802027034 129 | 2017-06-11,2.3251791249590474 130 | 2017-06-18,2.567568686995643 131 | 2017-06-25,2.5696470370329796 132 | 2017-07-02,2.489867313786773 133 | 2017-07-09,2.943370427104985 134 | 2017-07-16,2.8399008432766637 135 | 2017-07-23,3.2562798152474337 136 | 2017-07-30,3.067607086100068 137 | 2017-08-06,3.6274950023462145 138 | 2017-08-13,3.1997037785817795 139 | 2017-08-20,3.301942133807892 140 | 2017-08-27,3.510211564816642 141 | 2017-09-03,3.0553190696600376 142 | 2017-09-10,3.277053316041225 143 | 2017-09-17,3.403790136878371 144 | 2017-09-24,2.7181611852315335 145 | 2017-10-01,2.9669267717064596 146 | 2017-10-08,2.872318726705907 147 | 2017-10-15,2.874002988333578 148 | 2017-10-22,2.381048528703988 149 | 2017-10-29,2.2944167444363175 150 | 2017-11-05,2.616880191780672 151 | 2017-11-12,2.5530424975976107 152 | --------------------------------------------------------------------------------