Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1987,7 +1987,7 @@ with gr.Blocks(css=css, title="DataSynth β Analytics Hub") as demo:
|
|
| 1987 |
)
|
| 1988 |
|
| 1989 |
# Train model based on task type
|
| 1990 |
-
|
| 1991 |
scaler_type, do_rfecv, do_tuning,
|
| 1992 |
clustering_algo, n_clusters, eps, min_samples,
|
| 1993 |
rule_algo, trans_col, min_sup, min_conf, min_lft, max_len,
|
|
@@ -2188,121 +2188,128 @@ with gr.Blocks(css=css, title="DataSynth β Analytics Hub") as demo:
|
|
| 2188 |
detailed_df = cluster_stats
|
| 2189 |
|
| 2190 |
else: # Rule-Based
|
| 2191 |
-
|
| 2192 |
-
|
| 2193 |
-
|
| 2194 |
-
|
| 2195 |
-
|
| 2196 |
-
if not transactions:
|
| 2197 |
-
return "No valid transactions found in the data.", None, None
|
| 2198 |
-
|
| 2199 |
-
# Run Apriori
|
| 2200 |
-
frequent_itemsets, rules = run_association_mining(
|
| 2201 |
-
transactions,
|
| 2202 |
-
min_support=min_sup,
|
| 2203 |
-
min_confidence=min_conf,
|
| 2204 |
-
min_lift=min_lft
|
| 2205 |
-
)
|
| 2206 |
-
|
| 2207 |
-
results_summary = f"## π Simple Apriori Association Rules\n\n"
|
| 2208 |
-
|
| 2209 |
-
else: # Frequency-Based Rules
|
| 2210 |
-
# Identify categorical columns
|
| 2211 |
-
cat_cols = df.select_dtypes(include=['object', 'category']).columns.tolist()
|
| 2212 |
-
if not cat_cols:
|
| 2213 |
-
# Try to use all columns as categorical
|
| 2214 |
-
cat_cols = df.columns.tolist()
|
| 2215 |
-
|
| 2216 |
-
rules_list = run_frequency_based_rules(
|
| 2217 |
-
df,
|
| 2218 |
-
categorical_cols=cat_cols,
|
| 2219 |
-
min_frequency=min_sup,
|
| 2220 |
-
min_cooccurrence=min_conf
|
| 2221 |
-
)
|
| 2222 |
-
|
| 2223 |
-
# Convert to rules format similar to Apriori
|
| 2224 |
-
rules = []
|
| 2225 |
-
for rule in rules_list:
|
| 2226 |
-
rules.append({
|
| 2227 |
-
'antecedents': {rule['antecedent']},
|
| 2228 |
-
'consequents': {rule['consequent']},
|
| 2229 |
-
'support': rule['support'],
|
| 2230 |
-
'confidence': rule['confidence'],
|
| 2231 |
-
'lift': rule['lift'],
|
| 2232 |
-
'rule_str': rule['rule']
|
| 2233 |
-
})
|
| 2234 |
-
|
| 2235 |
-
results_summary = f"## π Frequency-Based Association Rules\n\n"
|
| 2236 |
|
| 2237 |
-
if not
|
| 2238 |
-
return "No
|
| 2239 |
|
| 2240 |
-
|
| 2241 |
-
|
| 2242 |
-
|
| 2243 |
-
|
|
|
|
|
|
|
|
|
|
| 2244 |
|
| 2245 |
-
#
|
| 2246 |
-
top_rules = rules[:10]
|
| 2247 |
-
results_summary += "### π Top 10 Rules by Confidence\n\n"
|
| 2248 |
-
for idx, rule in enumerate(top_rules):
|
| 2249 |
-
if 'rule_str' in rule:
|
| 2250 |
-
rule_text = rule['rule_str']
|
| 2251 |
-
else:
|
| 2252 |
-
antecedents = ', '.join(list(rule['antecedents']))
|
| 2253 |
-
consequents = ', '.join(list(rule['consequents']))
|
| 2254 |
-
rule_text = f"IF {antecedents} THEN {consequents}"
|
| 2255 |
-
|
| 2256 |
-
results_summary += f"{idx+1}. **{rule_text}** \n"
|
| 2257 |
-
results_summary += f" Support: {rule['support']:.3f}, Confidence: {rule['confidence']:.3f}, Lift: {rule['lift']:.3f}\n\n"
|
| 2258 |
|
| 2259 |
-
|
| 2260 |
-
|
| 2261 |
-
|
| 2262 |
-
|
| 2263 |
-
|
| 2264 |
-
|
| 2265 |
-
|
| 2266 |
-
|
| 2267 |
-
|
| 2268 |
-
|
| 2269 |
-
|
| 2270 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2271 |
'support': rule['support'],
|
| 2272 |
'confidence': rule['confidence'],
|
| 2273 |
-
'lift': rule['lift']
|
|
|
|
| 2274 |
})
|
| 2275 |
|
| 2276 |
-
|
| 2277 |
-
|
| 2278 |
-
|
| 2279 |
-
|
| 2280 |
-
|
| 2281 |
-
|
| 2282 |
-
|
| 2283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2284 |
|
| 2285 |
-
|
| 2286 |
-
|
| 2287 |
-
|
| 2288 |
-
|
| 2289 |
-
|
| 2290 |
-
|
| 2291 |
-
|
| 2292 |
-
|
| 2293 |
-
|
| 2294 |
-
|
| 2295 |
-
|
| 2296 |
-
|
| 2297 |
-
'Support': f"{rule['support']:.3f}",
|
| 2298 |
-
'Confidence': f"{rule['confidence']:.3f}",
|
| 2299 |
-
'Lift': f"{rule['lift']:.3f}"
|
| 2300 |
-
})
|
| 2301 |
|
| 2302 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2303 |
|
| 2304 |
-
|
| 2305 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2306 |
|
| 2307 |
train_btn.click(
|
| 2308 |
fn=train_model_wrapper,
|
|
|
|
| 1987 |
)
|
| 1988 |
|
| 1989 |
# Train model based on task type
|
| 1990 |
+
def train_model_wrapper(task_type, model_name, dataset_choice, target_var,
|
| 1991 |
scaler_type, do_rfecv, do_tuning,
|
| 1992 |
clustering_algo, n_clusters, eps, min_samples,
|
| 1993 |
rule_algo, trans_col, min_sup, min_conf, min_lft, max_len,
|
|
|
|
| 2188 |
detailed_df = cluster_stats
|
| 2189 |
|
| 2190 |
else: # Rule-Based
|
| 2191 |
+
try:
|
| 2192 |
+
if rule_algo == "Apriori (Simple)":
|
| 2193 |
+
# Prepare transaction data
|
| 2194 |
+
transactions = prepare_transaction_data(df, trans_col if trans_col else None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2195 |
|
| 2196 |
+
if not transactions:
|
| 2197 |
+
return "No valid transactions found in the data.", None, None
|
| 2198 |
|
| 2199 |
+
# Run Apriori
|
| 2200 |
+
frequent_itemsets, rules = run_association_mining(
|
| 2201 |
+
transactions,
|
| 2202 |
+
min_support=min_sup,
|
| 2203 |
+
min_confidence=min_conf,
|
| 2204 |
+
min_lift=min_lft
|
| 2205 |
+
)
|
| 2206 |
|
| 2207 |
+
results_summary = f"## π Simple Apriori Association Rules\n\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2208 |
|
| 2209 |
+
else: # Frequency-Based Rules
|
| 2210 |
+
# Identify categorical columns
|
| 2211 |
+
cat_cols = df.select_dtypes(include=['object', 'category']).columns.tolist()
|
| 2212 |
+
if not cat_cols:
|
| 2213 |
+
# Try to use all columns as categorical
|
| 2214 |
+
cat_cols = df.columns.tolist()
|
| 2215 |
+
|
| 2216 |
+
rules_list = run_frequency_based_rules(
|
| 2217 |
+
df,
|
| 2218 |
+
categorical_cols=cat_cols,
|
| 2219 |
+
min_frequency=min_sup,
|
| 2220 |
+
min_cooccurrence=min_conf
|
| 2221 |
+
)
|
| 2222 |
+
|
| 2223 |
+
# Convert to rules format similar to Apriori
|
| 2224 |
+
rules = []
|
| 2225 |
+
for rule in rules_list:
|
| 2226 |
+
rules.append({
|
| 2227 |
+
'antecedents': {rule['antecedent']},
|
| 2228 |
+
'consequents': {rule['consequent']},
|
| 2229 |
'support': rule['support'],
|
| 2230 |
'confidence': rule['confidence'],
|
| 2231 |
+
'lift': rule['lift'],
|
| 2232 |
+
'rule_str': rule['rule']
|
| 2233 |
})
|
| 2234 |
|
| 2235 |
+
results_summary = f"## π Frequency-Based Association Rules\n\n"
|
| 2236 |
+
|
| 2237 |
+
if not rules:
|
| 2238 |
+
return "No association rules found with the given parameters.", None, None
|
| 2239 |
+
|
| 2240 |
+
results_summary += f"- **Total rules found:** {len(rules)}\n"
|
| 2241 |
+
results_summary += f"- **Minimum support:** {min_sup}\n"
|
| 2242 |
+
results_summary += f"- **Minimum confidence:** {min_conf}\n"
|
| 2243 |
+
results_summary += f"- **Minimum lift:** {min_lft}\n\n"
|
| 2244 |
+
|
| 2245 |
+
# Top 10 rules by confidence
|
| 2246 |
+
top_rules = rules[:10]
|
| 2247 |
+
results_summary += "### π Top 10 Rules by Confidence\n\n"
|
| 2248 |
+
for idx, rule in enumerate(top_rules):
|
| 2249 |
+
if 'rule_str' in rule:
|
| 2250 |
+
rule_text = rule['rule_str']
|
| 2251 |
+
else:
|
| 2252 |
+
antecedents = ', '.join(list(rule['antecedents']))
|
| 2253 |
+
consequents = ', '.join(list(rule['consequents']))
|
| 2254 |
+
rule_text = f"IF {antecedents} THEN {consequents}"
|
| 2255 |
|
| 2256 |
+
results_summary += f"{idx+1}. **{rule_text}** \n"
|
| 2257 |
+
results_summary += f" Support: {rule['support']:.3f}, Confidence: {rule['confidence']:.3f}, Lift: {rule['lift']:.3f}\n\n"
|
| 2258 |
+
|
| 2259 |
+
# Prepare rules for visualization
|
| 2260 |
+
plot_data = []
|
| 2261 |
+
for rule in rules[:20]: # Limit to 20 for plotting
|
| 2262 |
+
if 'rule_str' in rule:
|
| 2263 |
+
rule_name = rule['rule_str'][:50] + "..." if len(rule['rule_str']) > 50 else rule['rule_str']
|
| 2264 |
+
else:
|
| 2265 |
+
antecedents = ', '.join(list(rule['antecedents']))[:20]
|
| 2266 |
+
consequents = ', '.join(list(rule['consequents']))[:20]
|
| 2267 |
+
rule_name = f"{antecedents}β{consequents}"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2268 |
|
| 2269 |
+
plot_data.append({
|
| 2270 |
+
'rule': rule_name,
|
| 2271 |
+
'support': rule['support'],
|
| 2272 |
+
'confidence': rule['confidence'],
|
| 2273 |
+
'lift': rule['lift']
|
| 2274 |
+
})
|
| 2275 |
+
|
| 2276 |
+
if plot_data:
|
| 2277 |
+
plot_df = pd.DataFrame(plot_data)
|
| 2278 |
+
fig = px.scatter(plot_df, x='support', y='confidence',
|
| 2279 |
+
size='lift', color='lift',
|
| 2280 |
+
hover_name='rule',
|
| 2281 |
+
title=f'{rule_algo} Association Rules',
|
| 2282 |
+
labels={'support': 'Support', 'confidence': 'Confidence'})
|
| 2283 |
+
plot_fig = fig
|
| 2284 |
+
|
| 2285 |
+
# Prepare detailed results
|
| 2286 |
+
detailed_data = []
|
| 2287 |
+
for rule in rules[:20]:
|
| 2288 |
+
if 'rule_str' in rule:
|
| 2289 |
+
rule_str = rule['rule_str']
|
| 2290 |
+
else:
|
| 2291 |
+
antecedents = ', '.join(list(rule['antecedents']))
|
| 2292 |
+
consequents = ', '.join(list(rule['consequents']))
|
| 2293 |
+
rule_str = f"{antecedents} β {consequents}"
|
| 2294 |
|
| 2295 |
+
detailed_data.append({
|
| 2296 |
+
'Rule': rule_str,
|
| 2297 |
+
'Support': f"{rule['support']:.3f}",
|
| 2298 |
+
'Confidence': f"{rule['confidence']:.3f}",
|
| 2299 |
+
'Lift': f"{rule['lift']:.3f}"
|
| 2300 |
+
})
|
| 2301 |
+
|
| 2302 |
+
detailed_df = pd.DataFrame(detailed_data)
|
| 2303 |
+
|
| 2304 |
+
except Exception as e:
|
| 2305 |
+
return f"Error in rule-based mining: {str(e)}", None, None
|
| 2306 |
+
|
| 2307 |
+
# Return successful results
|
| 2308 |
+
return results_summary, plot_fig, detailed_df
|
| 2309 |
+
|
| 2310 |
+
except Exception as e:
|
| 2311 |
+
traceback.print_exc()
|
| 2312 |
+
return f"Error in model training: {str(e)}", None, None
|
| 2313 |
|
| 2314 |
train_btn.click(
|
| 2315 |
fn=train_model_wrapper,
|