WebashalarForML commited on
Commit
43c7e13
·
verified ·
1 Parent(s): 3a9a11e

Upload 13 files

Browse files
Monitor_reports/regression_performance_at_training.html ADDED
The diff for this file is too large to render. See raw diff
 
Monitor_reports/regression_performance_at_training.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"version": "0.6.5", "metrics": [{"metric": "RegressionQualityMetric", "result": {"columns": {"utility_columns": {"date": null, "id": null, "target": "GrdAmt", "prediction": "adjusted_pred"}, "num_feature_names": ["EngAmt", "EngCts"], "cat_feature_names": ["Tag", "EngShp", "EngQua", "EngCol", "EngCut", "EngPol", "EngSym", "EngFlo", "EngNts", "EngMikly", "EngLab"], "text_feature_names": [], "datetime_feature_names": [], "target_names": null}, "current": {"r2_score": 0.9999923028920211, "rmse": 1.7576599997312332, "mean_error": 0.12982898322209938, "mean_abs_error": 1.4146422000467425, "mean_abs_perc_error": 0.36231777831306916, "abs_error_max": 3.0279654590704013, "underperformance": {"majority": {"mean_error": 0.12798954903896345, "std_error": 1.0911472758726741}, "underestimation": {"mean_error": -2.759110321710523, "std_error": NaN}, "overestimation": {"mean_error": 3.0279654590704013, "std_error": NaN}}, "error_std": 1.8933036280707416, "abs_error_std": 1.1267277727646234, "abs_perc_error_std": 0.003736499656151631}, "reference": null, "rmse_default": 633.5356812819848, "me_default_sigma": 1.8933036280707416, "mean_abs_error_default": 363.31442857142855, "mean_abs_perc_error_default": 47.842013429798385, "abs_error_max_default": 1763.2030000000002, "error_normality": {"order_statistic_medians_x": [-1.314872752547375, -0.7439764884519314, -0.3471943041728483, 0.0, 0.3471943041728483, 0.7439764884519314, 1.314872752547375], "order_statistic_medians_y": [-2.759110321710523, -1.347814805996677, -0.3899211311790509, 0.0004486202879263601, 1.0304255232912851, 1.3468095387913337, 3.0279654590704013], "slope": 2.103082399659136, "intercept": 0.12982898322209938, "r": 0.9941374379341389}, "error_bias": {"EngAmt": {"feature_type": "num", "current_majority": 601.6108571428571, "current_under": 1818.545, "current_over": 821.99, "current_range": 63.14647907315083}, "EngCts": {"feature_type": "num", "current_majority": 0.6328571428571428, "current_under": 1.01, "current_over": 0.96, "current_range": 7.042253521126767}, "Tag": {"feature_type": "cat", "current_majority": 0, "current_under": 0, "current_over": 0, "current_range": 0.0}, "EngShp": {"feature_type": "cat", "current_majority": 0, "current_under": 6, "current_over": 6, "current_range": 1.0}, "EngQua": {"feature_type": "cat", "current_majority": 7, "current_under": 7, "current_over": 2, "current_range": 1.0}, "EngCol": {"feature_type": "cat", "current_majority": 2, "current_under": 5, "current_over": 3, "current_range": 1.0}, "EngCut": {"feature_type": "cat", "current_majority": 5, "current_under": 2, "current_over": 5, "current_range": 1.0}, "EngPol": {"feature_type": "cat", "current_majority": 0, "current_under": 0, "current_over": 1, "current_range": 1.0}, "EngSym": {"feature_type": "cat", "current_majority": 1, "current_under": 0, "current_over": 1, "current_range": 1.0}, "EngFlo": {"feature_type": "cat", "current_majority": 2, "current_under": 2, "current_over": 2, "current_range": 0.0}, "EngNts": {"feature_type": "cat", "current_majority": 0, "current_under": 0, "current_over": 0, "current_range": 0.0}, "EngMikly": {"feature_type": "cat", "current_majority": 1, "current_under": 1, "current_over": 1, "current_range": 0.0}, "EngLab": {"feature_type": "cat", "current_majority": 1, "current_under": 1, "current_over": 1, "current_range": 0.0}}}}, {"metric": "RegressionPredictedVsActualScatter", "result": {}}, {"metric": "RegressionPredictedVsActualPlot", "result": {}}, {"metric": "RegressionErrorPlot", "result": {}}, {"metric": "RegressionAbsPercentageErrorPlot", "result": {}}, {"metric": "RegressionErrorDistribution", "result": {}}, {"metric": "RegressionErrorNormality", "result": {}}, {"metric": "RegressionTopErrorMetric", "result": {}}, {"metric": "RegressionErrorBiasTable", "result": {"top_error": -1.0, "target_name": "", "prediction_name": "", "num_feature_names": [], "cat_feature_names": [], "error_bias": null, "columns": null}}], "timestamp": "2025-03-07 15:33:42.729397"}
Monitor_reports/regression_performance_at_training_adjusted.html ADDED
The diff for this file is too large to render. See raw diff
 
Monitor_reports/regression_performance_at_training_gia_adjusted.html ADDED
The diff for this file is too large to render. See raw diff
 
Monitor_reports/regression_performance_at_training_gia_ogp.html ADDED
The diff for this file is too large to render. See raw diff
 
Monitor_reports/regression_performance_at_training_og.html ADDED
The diff for this file is too large to render. See raw diff
 
