jonwiese commited on
Commit
c1f29cc
1 Parent(s): 13d2dd0

add train.py

Browse files
Files changed (1) hide show
  1. train.py +137 -0
train.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.optim as optim
4
+ import pandas as pd
5
+ import numpy as np
6
+ from sklearn.preprocessing import MinMaxScaler
7
+ from datetime import datetime
8
+
9
+
10
+ class WeatherPredictor:
11
+ def __init__(self, data_path):
12
+ # Load and preprocess data
13
+ self.df = pd.read_csv(data_path, parse_dates=['datetime'],
14
+ date_parser=lambda x: datetime.strptime(x, '%d/%m/%y'))
15
+ self.df['day'] = self.df['datetime'].dt.day
16
+ self.df['month'] = self.df['datetime'].dt.month
17
+ self.df['year'] = self.df['datetime'].dt.year
18
+ self.df['day_sin'] = np.sin(2 * np.pi * self.df['day'] / 31)
19
+ self.df['day_cos'] = np.cos(2 * np.pi * self.df['day'] / 31)
20
+ self.df['month_sin'] = np.sin(2 * np.pi * self.df['month'] / 12)
21
+ self.df['month_cos'] = np.cos(2 * np.pi * self.df['month'] / 12)
22
+ self.df['year'] = self.df['datetime'].dt.year
23
+
24
+ features = ['day_sin', 'day_cos', 'month_sin', 'month_cos', 'year']
25
+ target_columns = ['temp', 'precip', 'snow', 'windspeed']
26
+
27
+ # Scale features and targets
28
+ self.feature_scaler = MinMaxScaler()
29
+ self.target_scaler = MinMaxScaler()
30
+
31
+ X = self.feature_scaler.fit_transform(self.df[features])
32
+ Y = self.target_scaler.fit_transform(self.df[target_columns])
33
+
34
+ self.X_tensor = torch.FloatTensor(X)
35
+ self.Y_tensor = torch.FloatTensor(Y)
36
+
37
+ # Single model for all targets
38
+ input_dim = len(features)
39
+ self.model = nn.Sequential(
40
+ nn.Linear(input_dim, 16),
41
+ nn.ReLU(),
42
+ nn.Linear(16, 8),
43
+ nn.ReLU(),
44
+ nn.Linear(8, 4)
45
+ )
46
+
47
+ def train(self, epochs=1000):
48
+ # Define loss function and optimizer
49
+ criterion = nn.MSELoss()
50
+ optimizer = optim.Adam(self.model.parameters(), lr=0.01)
51
+
52
+ for epoch in range(epochs):
53
+ # Forward pass
54
+ outputs = self.model(self.X_tensor) # Multi-output predictions
55
+ loss = criterion(outputs, self.Y_tensor)
56
+
57
+ # Backward pass and optimize
58
+ optimizer.zero_grad()
59
+ loss.backward()
60
+ optimizer.step()
61
+
62
+ if epoch % 100 == 0:
63
+ print(f'Epoch [{epoch}/{epochs}], Loss: {loss.item():.4f}')
64
+
65
+ # Save the model after training
66
+ self.save_model('weather_predictor.pth')
67
+
68
+ def predict(self, input_date):
69
+ # Convert input date to features
70
+ date = datetime.strptime(input_date, '%d/%m/%y')
71
+ features = [
72
+ np.sin(2 * np.pi * date.day / 31),
73
+ np.cos(2 * np.pi * date.day / 31),
74
+ np.sin(2 * np.pi * date.month / 12),
75
+ np.cos(2 * np.pi * date.month / 12),
76
+ date.year
77
+ ]
78
+
79
+ # Transform features to match training scale
80
+ scaled_features = self.feature_scaler.transform([features])
81
+ input_tensor = torch.FloatTensor(scaled_features)
82
+
83
+ # Predict outputs
84
+ with torch.no_grad():
85
+ scaled_predictions = self.model(input_tensor).numpy() # Outputs: [temp, precip, snow, windspeed]
86
+ predictions = self.target_scaler.inverse_transform(scaled_predictions.reshape(1, -1)).flatten()
87
+
88
+ # Map predictions to target columns
89
+ target_columns = ['temp', 'precip', 'snow', 'windspeed']
90
+ return dict(zip(target_columns, predictions))
91
+
92
+
93
+ def predict(self, input_date):
94
+ # Convert input date to features
95
+ date = datetime.strptime(input_date, '%d/%m/%y')
96
+ features = [
97
+ np.sin(2 * np.pi * date.day / 31),
98
+ np.cos(2 * np.pi * date.day / 31),
99
+ np.sin(2 * np.pi * date.month / 12),
100
+ np.cos(2 * np.pi * date.month / 12),
101
+ date.year
102
+ ]
103
+
104
+ # Transform features to match training scale
105
+ scaled_features = self.feature_scaler.transform([features])
106
+ input_tensor = torch.FloatTensor(scaled_features)
107
+
108
+ # Load the model before making predictions
109
+ self.load_model('weather_predictor.pth')
110
+
111
+ # Predict outputs
112
+ with torch.no_grad():
113
+ scaled_predictions = self.model(input_tensor).numpy() # Outputs: [temp, precip, snow, windspeed]
114
+ predictions = self.target_scaler.inverse_transform(scaled_predictions.reshape(1, -1)).flatten()
115
+
116
+ # Map predictions to target columns
117
+ target_columns = ['temp', 'precip', 'snow', 'windspeed']
118
+ return dict(zip(target_columns, predictions))
119
+
120
+ def save_model(self, file_path):
121
+ torch.save(self.model.state_dict(), file_path)
122
+
123
+ def load_model(self, file_path):
124
+ self.model.load_state_dict(torch.load(file_path))
125
+ self.model.eval()
126
+
127
+ def main():
128
+ predictor = WeatherPredictor('basel-weather.csv')
129
+ predictor.train()
130
+
131
+ # Predict for a specific date
132
+ result = predictor.predict('01/02/23')
133
+ print("Predictions:", result)
134
+
135
+
136
+ if __name__ == '__main__':
137
+ main()