Perunio commited on
Commit
54bdd46
1 Parent(s): 2d0a2c5
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.12.4-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY app/ /app/
6
+ COPY pyproject.toml /app
7
+
8
+ RUN pip install --no-cache-dir poetry
9
+
10
+ RUN poetry install --no-root
11
+
12
+ EXPOSE 7860
13
+
14
+ ENV GRADIO_SERVER_NAME="0.0.0.0"
15
+
16
+ CMD ["poetry", "run", "python", "gradio_app.py"]
app/.gradio/flagged/dataset1.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ TotalHouseArea,OverallQual,NeighborhoodPrice,GrLivArea,GarageEfficency,BuildingAge,KitchenQual,BsmtQual,GarageAge,TotalFullBath,RemodAge,GarageFinish,ExterScore,LotFrontage,TotRmsAbvGrd,BathPerBedroom,SalePrice,Predicted Value,timestamp
2
+ ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,2024-12-17 15:05:29.544565
3
+ ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,2024-12-17 15:05:35.128059
app/gradio_app.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import joblib
4
+ from pathlib import Path
5
+
6
+
7
+ def denormalize(data):
8
+ scaler = joblib.load("scaler.joblib")
9
+ data_denorm = scaler.inverse_transform(data)
10
+ denormalized_df = pd.DataFrame(data_denorm, columns=scaler.feature_names_in_)
11
+ return denormalized_df
12
+
13
+
14
+ def prepare_for_predict(*inputs):
15
+ scaler = joblib.load("scaler.joblib")
16
+
17
+ scaler_columns = scaler.feature_names_in_
18
+
19
+ predict_data = pd.DataFrame([inputs], columns=scaler_columns)
20
+
21
+ kitchen_qual_mapping = {
22
+ "Doskona艂a": 0,
23
+ "Dobra": 2,
24
+ "Ponadprzeci臋tna": 3,
25
+ "Przeci臋tna": 1,
26
+ }
27
+
28
+ bsmt_qual_mapping = {
29
+ "Doskona艂a": 0,
30
+ "Dobra": 2,
31
+ "Ponadprzeci臋tna": 3,
32
+ "Przeci臋tna": 1,
33
+ }
34
+
35
+ garage_finish_mapping = {
36
+ "Prawie wyko艅czony": 1,
37
+ "Niewyko艅czony": 2,
38
+ "Wyko艅czony": 0,
39
+ }
40
+
41
+ exter_score_mapping = {
42
+ "Doskona艂a": 10,
43
+ "Bardzo dobra": 9,
44
+ "Dobra": 8,
45
+ "Ponadprzeci臋tna": 7,
46
+ "Przeci臋tna": 6,
47
+ "S艂aba": 5,
48
+ "Bardzo s艂aba": 4,
49
+ }
50
+
51
+ predict_data["KitchenQual"] = kitchen_qual_mapping.get(
52
+ predict_data["KitchenQual"][0], None
53
+ )
54
+ predict_data["BsmtQual"] = bsmt_qual_mapping.get(predict_data["BsmtQual"][0], None)
55
+ predict_data["GarageFinish"] = garage_finish_mapping.get(
56
+ predict_data["GarageFinish"][0], None
57
+ )
58
+ predict_data["ExterScore"] = exter_score_mapping.get(
59
+ predict_data["ExterScore"][0], None
60
+ )
61
+
62
+ predict_data = scaler.transform(predict_data)
63
+
64
+ return predict_data
65
+
66
+
67
+ def predict(*inputs):
68
+ model = joblib.load("model1.joblib")
69
+
70
+ predict_data = prepare_for_predict(*inputs)
71
+
72
+ prediction = model.predict(predict_data)
73
+
74
+ return f"{prediction[0]:.2f} USD."
75
+
76
+
77
+ def app():
78
+ data = pd.read_csv(Path("prepared_train.csv"))
79
+ data = data.drop(["SalePrice"], axis=1)
80
+
81
+ columns = data.columns.tolist()
82
+
83
+ inputs = []
84
+
85
+ original_values = denormalize(data)
86
+ mean_values = original_values.mean()
87
+
88
+ feature_translation = {
89
+ "TotalHouseArea": "Ca艂kowita powierzchnia domu w stopach kwadratowych",
90
+ "OverallQual": "Og贸lna jako艣膰 budynku w skali od 0 do 10",
91
+ "NeighborhoodPrice": "艢rednia cena w s膮siedztwie",
92
+ "GrLivArea": "Powierzchnia mieszkalna nad poziomem gruntu w stopach kwadratowych",
93
+ "GarageEfficency": "Efektywno艣膰 gara偶u",
94
+ "BuildingAge": "Wiek budynku",
95
+ "KitchenQual": "Jako艣膰 kuchni",
96
+ "BsmtQual": "Jako艣膰 piwnicy",
97
+ "GarageAge": "Wiek gara偶u",
98
+ "TotalFullBath": "Liczba pe艂nych 艂azienek",
99
+ "RemodAge": "Wiek ostatniego remontu",
100
+ "GarageFinish": "Wyko艅czenie gara偶u",
101
+ "ExterScore": "Ocena stanu zewn臋trznego",
102
+ "LotFrontage": "Licznik metr贸w bie偶膮cych ulicy po艂膮czonej z nieruchomo艣ci膮",
103
+ "TotRmsAbvGrd": "Ilo艣膰 pokoi ponad poziomem gruntu",
104
+ "BathPerBedroom": "Stosunek 艂膮zienek do sypialni",
105
+ }
106
+
107
+ for col in columns:
108
+ if col == "KitchenQual":
109
+ inputs.append(
110
+ gr.Dropdown(
111
+ label=f"{col} ({feature_translation.get(col, 'Brak t艂umaczenia')})",
112
+ choices=["Doskona艂a", "Dobra", "Ponadprzeci臋tna", "Przeci臋tna"],
113
+ value="Dobra",
114
+ )
115
+ )
116
+ elif col == "BsmtQual":
117
+ inputs.append(
118
+ gr.Dropdown(
119
+ label=f"{col} ({feature_translation.get(col, 'Brak t艂umaczenia')})",
120
+ choices=["Doskona艂a", "Dobra", "Ponadprzeci臋tna", "Przeci臋tna"],
121
+ value="Dobra",
122
+ )
123
+ )
124
+ elif col == "OverallQual":
125
+ inputs.append(
126
+ gr.Dropdown(
127
+ label=f"{col} ({feature_translation.get(col, 'Brak t艂umaczenia')})",
128
+ choices=[10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
129
+ value=5,
130
+ )
131
+ )
132
+ elif col == "GarageFinish":
133
+ inputs.append(
134
+ gr.Dropdown(
135
+ label=f"{col} ({feature_translation.get(col, 'Brak t艂umaczenia')})",
136
+ choices=["Prawie wyko艅czony", "Niewyko艅czony", "Wyko艅czony"],
137
+ value="Wyko艅czony",
138
+ )
139
+ )
140
+ elif col == "ExterScore":
141
+ inputs.append(
142
+ gr.Dropdown(
143
+ label=f"{col} ({feature_translation.get(col, 'Brak t艂umaczenia')})",
144
+ choices=[
145
+ "Doskona艂a",
146
+ "Bardzo dobra",
147
+ "Dobra",
148
+ "Ponadprzeci臋tna",
149
+ "Przeci臋tna",
150
+ "S艂aba",
151
+ "Bardzo s艂aba",
152
+ ],
153
+ value="Dobra",
154
+ )
155
+ )
156
+ else:
157
+ mean_value = round(mean_values.get(col, 0), 0)
158
+ inputs.append(
159
+ gr.Number(
160
+ label=f"{col} ({feature_translation.get(col, 'Brak t艂umaczenia')})",
161
+ value=mean_value,
162
+ )
163
+ )
164
+
165
+ with gr.Blocks() as iface:
166
+ gr.Markdown("# Prognozowanie cen nieruchomo艣ci")
167
+ with gr.Row():
168
+ for i in range(0, len(inputs), 16):
169
+ for j in range(4):
170
+ with gr.Column():
171
+ for input_field in inputs[i + j * 4 : i + (j + 1) * 4]:
172
+ input_field.render()
173
+
174
+ predict_button = gr.Button("Prognozuj")
175
+ output = gr.Textbox(label="Przewidziana warto艣膰")
176
+
177
+ predict_button.click(fn=predict, inputs=inputs, outputs=output)
178
+
179
+ iface.launch()
180
+
181
+
182
+ if __name__ == "__main__":
183
+ app()
app/model1.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7fc752efab0870031db12763adef25236e9a7464d28c7dff36d6725facffff1d
3
+ size 122765461
app/prepared_train.csv ADDED
The diff for this file is too large to render. See raw diff
 
app/scaler.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:addd619c43d56bcff67128c5cec4038ea42b1d8aaf642e0739f64c9978df4bad
3
+ size 1895
pyproject.toml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [tool.poetry]
2
+ name = "praca-dyplomowa"
3
+ version = "0.2.0"
4
+ description = ""
5
+ authors = ["Perunio <divodar@protonmail.com>"]
6
+ readme = "README.md"
7
+
8
+ [tool.poetry.dependencies]
9
+ python = "^3.12"
10
+ scikit-learn = "^1.5.2"
11
+ scipy = "^1.14.1"
12
+ matplotlib = "^3.9.2"
13
+ seaborn = "^0.13.2"
14
+ ruff = "^0.7.4"
15
+ pytest = "^8.3.3"
16
+ optuna = {version = "^4.1.0", extras = ["dashboard"]}
17
+ optuna-dashboard = "^0.17.0"
18
+ aiohttp = "^3.11.10"
19
+ jinja2 = "^3.1.4"
20
+
21
+ pandas = "^2.2.3"
22
+ xgboost = "^2.1.3"
23
+ joblib = "^1.4.2"
24
+ gradio = "^5.9.1"
25
+
26
+
27
+ [build-system]
28
+ requires = ["poetry-core"]
29
+ build-backend = "poetry.core.masonry.api"