Commit
·
b331a3f
1
Parent(s):
b3ab864
final version
Browse files- .gitattributes +1 -0
- .gradio/certificate.pem +31 -0
- .gradio/flagged/dataset1.csv +2 -0
- app.py +92 -27
- data/2024_11_7_total_return_sample.pkl +3 -0
- requirements.txt +1 -0
.gitattributes
CHANGED
|
@@ -35,3 +35,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
data/NECRIF_and_PRISM_merged.csv filter=lfs diff=lfs merge=lfs -text
|
| 37 |
data/PRISM.pkl filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
data/NECRIF_and_PRISM_merged.csv filter=lfs diff=lfs merge=lfs -text
|
| 37 |
data/PRISM.pkl filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
data/2024_11_7_total_return_sample.pkl filter=lfs diff=lfs merge=lfs -text
|
.gradio/certificate.pem
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN CERTIFICATE-----
|
| 2 |
+
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
|
| 31 |
+
-----END CERTIFICATE-----
|
.gradio/flagged/dataset1.csv
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Select CBSA Area,Predicted Total Return for 2025 (Quarters),timestamp
|
| 2 |
+
AL-Birmingham-Hoover,,2024-11-05 12:18:07.477425
|
app.py
CHANGED
|
@@ -1,53 +1,118 @@
|
|
| 1 |
-
# Import required libraries
|
| 2 |
import gradio as gr
|
| 3 |
import numpy as np
|
|
|
|
| 4 |
import pickle
|
| 5 |
from tensorflow.keras.models import load_model
|
| 6 |
from sklearn.preprocessing import MinMaxScaler
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
-
# Load the model and scaler
|
| 9 |
model = load_model('models/new_merged_weather_financial_q_l4q_l24q.keras')
|
| 10 |
scaler = MinMaxScaler()
|
| 11 |
|
| 12 |
-
# Load the dataset from the pickle file
|
| 13 |
with open('data/PRISM.pkl', 'rb') as f:
|
| 14 |
data = pickle.load(f)
|
| 15 |
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
| 18 |
scaler.fit(features)
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
cbsa_data = data[data['CBSA_Name'] == cbsa_name]
|
| 23 |
-
|
| 24 |
-
|
|
|
|
|
|
|
| 25 |
|
| 26 |
-
|
|
|
|
|
|
|
| 27 |
cbsa_scaled_features = scaler.transform(cbsa_features)
|
| 28 |
|
| 29 |
-
|
| 30 |
-
num_steps = 24
|
| 31 |
latest_sequence = cbsa_scaled_features[-num_steps:].reshape(1, num_steps, cbsa_scaled_features.shape[1])
|
| 32 |
-
|
| 33 |
-
# Generate predictions for the next 4 quarters
|
| 34 |
future_predictions = []
|
| 35 |
-
|
|
|
|
| 36 |
predicted_value = model.predict(latest_sequence)[0, 0]
|
| 37 |
-
future_predictions.append(predicted_value)
|
| 38 |
latest_sequence = np.roll(latest_sequence, -1, axis=1)
|
| 39 |
latest_sequence[0, -1, -1] = predicted_value
|
| 40 |
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
-
|
| 44 |
-
cbsa_options = data['CBSA_Name'].unique().tolist()
|
| 45 |
-
iface = gr.Interface(
|
| 46 |
-
fn=predict_future,
|
| 47 |
-
inputs=gr.Dropdown(choices=cbsa_options, label="Select CBSA Area"),
|
| 48 |
-
outputs=gr.JSON(label="Predicted Total Return for 2025 (Quarters)"),
|
| 49 |
-
title="CBSA Total Return Predictor",
|
| 50 |
-
description="Select a CBSA to get predicted total returns for the upcoming year."
|
| 51 |
-
)
|
| 52 |
|
| 53 |
-
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import numpy as np
|
| 3 |
+
import pandas as pd
|
| 4 |
import pickle
|
| 5 |
from tensorflow.keras.models import load_model
|
| 6 |
from sklearn.preprocessing import MinMaxScaler
|
| 7 |
+
import matplotlib.pyplot as plt
|
| 8 |
+
from io import BytesIO
|
| 9 |
+
from PIL import Image
|
| 10 |
+
import json
|
| 11 |
|
|
|
|
| 12 |
model = load_model('models/new_merged_weather_financial_q_l4q_l24q.keras')
|
| 13 |
scaler = MinMaxScaler()
|
| 14 |
|
|
|
|
| 15 |
with open('data/PRISM.pkl', 'rb') as f:
|
| 16 |
data = pickle.load(f)
|
| 17 |
|
| 18 |
+
data = data.sort_values(by=['YYYYQ', 'CBSA_Name'])
|
| 19 |
+
|
| 20 |
+
features = data.drop(
|
| 21 |
+
columns=['Date', 'CBSA_Name', 'Id', 'iname', 'type', 'Cluster', 'region', 'division', 'state', 'msa'])
|
| 22 |
scaler.fit(features)
|
| 23 |
|
| 24 |
+
|
| 25 |
+
def get_actual_values_2015_2023(cbsa_name):
|
| 26 |
+
with open('data/2024_11_7_total_return_sample.pkl', 'rb') as f:
|
| 27 |
+
cbsa_filtered_data = pickle.load(f)
|
| 28 |
+
|
| 29 |
+
cbsa_data = cbsa_filtered_data[cbsa_filtered_data['CBSA_Name'] == cbsa_name]
|
| 30 |
+
cbsa_data = cbsa_data.sort_values(by='YYYYQ')
|
| 31 |
+
cbsa_data['YYYYQ'] = cbsa_data['YYYYQ'].astype(str).str.strip()
|
| 32 |
+
|
| 33 |
+
actual_values = cbsa_data[(cbsa_data['YYYYQ'].str[:4].astype(int) >= 2015) &
|
| 34 |
+
(cbsa_data['YYYYQ'].str[:4].astype(int) <= 2023)]['tret'].values
|
| 35 |
+
|
| 36 |
+
return actual_values
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def predict_and_plot(cbsa_name):
|
| 40 |
cbsa_data = data[data['CBSA_Name'] == cbsa_name]
|
| 41 |
+
cbsa_data = cbsa_data.sort_values(by='YYYYQ')
|
| 42 |
+
cbsa_data['YYYYQ'] = cbsa_data['YYYYQ'].astype(str).str.strip()
|
| 43 |
+
|
| 44 |
+
actual_values = get_actual_values_2015_2023(cbsa_name)
|
| 45 |
|
| 46 |
+
cbsa_features = cbsa_data.drop(
|
| 47 |
+
columns=['Date', 'CBSA_Name', 'Id', 'iname', 'type', 'Cluster', 'region', 'division', 'state', 'msa']
|
| 48 |
+
)
|
| 49 |
cbsa_scaled_features = scaler.transform(cbsa_features)
|
| 50 |
|
| 51 |
+
num_steps = min(len(cbsa_scaled_features), 24)
|
|
|
|
| 52 |
latest_sequence = cbsa_scaled_features[-num_steps:].reshape(1, num_steps, cbsa_scaled_features.shape[1])
|
|
|
|
|
|
|
| 53 |
future_predictions = []
|
| 54 |
+
|
| 55 |
+
for _ in range(44): # Ensure predictions cover from 2015 Q1 to 2025 Q4
|
| 56 |
predicted_value = model.predict(latest_sequence)[0, 0]
|
| 57 |
+
future_predictions.append(float(predicted_value)) # Convert to native float type
|
| 58 |
latest_sequence = np.roll(latest_sequence, -1, axis=1)
|
| 59 |
latest_sequence[0, -1, -1] = predicted_value
|
| 60 |
|
| 61 |
+
combined_values = np.array(future_predictions)
|
| 62 |
+
|
| 63 |
+
years_quarters = [f"{year} Q{quarter}" for year in range(2015, 2026) for quarter in range(1, 5)]
|
| 64 |
+
years_quarters = years_quarters[:len(combined_values)]
|
| 65 |
+
|
| 66 |
+
predicted_json = []
|
| 67 |
+
for i, value in enumerate(combined_values[len(actual_values):]):
|
| 68 |
+
year, quarter = years_quarters[len(actual_values) + i].split()
|
| 69 |
+
predicted_json.append({"Year": int(year), "Quarter": quarter, "Value": round(value, 3)})
|
| 70 |
+
|
| 71 |
+
json_output = {
|
| 72 |
+
"CBSA": cbsa_name,
|
| 73 |
+
"Label": "Total Return",
|
| 74 |
+
"Predicted": predicted_json
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
plt.figure(figsize=(14, 6))
|
| 78 |
+
plt.plot(years_quarters[:len(actual_values)], actual_values, label="Actual (2015-2023)", marker='o', color='blue')
|
| 79 |
+
plt.plot(years_quarters, combined_values, label="Predicted (2015-2025)", linestyle='--', color='orange')
|
| 80 |
+
|
| 81 |
+
plt.title(f'Total Return Prediction for {cbsa_name} (2015-2025)')
|
| 82 |
+
plt.xlabel('Quarter')
|
| 83 |
+
plt.ylabel('Total Return')
|
| 84 |
+
plt.xticks(rotation=45)
|
| 85 |
+
plt.legend()
|
| 86 |
+
|
| 87 |
+
buf = BytesIO()
|
| 88 |
+
plt.savefig(buf, format='png')
|
| 89 |
+
buf.seek(0)
|
| 90 |
+
img = Image.open(buf)
|
| 91 |
+
img_array = np.array(img)
|
| 92 |
+
|
| 93 |
+
return img_array, json.dumps(json_output, indent=2)
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
with gr.Blocks() as demo:
|
| 97 |
+
with gr.Row():
|
| 98 |
+
with gr.Column():
|
| 99 |
+
cbsa_dropdown = gr.Dropdown(choices=data['CBSA_Name'].unique().tolist(), label="Select CBSA Area")
|
| 100 |
+
predict_button = gr.Button("Submit")
|
| 101 |
+
with gr.Column():
|
| 102 |
+
gr.Markdown("""
|
| 103 |
+
**Total Return**: Total return is a measure of the performance of an asset or investment over a specific period, defined as the sum of **Income Return** and **Asset Return**.
|
| 104 |
+
|
| 105 |
+
- **Income Return**: The net income generated by a property, calculated as rental income minus operating and capital expenditures.
|
| 106 |
+
- **Asset Return**: The appreciation in the market value of a property from purchase to sale.
|
| 107 |
+
|
| 108 |
+
**CBSA (Core-Based Statistical Area)**: Represents a geographical area defined by the Office of Management and Budget, typically used for statistical purposes in the U.S. It consists of counties and county equivalents centered around an urban center with a high degree of social and economic integration.
|
| 109 |
+
""")
|
| 110 |
+
with gr.Row():
|
| 111 |
+
with gr.Column():
|
| 112 |
+
output_image = gr.Image(type="numpy", label="Actual vs Predicted Total Return (2015-2025)")
|
| 113 |
+
with gr.Column():
|
| 114 |
+
json_display = gr.JSON(label="Prediction JSON Output")
|
| 115 |
|
| 116 |
+
predict_button.click(fn=predict_and_plot, inputs=cbsa_dropdown, outputs=[output_image, json_display])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
+
demo.launch()
|
data/2024_11_7_total_return_sample.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f0043164c3837ad6e8d742088852919f908a1514ea980e7bd3c8aaee260c7b4e
|
| 3 |
+
size 3905447
|
requirements.txt
CHANGED
|
@@ -3,3 +3,4 @@ tensorflow
|
|
| 3 |
pandas
|
| 4 |
numpy
|
| 5 |
scikit-learn
|
|
|
|
|
|
| 3 |
pandas
|
| 4 |
numpy
|
| 5 |
scikit-learn
|
| 6 |
+
matplotlib
|