app2.py ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, redirect, url_for, flash, send_file
2
+ import os
3
+ import pandas as pd
4
+ from werkzeug.utils import secure_filename
5
+ from joblib import load
6
+ import numpy as np
7
+ from sklearn.preprocessing import OneHotEncoder, LabelEncoder
8
+ from sklearn.model_selection import train_test_split
9
+ from sklearn.preprocessing import StandardScaler
10
+ from sklearn.decomposition import PCA
11
+ from sklearn.pipeline import Pipeline
12
+ from sklearn.tree import DecisionTreeRegressor
13
+ from sklearn.ensemble import RandomForestRegressor
14
+ from sklearn.linear_model import LinearRegression
15
+ from xgboost import XGBRegressor
16
+ from sklearn.neighbors import KNeighborsRegressor
17
+ from sklearn.model_selection import cross_val_score
18
+ from sklearn.metrics import mean_squared_error
19
+ from sklearn import metrics
20
+ from sklearn.metrics.pairwise import cosine_similarity
21
+ from time import time
22
+
23
+ app = Flask(__name__)
24
+
25
+ # Set the secret key for session management
26
+ app.secret_key = os.urandom(24)
27
+
28
+ # Configurations
29
+ UPLOAD_FOLDER = "uploads/"
30
+ DATA_FOLDER = "data/"
31
+
32
+ # Define the model directory (ensuring correct path formatting)
33
+ MODEL_DIR = r'.\Model'
34
+ LABEL_ENOCDER_DIR = r'.\Label_encoders'
35
+
36
+ # Define the output file path
37
+ PRED_OUTPUT_FILE = "data/pred_output.csv"
38
+ CLASS_OUTPUT_FILE = "data/class_output.csv"
39
+
40
+ ALLOWED_EXTENSIONS = {'csv', 'xlsx'}
41
+
42
+ app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
43
+
44
+ # Ensure the upload folder exists
45
+ os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
46
+
47
+ # Load models using os.path.join for better cross-platform compatibility
48
+
49
+ # linear_regression_model
50
+ gia_model = load(os.path.join(MODEL_DIR, 'linear_regression_model_gia_price.joblib'))
51
+ grade_model = load(os.path.join(MODEL_DIR, 'linear_regression_model_grade_price.joblib'))
52
+ bygrade_model = load(os.path.join(MODEL_DIR, 'linear_regression_model_bygrade_price.joblib'))
53
+ makable_model = load(os.path.join(MODEL_DIR, 'linear_regression_model_makable_price.joblib'))
54
+
55
+ # classifier_model
56
+ col_model = load(os.path.join(MODEL_DIR, 'classification_LogisticRegression_col.joblib'))
57
+ cts_model = load(os.path.join(MODEL_DIR, 'classification_LogisticRegression_cts.joblib'))
58
+ cut_model = load(os.path.join(MODEL_DIR, 'classification_LogisticRegression_cut.joblib'))
59
+ qua_model = load(os.path.join(MODEL_DIR, 'classification_LogisticRegression_qua.joblib'))
60
+ shp_model = load(os.path.join(MODEL_DIR, 'classification_LogisticRegression_shp.joblib'))
61
+
62
+ # print("===================================models==================================")
63
+ # print(gia_model)
64
+ # print(grade_model)
65
+ # print(bygrade_model)
66
+ # print(makable_model)
67
+
68
+ # Load label encoders
69
+ encoder_list = ['Tag', 'EngShp', 'EngQua', 'EngCol', 'EngCut', 'EngPol', 'EngSym', 'EngFlo', 'EngNts', 'EngMikly', 'EngLab',
70
+ 'Change_cts_value', 'Change_shape_value', 'Change_quality_value', 'Change_color_value', 'Change_cut_value']
71
+ #loaded_label_encoder = {val: load(f"./Label_encoders/label_encoder_{val}.joblib") for val in encoder_list}
72
+ loaded_label_encoder = {}
73
+ for val in encoder_list:
74
+ #encoder_path = f"H:/DEV PATEL/2025/AI_In_Diamond_Industry/Label_encoders/label_encoder_{val}.joblib"
75
+ encoder_path = os.path.join(LABEL_ENOCDER_DIR, f"label_encoder_{val}.joblib")
76
+ loaded_label_encoder[val] = load(encoder_path)
77
+
78
+ # print(loaded_label_encoder)
79
+
80
+ # Ensure upload folder exists
81
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
82
+
83
+ def allowed_file(filename):
84
+ return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
85
+
86
+ @app.route('/')
87
+ def index():
88
+ return render_template('index.html')
89
+
90
+ @app.route('/predict', methods=['POST'])
91
+ def predict():
92
+ if 'file' not in request.files:
93
+ flash('No file part', 'error')
94
+ return redirect(request.url)
95
+
96
+ file = request.files['file']
97
+ if file.filename == '':
98
+ flash('No selected file', 'error')
99
+ return redirect(request.url)
100
+
101
+ if file and allowed_file(file.filename):
102
+ filename = secure_filename(file.filename)
103
+ filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
104
+ file.save(filepath)
105
+
106
+ # Convert to DataFrame
107
+ if filename.endswith('.csv'):
108
+ df = pd.read_csv(filepath)
109
+ else:
110
+ df = pd.read_excel(filepath)
111
+
112
+ # Preprocess DataFrame
113
+ print("===================================process_dataframe=0==================================")
114
+ df,dx = process_dataframe(df)
115
+ print("===================================process_dataframe=5==================================")
116
+ return render_template('output.html', df=df.to_html(), dx=dx.to_html())
117
+ else:
118
+ flash('Invalid file type. Only CSV and Excel files are allowed.', 'error')
119
+ print('Invalid file type. Only CSV and Excel files are allowed.')
120
+ return redirect(request.url)
121
+
122
+ def process_dataframe(df):
123
+ try:
124
+ print("===================================process_dataframe=1==================================")
125
+ # 'EngLab' is not in the required columns
126
+ required_columns = ['Tag', 'EngCts', 'EngShp', 'EngQua', 'EngCol', 'EngCut', 'EngPol',
127
+ 'EngSym', 'EngFlo', 'EngNts', 'EngMikly', 'EngAmt']
128
+
129
+ # for prediction
130
+ df = df[required_columns]
131
+ df = df.copy()
132
+ # for classification
133
+
134
+
135
+ # df[col] = df[col].map(lambda x: loaded_label_encoder[col].transform([x])[0] if x in loaded_label_encoder[col].classes_ else np.nan)
136
+
137
+ # Transform categorical features using loaded label encoders
138
+ df["Tag"] = loaded_label_encoder['Tag'].transform(df["Tag"])
139
+ df["EngShp"] = loaded_label_encoder['EngShp'].transform(df["EngShp"])
140
+ df["EngQua"] = loaded_label_encoder['EngQua'].transform(df["EngQua"])
141
+ df["EngCol"] = loaded_label_encoder['EngCol'].transform(df["EngCol"])
142
+ df["EngCut"] = loaded_label_encoder['EngCut'].transform(df["EngCut"])
143
+ df["EngPol"] = loaded_label_encoder['EngPol'].transform(df["EngPol"])
144
+ df["EngSym"] = loaded_label_encoder['EngSym'].transform(df["EngSym"])
145
+ df["EngFlo"] = loaded_label_encoder['EngFlo'].transform(df["EngFlo"])
146
+ df["EngNts"] = loaded_label_encoder['EngNts'].transform(df["EngNts"])
147
+ df["EngMikly"] = loaded_label_encoder['EngMikly'].transform(df["EngMikly"])
148
+ #EngLab = loaded_label_encoder['EngLab'].transform(df[EngLab])
149
+
150
+ df=df.astype(float)
151
+ print(df.head())
152
+
153
+ dx = df.copy()
154
+
155
+ print(df.columns)
156
+ x= df.copy()
157
+
158
+ # print("Model expects", gia_model.n_features_in_, "features.")
159
+ # print("X_features shape:", x.shape)
160
+
161
+ print("===================================process_dataframe=2==================================")
162
+
163
+ # ================================================================================================
164
+ # Prediction report
165
+ # ================================================================================================
166
+
167
+ # Predict prices
168
+ df['GIA_Predicted'] = gia_model.predict(x)
169
+ df['Grade_Predicted'] = grade_model.predict(x)
170
+ df['ByGrade_Predicted'] = bygrade_model.predict(x)
171
+ df['Makable_Predicted'] = makable_model.predict(x)
172
+
173
+
174
+ # Compute differences
175
+ df['GIA_Diff'] = df['EngAmt'] - df['GIA_Predicted']
176
+ df['Grade_Diff'] = df['EngAmt'] - df['Grade_Predicted']
177
+ df['ByGrade_Diff'] = df['EngAmt'] - df['ByGrade_Predicted']
178
+ df['Makable_Diff'] = df['EngAmt'] - df['Makable_Predicted']
179
+
180
+ print(df.head())
181
+
182
+ predictions = df.to_dict(orient='records')
183
+ analysis = df.describe().to_html()
184
+ #print(analysis)
185
+ #print(predictions)
186
+ print("===================================process_dataframe=3==================================")
187
+
188
+ # ================================================================================================
189
+ # Classification report
190
+ # ================================================================================================
191
+
192
+ dx['col_change'] = col_model.predict(x)
193
+ dx['cts_change'] = cts_model.predict(x)
194
+ dx['cut_change'] = cut_model.predict(x)
195
+ dx['qua_change'] = qua_model.predict(x)
196
+ dx['shp_change'] = shp_model.predict(x)
197
+
198
+ # Inverse transform the predictions
199
+ dx['col_change'] = loaded_label_encoder['Change_color_value'].inverse_transform(dx['col_change'])
200
+ dx['cts_change'] = loaded_label_encoder['Change_cts_value'].inverse_transform(dx['cts_change'])
201
+ dx['cut_change'] = loaded_label_encoder['Change_cut_value'].inverse_transform(dx['cut_change'])
202
+ dx['qua_change'] = loaded_label_encoder['Change_quality_value'].inverse_transform(dx['qua_change'])
203
+ dx['shp_change'] = loaded_label_encoder['Change_shape_value'].inverse_transform(dx['shp_change'])
204
+
205
+ print(dx.head())
206
+
207
+ print("===================================process_dataframe=4==================================")
208
+
209
+ # Save output file with date and time
210
+ time = str(pd.Timestamp.now().strftime("%Y-%m-%d"))
211
+
212
+ #saving the output file
213
+ global PRED_OUTPUT_FILE
214
+ PRED_OUTPUT_FILE = f'data/prediction_output_{time}.csv'
215
+ df.to_csv(PRED_OUTPUT_FILE, index=False)
216
+
217
+ #saving the output file
218
+ global CLASS_OUTPUT_FILE
219
+ CLASS_OUTPUT_FILE = f'data/classification_output_{time}.csv'
220
+ dx.to_csv(CLASS_OUTPUT_FILE, index=False)
221
+
222
+ print("===================================Output file saved as output.csv===================================")
223
+
224
+ return df.head(), dx.head()
225
+ except Exception as e:
226
+ print(f'Error processing file: {e}')
227
+ flash(f'Error processing file: {e}', 'error')
228
+ return pd.DataFrame(), pd.DataFrame()
229
+
230
+ def classification_report(df):
231
+ try:
232
+ classifcation_data = df[["EngGraphCts","EngCts","EngShp","EngQua","EngCol","EngCut","EngPol","EngSym","EngFlo","EngNts","EngMikly","EngLab","EngAmt",
233
+ "MkblCts","MkblShp","MkblQua","MkblCol","MkblCut","MkblPol","MkblSym","MkblFlo","MkblNts","MkblMikly","MkblLab","MkblAmt"]]
234
+
235
+ # Make predictions
236
+ classifcation_data["Cts_diff_eng_mkbl"] = round(classifcation_data["EngCts"] - classifcation_data["MkblCts"],2)
237
+
238
+ # Create a new column 'Change_Label' based on the values in 'Cts_diff_eng_mkbl'
239
+ classifcation_data['Change_cts_value'] = classifcation_data['Cts_diff_eng_mkbl'].apply(
240
+ lambda x: str(x)+' negative change' if x < 0 else (str(x)+' positive change' if x > 0 else 'no change')
241
+ )
242
+
243
+ # Create a new column 'Shape_Change' based on the values in 'EngShp' and 'MkblShp'
244
+ classifcation_data['Change_shape_value'] = classifcation_data.apply(
245
+ lambda row: str(row['EngShp'])+' to '+str(row['MkblShp'])+' shape change' if row['EngShp'] != row['MkblShp'] else 'shape not change', axis=1
246
+ )
247
+
248
+ # Create a new column 'quality_Change' based on the values in 'EngQua' and 'MkblQua'
249
+ classifcation_data['Change_quality_value'] = classifcation_data.apply(
250
+ lambda row: str(row['EngQua'])+' to '+str(row['MkblQua'])+' quality change' if row['EngQua'] != row['MkblQua'] else 'quality not change', axis=1
251
+ )
252
+
253
+ # Create a new column 'color_Change' based on the values in 'EngCol' and 'MkblCol'
254
+ classifcation_data['Change_color_value'] = classifcation_data.apply(
255
+ lambda row: str(row['EngCol'])+' to '+str(row['MkblCol'])+' color change' if row['EngCol'] != row['MkblCol'] else 'color not change', axis=1
256
+ )
257
+
258
+ # Create a new column 'cut_Change' based on the values in 'EngCut' and 'MkblCut'
259
+ classifcation_data['Change_cut_value'] = classifcation_data.apply(
260
+ lambda row: str(row['EngCut'])+' to '+str(row['MkblCut'])+' cut change' if row['EngCut'] != row['MkblCut'] else 'cut not change', axis=1
261
+ )
262
+
263
+ # Generate classification report
264
+
265
+
266
+ return classifcation_data
267
+ except Exception as e:
268
+ flash(f'Error generating classification report: {e}', 'error')
269
+ print(f'Error generating classification report: {e}')
270
+ return None
271
+
272
+ @app.route('/download_pred', methods=['GET'])
273
+ def download_pred():
274
+ """Serve the output.csv file for download."""
275
+ return send_file(PRED_OUTPUT_FILE, as_attachment=True)
276
+
277
+ @app.route('/download_class', methods=['GET'])
278
+ def download_class():
279
+ """Serve the output.csv file for download."""
280
+ return send_file(CLASS_OUTPUT_FILE, as_attachment=True)
281
+
282
+ if __name__ == "__main__":
283
+ app.run(debug=True)
requirement.txt ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ absl-py
2
+ asttokens
3
+ astunparse
4
+ blinker
5
+ certifi
6
+ charset-normalizer
7
+ click
8
+ colorama
9
+ comm
10
+ contourpy
11
+ cycler
12
+ debugpy
13
+ decorator
14
+ et_xmlfile
15
+ executing
16
+ filelock
17
+ Flask
18
+ flatbuffers
19
+ fonttools
20
+ fsspec
21
+ gast
22
+ google-pasta
23
+ grpcio
24
+ h5py
25
+ idna
26
+ ipykernel
27
+ ipython
28
+ itsdangerous
29
+ jedi
30
+ Jinja2
31
+ joblib
32
+ jupyter_client
33
+ jupyter_core
34
+ keras
35
+ kiwisolver
36
+ libclang
37
+ Markdown
38
+ markdown-it-py
39
+ MarkupSafe
40
+ matplotlib
41
+ matplotlib-inline
42
+ mdurl
43
+ ml-dtypes
44
+ mpmath
45
+ namex
46
+ nest-asyncio
47
+ networkx
48
+ numpy
49
+ openpyxl
50
+ opt_einsum
51
+ optree
52
+ packaging
53
+ pandas
54
+ parso
55
+ patsy
56
+ pillow
57
+ platformdirs
58
+ prompt_toolkit
59
+ protobuf
60
+ psutil
61
+ pure_eval
62
+ Pygments
63
+ pyparsing
64
+ python-dateutil
65
+ python-dotenv
66
+ pytz
67
+ pywin32
68
+ pyzmq
69
+ requests
70
+ rich
71
+ scikit-learn
72
+ scipy
73
+ seaborn
74
+ setuptools
75
+ six
76
+ stack-data
77
+ statsmodels
78
+ sympy
79
+ tensorboard
80
+ tensorboard-data-server
81
+ tensorflow
82
+ tensorflow_intel
83
+ termcolor
84
+ threadpoolctl
85
+ torch
86
+ torchaudio
87
+ torchvision
88
+ tornado
89
+ traitlets
90
+ typing_extensions
91
+ tzdata
92
+ urllib3
93
+ wcwidth
94
+ Werkzeug
95
+ wheel
96
+ wrapt
97
+ xgboost
templates/home.html ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Diamond Price Prediction</title>
6
+ <style>
7
+ body {
8
+ background-color: #041C32;
9
+ color: #ECB365;
10
+ font-family: Arial, sans-serif;
11
+ margin: 0;
12
+ padding: 20px;
13
+ }
14
+ .container {
15
+ max-width: 800px;
16
+ margin: auto;
17
+ background-color: #04293A;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ }
21
+ h1 {
22
+ color: #ECB365;
23
+ }
24
+ label {
25
+ display: block;
26
+ margin-top: 10px;
27
+ color: #ECB365;
28
+ }
29
+ input[type="text"],
30
+ input[type="number"],
31
+ select {
32
+ width: 100%;
33
+ padding: 8px;
34
+ margin-top: 5px;
35
+ border: 1px solid #064663;
36
+ border-radius: 4px;
37
+ background-color: #064663;
38
+ color: #ECB365;
39
+ box-sizing: border-box;
40
+ }
41
+ .btn {
42
+ margin-top: 20px;
43
+ padding: 10px 15px;
44
+ background-color: #ECB365;
45
+ color: #041C32;
46
+ border: none;
47
+ border-radius: 4px;
48
+ cursor: pointer;
49
+ font-weight: bold;
50
+ }
51
+ .flash {
52
+ padding: 10px;
53
+ margin-bottom: 15px;
54
+ border: 1px solid #ECB365;
55
+ background-color: #064663;
56
+ }
57
+ </style>
58
+ </head>
59
+ <body>
60
+ <div class="container">
61
+ <h1>Diamond Price Prediction</h1>
62
+ <p><strong>Note:</strong>there may be values missing in option due to less data.</p>
63
+ {% with messages = get_flashed_messages(with_categories=true) %}
64
+ {% if messages %}
65
+ {% for category, message in messages %}
66
+ <div class="flash">{{ message }}</div>
67
+ {% endfor %}
68
+ {% endif %}
69
+ {% endwith %}
70
+ <form action="{{ url_for('predict') }}" method="post">
71
+
72
+ <!-- Fixed dropdown fields -->
73
+ <label for="Tag">Tag (Category)</label>
74
+ <select id="Tag" name="Tag">
75
+ <option value="">Select Tag</option>
76
+ <option value="A">A</option>
77
+ <option value="B">B</option>
78
+ <option value="C">C</option>
79
+ <option value="D">D</option>
80
+ <option value="E">E</option>
81
+ <option value="F">F</option>
82
+ <option value="G">G</option>
83
+ <option value="H">H</option>
84
+ <option value="I">I</option>
85
+ </select>
86
+
87
+ <label for="EngShp">EngShp</label>
88
+ <select id="EngShp" name="EngShp">
89
+ <option value="">Select EngShp</option>
90
+ <option value="OV">OV</option>
91
+ <option value="MQ">MQ</option>
92
+ <option value="PE">PE</option>
93
+ <option value="R">R</option>
94
+ <option value="EM">EM</option>
95
+ <option value="HR">HR</option>
96
+ <option value="RD">RD</option>
97
+ <option value="PR">PR</option>
98
+ </select>
99
+
100
+ <label for="EngQua">EngQua</label>
101
+ <select id="EngQua" name="EngQua">
102
+ <option value="">Select EngQua</option>
103
+ <option value="SI2">SI2</option>
104
+ <option value="SI1">SI1</option>
105
+ <option value="VS2">VS2</option>
106
+ <option value="VVS2">VVS2</option>
107
+ <option value="VS1">VS1</option>
108
+ <option value="I2">I2</option>
109
+ <option value="I1">I1</option>
110
+ <option value="I2-">I2-</option>
111
+ <option value="I3">I3</option>
112
+ <option value="SI3">SI3</option>
113
+ <option value="I1-">I1-</option>
114
+ <option value="I4">I4</option>
115
+ <option value="I5">I5</option>
116
+ <option value="VVS1">VVS1</option>
117
+ </select>
118
+
119
+ <label for="EngCol">EngCol</label>
120
+ <select id="EngCol" name="EngCol">
121
+ <option value="">Select EngCol</option>
122
+ <option value="G">G</option>
123
+ <option value="F">F</option>
124
+ <option value="H">H</option>
125
+ <option value="E">E</option>
126
+ <option value="I">I</option>
127
+ <option value="J">J</option>
128
+ <option value="D">D</option>
129
+ <option value="L">L</option>
130
+ <option value="K">K</option>
131
+ <option value="M">M</option>
132
+ </select>
133
+
134
+ <label for="EngCut">EngCut</label>
135
+ <select id="EngCut" name="EngCut">
136
+ <option value="">Select EngCut</option>
137
+ <option value="EX3">EX3</option>
138
+ <option value="VG1">VG1</option>
139
+ <option value="EX1">EX1</option>
140
+ <option value="EX4">EX4</option>
141
+ <option value="EX2">EX2</option>
142
+ <option value="GD1">GD1</option>
143
+ </select>
144
+
145
+ <label for="EngPol">EngPol</label>
146
+ <select id="EngPol" name="EngPol">
147
+ <option value="">Select EngPol</option>
148
+ <option value="EX">EX</option>
149
+ <option value="VG">VG</option>
150
+ </select>
151
+
152
+ <label for="EngSym">EngSym</label>
153
+ <select id="EngSym" name="EngSym">
154
+ <option value="">Select EngSym</option>
155
+ <option value="EX">EX</option>
156
+ <option value="VG">VG</option>
157
+ </select>
158
+
159
+ <label for="EngFlo">EngFlo</label>
160
+ <select id="EngFlo" name="EngFlo">
161
+ <option value="">Select EngFlo</option>
162
+ <option value="Non">Non</option>
163
+ <option value="Fnt">Fnt</option>
164
+ <option value="Med">Med</option>
165
+ <option value="Str">Str</option>
166
+ <option value="VStr">VStr</option>
167
+ </select>
168
+
169
+ <label for="EngNts">EngNts</label>
170
+ <select id="EngNts" name="EngNts">
171
+ <option value="">Select EngNts</option>
172
+ <option value="N">N</option>
173
+ <option value="NTS2">NTS2</option>
174
+ <option value="NTS1">NTS1</option>
175
+ <option value="RSP-1">RSP-1</option>
176
+ </select>
177
+
178
+ <label for="EngMikly">EngMikly</label>
179
+ <select id="EngMikly" name="EngMikly">
180
+ <option value="">Select EngMikly</option>
181
+ <option value="N">N</option>
182
+ <option value="ML1">ML1</option>
183
+ <option value="Nv">Nv</option>
184
+ </select>
185
+
186
+ <label for="EngLab">EngLab</label>
187
+ <select id="EngLab" name="EngLab">
188
+ <option value="">Select EngLab</option>
189
+ <option value="nan">None</option>
190
+ <option value="IGI">IGI</option>
191
+ </select>
192
+
193
+ <!-- Other input fields remain for user to fill manually -->
194
+ <!-- <label for="ICarat">ICarat</label>
195
+ <input type="number" step="any" id="ICarat" name="ICarat" placeholder="Enter ICarat">
196
+
197
+ <label for="MkblCarat">MkblCarat</label>
198
+ <input type="number" step="any" id="MkblCarat" name="MkblCarat" placeholder="Enter MkblCarat">
199
+
200
+ <label for="SawLossCarat">SawLossCarat</label>
201
+ <input type="number" step="any" id="SawLossCarat" name="SawLossCarat" placeholder="Enter SawLossCarat">
202
+
203
+ <label for="CrapsCarat">CrapsCarat</label>
204
+ <input type="number" step="any" id="CrapsCarat" name="CrapsCarat" placeholder="Enter CrapsCarat">
205
+
206
+ <label for="EngGraphCts">EngGraphCts</label>
207
+ <input type="number" step="any" id="EngGraphCts" name="EngGraphCts" placeholder="Enter EngGraphCts"> -->
208
+
209
+ <label for="EngCts">EngCts</label>
210
+ <input type="number" step="any" id="EngCts" name="EngCts" placeholder="Enter EngCts">
211
+
212
+ <label for="EngAmt">EngAmt</label>
213
+ <input type="number" step="any" id="EngAmt" name="EngAmt" placeholder="Enter EngAmt">
214
+
215
+ <button type="submit" class="btn">Predict Price</button>
216
+ </form>
217
+ </div>
218
+ </body>
219
+ </html>
templates/index.html ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Diamond Price Prediction</title>
6
+ <style>
7
+ body {
8
+ background-color: #041C32;
9
+ color: #ECB365;
10
+ font-family: Arial, sans-serif;
11
+ margin: 0;
12
+ padding: 20px;
13
+ }
14
+ .container {
15
+ max-width: 800px;
16
+ margin: auto;
17
+ background-color: #04293A;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ }
21
+ h1 {
22
+ color: #ECB365;
23
+ text-align: center;
24
+ }
25
+ label {
26
+ display: block;
27
+ margin-top: 10px;
28
+ color: #ECB365;
29
+ }
30
+ input, select {
31
+ width: 100%;
32
+ padding: 8px;
33
+ margin-top: 5px;
34
+ border: 1px solid #064663;
35
+ border-radius: 4px;
36
+ background-color: #064663;
37
+ color: #ECB365;
38
+ box-sizing: border-box;
39
+ }
40
+ .btn {
41
+ margin-top: 20px;
42
+ padding: 10px 15px;
43
+ background-color: #ECB365;
44
+ color: #041C32;
45
+ border: none;
46
+ border-radius: 4px;
47
+ cursor: pointer;
48
+ font-weight: bold;
49
+ }
50
+ .upload-section {
51
+ margin-top: 20px;
52
+ padding: 15px;
53
+ border: 2px dashed #ECB365;
54
+ text-align: center;
55
+ }
56
+ </style>
57
+ </head>
58
+ <body>
59
+ <div class="container">
60
+ <h1>Diamond Price Prediction</h1>
61
+ <div class="upload-section">
62
+ <h3>Upload CSV or Excel for Bulk Prediction</h3>
63
+ <form action="{{ url_for('predict') }}" method="post" enctype="multipart/form-data">
64
+ <input type="file" name="file" accept=".csv, .xlsx" required>
65
+ <button type="submit" class="btn">Upload & Predict</button>
66
+ </form>
67
+ </div>
68
+ </div>
69
+ </body>
70
+ </html>
templates/output.html ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Prediction Result</title>
6
+ <style>
7
+ body {
8
+ background-color: #041C32;
9
+ color: #ECB365;
10
+ font-family: Arial, sans-serif;
11
+ margin: 0;
12
+ padding: 20px;
13
+ }
14
+ .container {
15
+ max-width: 900px;
16
+ margin: auto;
17
+ background-color: #04293A;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ text-align: center;
21
+ }
22
+ h1 {
23
+ color: #ECB365;
24
+ }
25
+ .result-box {
26
+ padding: 20px;
27
+ margin-top: 15px;
28
+ border: 2px solid #ECB365;
29
+ background-color: #064663;
30
+ font-size: 1em;
31
+ font-weight: normal;
32
+ border-radius: 5px;
33
+ }
34
+ .btn {
35
+ margin-top: 20px;
36
+ padding: 10px 15px;
37
+ background-color: #ECB365;
38
+ color: #041C32;
39
+ border: none;
40
+ border-radius: 4px;
41
+ cursor: pointer;
42
+ font-weight: bold;
43
+ display: inline-block;
44
+ text-decoration: none;
45
+ }
46
+ /* Styles for the table container */
47
+ .table-wrapper {
48
+ overflow-x: auto;
49
+ margin: auto;
50
+ max-width: 100%;
51
+ padding: 10px;
52
+ background-color: #04293A;
53
+ border-radius: 4px;
54
+ }
55
+ table {
56
+ width: 100%;
57
+ border-collapse: collapse;
58
+ color: #ECB365;
59
+ }
60
+ th, td {
61
+ border: 1px solid #ECB365;
62
+ padding: 8px;
63
+ text-align: center;
64
+ }
65
+ th {
66
+ background-color: #064663;
67
+ font-weight: bold;
68
+ }
69
+ </style>
70
+ </head>
71
+ <body>
72
+ <!--Prediction Report-->
73
+ <div class="container">
74
+ <h1>Predicted Diamond Price</h1>
75
+ <div class="result-box">
76
+ <p>The Prediction on diamond:</p>
77
+ <div class="table-wrapper">
78
+ {{ df|safe }}
79
+ </div>
80
+ </div>
81
+ <a href="{{ url_for('download_pred') }}" class="btn">Download CSV</a>
82
+ <a href="/" class="btn">Go Back</a>
83
+ </div>
84
+ <!--Analysis Report-->
85
+ <div class="container">
86
+ <h1>Analysis Diamond Parameter changes</h1>
87
+ <div class="result-box">
88
+ <p>The analysis on diamond:</p>
89
+ <div class="table-wrapper">
90
+ {{ dx|safe }}
91
+ </div>
92
+ </div>
93
+ <a href="{{ url_for('download_class') }}" class="btn">Download CSV</a>
94
+ <a href="/" class="btn">Go Back</a>
95
+ </div>
96
+ </body>
97
+ </html>
templates/results.html ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Prediction Results</title>
6
+ <style>
7
+ body {
8
+ background-color: #041C32;
9
+ color: #ECB365;
10
+ font-family: Arial, sans-serif;
11
+ margin: 0;
12
+ padding: 20px;
13
+ }
14
+ .container {
15
+ max-width: 600px;
16
+ margin: auto;
17
+ background-color: #04293A;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ }
21
+ h1 {
22
+ color: #ECB365;
23
+ text-align: center;
24
+ }
25
+ table {
26
+ width: 100%;
27
+ border-collapse: collapse;
28
+ margin-top: 20px;
29
+ }
30
+ th, td {
31
+ border: 1px solid #064663;
32
+ padding: 10px;
33
+ text-align: center;
34
+ }
35
+ th {
36
+ background-color: #064663;
37
+ }
38
+ .positive {
39
+ color: green;
40
+ font-weight: bold;
41
+ }
42
+ .negative {
43
+ color: red;
44
+ font-weight: bold;
45
+ }
46
+ .btn {
47
+ display: block;
48
+ margin: 20px auto 0;
49
+ padding: 10px 15px;
50
+ background-color: #ECB365;
51
+ color: #041C32;
52
+ border: none;
53
+ border-radius: 4px;
54
+ text-decoration: none;
55
+ font-weight: bold;
56
+ width: fit-content;
57
+ }
58
+ /* Tooltip container */
59
+ .tooltip {
60
+ position: relative;
61
+ display: inline-block;
62
+ cursor: pointer;
63
+ }
64
+ /* Tooltip text (info card) */
65
+ .tooltip .tooltip-content {
66
+ visibility: hidden;
67
+ width: 200px;
68
+ background-color: #ECB365;
69
+ color: #041C32;
70
+ text-align: center;
71
+ border-radius: 6px;
72
+ padding: 10px;
73
+ position: absolute;
74
+ z-index: 1;
75
+ bottom: 125%; /* Position above the text */
76
+ left: 50%;
77
+ transform: translateX(-50%);
78
+ opacity: 0;
79
+ transition: opacity 0.3s;
80
+ }
81
+ /* Tooltip arrow */
82
+ .tooltip .tooltip-content::after {
83
+ content: "";
84
+ position: absolute;
85
+ top: 100%; /* At the bottom of the tooltip */
86
+ left: 50%;
87
+ transform: translateX(-50%);
88
+ border-width: 5px;
89
+ border-style: solid;
90
+ border-color: #ECB365 transparent transparent transparent;
91
+ }
92
+ /* Show tooltip on hover */
93
+ .tooltip:hover .tooltip-content {
94
+ visibility: visible;
95
+ opacity: 1;
96
+ }
97
+ </style>
98
+ </head>
99
+ <body>
100
+ <div class="container">
101
+ <h1>Prediction Results</h1>
102
+ <p>Note: This is a demo model results, so results may vary and be weak on predictions.</p>
103
+ <table>
104
+ <tr>
105
+ <th>Model</th>
106
+ <th>Predicted Price</th>
107
+ <th>Difference (Price - EngAmt)</th>
108
+ </tr>
109
+ <tr>
110
+ <td>
111
+ <div class="tooltip">
112
+ GIA
113
+ <div class="tooltip-content">
114
+ <strong>Note:</strong> this GIA model is trainned over 372 records.
115
+ </div>
116
+ </div>
117
+ </td>
118
+ <td>{{ gia_price }}</td>
119
+ <td>
120
+ {% if gia_diff >= 0 %}
121
+ <span class="positive">{{ gia_diff }}</span>
122
+ {% else %}
123
+ <span class="negative">{{ gia_diff }}</span>
124
+ {% endif %}
125
+ </td>
126
+ </tr>
127
+ <tr>
128
+ <td>
129
+ <div class="tooltip">
130
+ Grade
131
+ <div class="tooltip-content">
132
+ <strong>Note:</strong> this Grade model is trainned over 641 records.
133
+ </div>
134
+ </div>
135
+ </td>
136
+ <td>{{ grade_price }}</td>
137
+ <td>
138
+ {% if grade_diff >= 0 %}
139
+ <span class="positive">{{ grade_diff }}</span>
140
+ {% else %}
141
+ <span class="negative">{{ grade_diff }}</span>
142
+ {% endif %}
143
+ </td>
144
+ </tr>
145
+ <tr>
146
+ <td>
147
+ <div class="tooltip">
148
+ By Grade
149
+ <div class="tooltip-content">
150
+ <strong>Note:</strong> this By Grade model is trainned over 641 records.
151
+ </div>
152
+ </div>
153
+ </td>
154
+ <td>{{ bygrade_price }}</td>
155
+ <td>
156
+ {% if bygrade_diff >= 0 %}
157
+ <span class="positive">{{ bygrade_diff }}</span>
158
+ {% else %}
159
+ <span class="negative">{{ bygrade_diff }}</span>
160
+ {% endif %}
161
+ </td>
162
+ </tr>
163
+ <tr>
164
+ <td>
165
+ <div class="tooltip">
166
+ Makable
167
+ <div class="tooltip-content">
168
+ <strong>Note:</strong> this Makable model is trainned over 1774 records.
169
+ </div>
170
+ </div>
171
+ </td>
172
+ <td>{{ makable_price }}</td>
173
+ <td>
174
+ {% if makable_diff >= 0 %}
175
+ <span class="positive">{{ makable_diff }}</span>
176
+ {% else %}
177
+ <span class="negative">{{ makable_diff }}</span>
178
+ {% endif %}
179
+ </td>
180
+ </tr>
181
+ </table>
182
+ <a href="{{ url_for('home') }}" class="btn">Make Another Prediction</a>
183
+ </div>
184
+ </body>
185
+ </html>
utils/tools.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from joblib import dump, load
2
+ import pandas as pd
3
+ from sklearn import metrics
4
+ from flask import flash
5
+ import numpy as np
6
+ import pandas as pd
7
+ from sklearn.preprocessing import LabelEncoder
8
+ from sklearn.metrics.pairwise import cosine_similarity
9
+ from sklearn import metrics
10
+
11
+
12
+ def data_similarity(df,pt,index,column,value):
13
+ # index fetch
14
+ index = np.where(pt.index==index)[0][0]
15
+ similarity_scores = cosine_similarity(pt)
16
+ similar_items = sorted(list(enumerate(similarity_scores[index])),key=lambda x:x[1],reverse=True)[1:2]
17
+
18
+ data = []
19
+ for i in similar_items:
20
+ item = []
21
+ temp_df = df[df['index'] == pt.index[i[0]]]
22
+ item.extend(list(temp_df.drop_duplicates(index)[value].values))
23
+ #item.extend(list(temp_df.drop_duplicates(index)[column].values))
24
+ #item.extend(list(temp_df.drop_duplicates(index)[index].values))
25
+
26
+ data.append(item)
27
+ list = [item.item() if isinstance(item, np.generic) else item for sublist in data for item in sublist]
28
+
29
+ original_values = [list['Change_cts_value'].inverse_transform([val]) for val in list]
30
+
31
+ return original_values
32
+
33
+ def recommendation_generator(df):
34
+ try:
35
+ pivot_cts = df.pivot_table(index='EngCts', columns='MkblCts', values='Change_cts_value')
36
+ pivot_shp = df.pivot_table(index='EngShp', columns='MkblShp', values='change_shape_value')
37
+ pivot_qua = df.pivot_table(index='EngQua', columns='MkblQua', values='Change_quality_value')
38
+ pivot_col = df.pivot_table(index='EngCol', columns='MkblCol', values='Change_color_value')
39
+ pivot_cut = df.pivot_table(index='EngCut', columns='MkblCut', values='Change_cut_value')
40
+
41
+ #==============================================================================
42
+ # # Recommendation
43
+ #==============================================================================
44
+ cts_data = data_similarity(df,pivot_cts,'EngCts','MkblCts','Change_cts_value')
45
+ shp_data = data_similarity(df,pivot_shp,'EngShp','MkblShp','Change_shape_value')
46
+ qua_data = data_similarity(df,pivot_qua,'EngQua','MkblQua','Change_quality_value')
47
+ col_data = data_similarity(df,pivot_col,'EngCol','MkblCol','Change_color_value')
48
+ cut_data = data_similarity(df,pivot_cut,'EngCut','MkblCut','Change_cut_value')
49
+
50
+ return cts_data,shp_data,qua_data,col_data,cut_data
51
+
52
+ except Exception as e:
53
+ flash(f'Error generating recommendation: {e}', 'error')
54
+ return None
55
+
56
+ def classification_report(df):
57
+ try:
58
+ classifcation_data = df[["EngGraphCts","EngCts","EngShp","EngQua","EngCol","EngCut","EngPol","EngSym","EngFlo","EngNts","EngMikly","EngLab","EngAmt",
59
+ "MkblCts","MkblShp","MkblQua","MkblCol","MkblCut","MkblPol","MkblSym","MkblFlo","MkblNts","MkblMikly","MkblLab","MkblAmt"]]
60
+
61
+ #==============================================================================
62
+ # # Feature Engineering to generate new columns
63
+ #==============================================================================
64
+ # Make predictions
65
+ classifcation_data["Cts_diff_eng_mkbl"] = round(classifcation_data["EngCts"] - classifcation_data["MkblCts"],2)
66
+
67
+ # Create a new column 'Change_Label' based on the values in 'Cts_diff_eng_mkbl'
68
+ classifcation_data['Change_cts_value'] = classifcation_data['Cts_diff_eng_mkbl'].apply(
69
+ lambda x: str(x)+' negative change' if x < 0 else (str(x)+' positive change' if x > 0 else 'no change')
70
+ )
71
+
72
+ # Create a new column 'Shape_Change' based on the values in 'EngShp' and 'MkblShp'
73
+ classifcation_data['Change_shape_value'] = classifcation_data.apply(
74
+ lambda row: str(row['EngShp'])+' to '+str(row['MkblShp'])+' shape change' if row['EngShp'] != row['MkblShp'] else 'shape not change', axis=1
75
+ )
76
+
77
+ # Create a new column 'quality_Change' based on the values in 'EngQua' and 'MkblQua'
78
+ classifcation_data['Change_quality_value'] = classifcation_data.apply(
79
+ lambda row: str(row['EngQua'])+' to '+str(row['MkblQua'])+' quality change' if row['EngQua'] != row['MkblQua'] else 'quality not change', axis=1
80
+ )
81
+
82
+ # Create a new column 'color_Change' based on the values in 'EngCol' and 'MkblCol'
83
+ classifcation_data['Change_color_value'] = classifcation_data.apply(
84
+ lambda row: str(row['EngCol'])+' to '+str(row['MkblCol'])+' color change' if row['EngCol'] != row['MkblCol'] else 'color not change', axis=1
85
+ )
86
+
87
+ # Create a new column 'cut_Change' based on the values in 'EngCut' and 'MkblCut'
88
+ classifcation_data['Change_cut_value'] = classifcation_data.apply(
89
+ lambda row: str(row['EngCut'])+' to '+str(row['MkblCut'])+' cut change' if row['EngCut'] != row['MkblCut'] else 'cut not change', axis=1
90
+ )
91
+
92
+ #==============================================================================
93
+ # # Label Encoding and storing the label encoders
94
+ #==============================================================================
95
+
96
+ # Get list of categorical variables
97
+ s = (classifcation_data.dtypes =="object")
98
+ object_cols = list(s[s].index)
99
+ print("Categorical variables:")
100
+ print(object_cols)
101
+
102
+ # Make copy to avoid changing original data
103
+ label_data = classifcation_data.copy()
104
+
105
+ # Apply label encoder to each column with categorical data
106
+ label_encoder = LabelEncoder()
107
+ for col in object_cols:
108
+ label_data[col] = label_encoder.fit_transform(label_data[col])
109
+ dump(label_encoder, f"./AI_In_Diamond_Industry/Label_encoders/label_encoder_{col}.joblib")
110
+
111
+ label_data.head()
112
+
113
+ #==============================================================================
114
+ # # recommendation_system
115
+ #==============================================================================
116
+ df=classifcation_data.copy()
117
+
118
+ =recommendation_generator(df)
119
+
120
+
121
+
122
+
123
+ return label_data
124
+ except Exception as e:
125
+ flash(f'Error generating classification report: {e}', 'error')
126
+ return None
127
+
128
+
129
+
130
+