itou-daiki commited on
Commit
9e5faab
·
verified ·
1 Parent(s): f4dc268

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +28 -49
  2. common.py +48 -0
app.py CHANGED
@@ -11,10 +11,12 @@ import shap
11
  from pycaret.regression import *
12
  from sklearn.tree import plot_tree
13
  from sklearn.inspection import permutation_importance
 
 
14
  import matplotlib.font_manager as fm
15
 
16
  # フォントファイルのパスを指定
17
- font_path = 'ipaexg.ttf' # フォントファイルのパスを正確に指定してください
18
 
19
  # フォントプロパティを作成
20
  font_prop = fm.FontProperties(fname=font_path)
@@ -49,7 +51,7 @@ if 'model_configs' not in st.session_state:
49
 
50
  # メインアプリケーション
51
  st.title("easyAutoML(回帰)")
52
- st.caption("Created by Dit-Lab.(Daiki Ito)")
53
 
54
  with st.expander("このアプリケーションについて", expanded=False):
55
  st.markdown("""
@@ -93,15 +95,6 @@ with st.expander("このアプリケーションについて", expanded=False):
93
  - トレーニング済みモデルのダウンロード
94
  """)
95
 
96
- st.markdown("### 💡 使用方法")
97
- st.markdown("""
98
- 1. CSVまたはExcelファイルをアップロード
99
- 2. 予測したい目的変数を選択
100
- 3. モデルの比較と選択
101
- 4. 選択したモデルのチューニングと評価
102
- 5. 最終モデルの保存
103
- """)
104
-
105
  st.info("⚠️ 注意: データの前処理(欠損値の処理など)は自動的に行われますが、データの品質が結果に大きく影響します。")
106
 
107
  # 1. データアップロード部分
@@ -196,9 +189,17 @@ if uploaded_file is not None:
196
  st.session_state.model_configs['ignore_features'] = ignore_features
197
 
198
  # データ処理オプション
199
- col1, col2 = st.columns(2)
200
  with col1:
201
  remove_outliers = st.checkbox('外れ値を除去する', value=False)
 
 
 
 
 
 
 
 
202
 
203
  # モデル比較の実行
204
  if st.button('モデルの比較を開始', use_container_width=True):
@@ -208,19 +209,23 @@ if uploaded_file is not None:
208
  progress_bar = st.progress(0)
209
  status_text = st.empty()
210
 
211
- # データのセットアップ
212
  status_text.text("データの前処理を実行中...")
213
  progress_bar.progress(20)
214
 
215
- # セットアップの実行
216
- setup_data = setup(
217
- data=data,
218
- target=target_variable,
219
- ignore_features=ignore_features,
220
- remove_outliers=remove_outliers,
221
- session_id=123,
222
- verbose=False
223
- )
 
 
 
 
224
 
225
  # 特徴量の保存
226
  X_train = get_config('X_train')
@@ -385,9 +390,7 @@ if uploaded_file is not None:
385
  fig, ax = plt.subplots(figsize=(10, 6))
386
  sns.barplot(data=importance_df, x='重要度', y='特徴量', ax=ax)
387
  st.pyplot(fig)
388
- # キャプションを追加
389
  st.caption("**モデルが学習した結果、各特徴量が目的変数の予測にどれだけ寄与したかを示しています。重要度が高い特徴量ほど、モデルの予測に大きな影響を与えています。**")
390
- # データフレームを表示
391
  with st.expander("特徴量重要度データ", expanded=False):
392
  st.dataframe(importance_df, use_container_width=True)
393
  else:
@@ -399,16 +402,12 @@ if uploaded_file is not None:
399
  st.write("SHAP値による特徴量重要度")
400
  with st.spinner('SHAP値を計算中...'):
401
  try:
402
- # SHAP値の計算
403
  explainer = shap.Explainer(model, X_train_transformed)
404
  shap_values = explainer(X_train_transformed)
405
- # SHAPサマリープロット
406
  shap.summary_plot(shap_values, X_train_transformed, plot_type="bar", show=False)
407
  st.pyplot(plt.gcf())
408
- # キャプションを追加
409
  st.caption("**SHAP値に基づく特徴量の重要度を示しています。各特徴量が予測結果に与える影響を定量的に評価できます。(青:正の影響 緑:負の影響)**")
410
  plt.clf()
411
- # SHAP値をデータフレームで表示
412
  with st.expander("SHAP値データ", expanded=False):
413
  shap_df = pd.DataFrame({
414
  '特徴量': feature_names,
@@ -437,7 +436,6 @@ if uploaded_file is not None:
437
  plot_model(model, plot='error', display_format="streamlit")
438
  st.caption("予測値と実測値の差を示しています。誤差が小さいほど、モデルの予測精度が高いことを示します。")
439
 
440
- # 追加の評価図を表示
441
  col3, col4 = st.columns(2)
442
  with col3:
443
  st.write("学習曲線")
@@ -458,8 +456,6 @@ if uploaded_file is not None:
458
  try:
459
  with st.spinner('決定木を可視化中...'):
460
  if selected_model == 'dt':
461
- # 決定木モデルの場合、直接ツリーをプロット
462
- # 図を描画
463
  fig, ax = plt.subplots(figsize=(40, 20))
464
  plot_tree(
465
  model,
@@ -472,14 +468,10 @@ if uploaded_file is not None:
472
  st.pyplot(fig)
473
  st.caption("決定木の構造を表示しています。")
474
  else:
475
- # ランダムフォレストや勾配ブースティングなどの場合
476
  from sklearn.metrics import mean_squared_error
477
-
478
- # テストデータを取得
479
  X_test_transformed = get_config('X_test_transformed')
480
  y_test = get_config('y_test')
481
 
482
- # 各決定木の性能を評価
483
  if selected_model in ['rf', 'et']:
484
  estimators = model.estimators_
485
  elif selected_model == 'gbr':
@@ -511,10 +503,8 @@ if uploaded_file is not None:
511
  best_score = mse
512
  best_estimator_index = idx
513
 
514
- # ベストなツリーを取得
515
  if selected_model in ['rf', 'et', 'gbr']:
516
  best_tree = estimators[best_estimator_index]
517
- # 図を描画
518
  fig, ax = plt.subplots(figsize=(40, 20))
519
  plot_tree(
520
  best_tree,
@@ -527,7 +517,6 @@ if uploaded_file is not None:
527
  st.pyplot(fig)
528
  st.caption(f"ベストな決定木(ツリー番号: {best_estimator_index})の構造を表示しています。")
529
  elif selected_model == 'xgboost':
530
- # xgboostの場合
531
  import xgboost as xgb
532
  booster = model.get_booster()
533
  fig, ax = plt.subplots(figsize=(40, 20))
@@ -535,7 +524,6 @@ if uploaded_file is not None:
535
  st.pyplot(fig)
536
  st.caption(f"ベストな決定木(ツリー番号: {best_estimator_index})の構造を表示しています。")
537
  elif selected_model == 'lightgbm':
538
- # lightgbmの場合
539
  import lightgbm as lgb
540
  graph = lgb.create_tree_digraph(model, tree_index=best_estimator_index)
541
  st.graphviz_chart(graph)
@@ -555,18 +543,15 @@ if uploaded_file is not None:
555
  progress_bar = st.progress(0)
556
  status_text = st.empty()
557
 
558
- # モデルのファイナライズ
559
  status_text.text("モデルをファイナライズ中...")
560
  progress_bar.progress(30)
561
  final_model = finalize_model(model)
562
 
563
- # 最終評価
564
  status_text.text("最終評価を実行中...")
565
  progress_bar.progress(60)
566
  predictions = predict_model(final_model)
567
  final_scores = pull()
568
 
569
- # 評価結果の表示
570
  st.subheader("ファイナルモデルの評価結果")
571
  col1, col2 = st.columns(2)
572
  with col1:
@@ -576,19 +561,14 @@ if uploaded_file is not None:
576
  st.write("ファイナライズ後の評価結果")
577
  st.dataframe(final_scores, use_container_width=True)
578
 
579
-
580
- # 目的変数の名前をモデルに保存
581
  final_model.target_column = target_variable
582
 
583
- # モデルの保存
584
  status_text.text("モデルを保存中...")
585
  progress_bar.progress(90)
586
  model_name = f"{target_variable}_finalized_model"
587
 
588
- # モデルの保存
589
  save_model(final_model, model_name)
590
 
591
- # モデルの読み込み
592
  with open(f"{model_name}.pkl", 'rb') as f:
593
  model_bytes = f.read()
594
 
@@ -611,5 +591,4 @@ if uploaded_file is not None:
611
  st.error(f"予期せぬエラーが発生しました: {str(e)}")
612
 
613
  # コピーライト情報
614
- st.markdown("---")
615
- st.caption('© 2022-2024 Dit-Lab.(Daiki Ito). All Rights Reserved.')
 
11
  from pycaret.regression import *
12
  from sklearn.tree import plot_tree
13
  from sklearn.inspection import permutation_importance
14
+ import common
15
+
16
  import matplotlib.font_manager as fm
17
 
18
  # フォントファイルのパスを指定
19
+ font_path = 'ipaexg.ttf'
20
 
21
  # フォントプロパティを作成
22
  font_prop = fm.FontProperties(fname=font_path)
 
51
 
52
  # メインアプリケーション
53
  st.title("easyAutoML(回帰)")
54
+ common.display_header()
55
 
56
  with st.expander("このアプリケーションについて", expanded=False):
57
  st.markdown("""
 
95
  - トレーニング済みモデルのダウンロード
96
  """)
97
 
 
 
 
 
 
 
 
 
 
98
  st.info("⚠️ 注意: データの前処理(欠損値の処理など)は自動的に行われますが、データの品質が結果に大きく影響します。")
99
 
100
  # 1. データアップロード部分
 
189
  st.session_state.model_configs['ignore_features'] = ignore_features
190
 
191
  # データ処理オプション
192
+ col1, col2, col3 = st.columns(3)
193
  with col1:
194
  remove_outliers = st.checkbox('外れ値を除去する', value=False)
195
+ with col2:
196
+ pca_option = st.checkbox('PCAを適用する', value=False)
197
+ with col3:
198
+ if pca_option:
199
+ max_components = len(data.columns) - 1 # 目的変数を除く
200
+ pca_components = st.slider('主成分の数', min_value=1, max_value=max_components, value=min(10, max_components))
201
+ else:
202
+ pca_components = None
203
 
204
  # モデル比較の実行
205
  if st.button('モデルの比較を開始', use_container_width=True):
 
209
  progress_bar = st.progress(0)
210
  status_text = st.empty()
211
 
212
+ # データの前処理
213
  status_text.text("データの前処理を実行中...")
214
  progress_bar.progress(20)
215
 
216
+ # setup() に PCA 関連のパラメータを追加
217
+ setup_params = {
218
+ 'data': data,
219
+ 'target': target_variable,
220
+ 'ignore_features': ignore_features,
221
+ 'remove_outliers': remove_outliers,
222
+ 'session_id': 123,
223
+ 'verbose': False,
224
+ 'pca': pca_option
225
+ }
226
+ if pca_option:
227
+ setup_params['pca_components'] = pca_components
228
+ setup_data = setup(**setup_params)
229
 
230
  # 特徴量の保存
231
  X_train = get_config('X_train')
 
390
  fig, ax = plt.subplots(figsize=(10, 6))
391
  sns.barplot(data=importance_df, x='重要度', y='特徴量', ax=ax)
392
  st.pyplot(fig)
 
393
  st.caption("**モデルが学習した結果、各特徴量が目的変数の予測にどれだけ寄与したかを示しています。重要度が高い特徴量ほど、モデルの予測に大きな影響を与えています。**")
 
394
  with st.expander("特徴量重要度データ", expanded=False):
395
  st.dataframe(importance_df, use_container_width=True)
396
  else:
 
402
  st.write("SHAP値による特徴量重要度")
403
  with st.spinner('SHAP値を計算中...'):
404
  try:
 
405
  explainer = shap.Explainer(model, X_train_transformed)
406
  shap_values = explainer(X_train_transformed)
 
407
  shap.summary_plot(shap_values, X_train_transformed, plot_type="bar", show=False)
408
  st.pyplot(plt.gcf())
 
409
  st.caption("**SHAP値に基づく特徴量の重要度を示しています。各特徴量が予測結果に与える影響を定量的に評価できます。(青:正の影響 緑:負の影響)**")
410
  plt.clf()
 
411
  with st.expander("SHAP値データ", expanded=False):
412
  shap_df = pd.DataFrame({
413
  '特徴量': feature_names,
 
436
  plot_model(model, plot='error', display_format="streamlit")
437
  st.caption("予測値と実測値の差を示しています。誤差が小さいほど、モデルの予測精度が高いことを示します。")
438
 
 
439
  col3, col4 = st.columns(2)
440
  with col3:
441
  st.write("学習曲線")
 
456
  try:
457
  with st.spinner('決定木を可視化中...'):
458
  if selected_model == 'dt':
 
 
459
  fig, ax = plt.subplots(figsize=(40, 20))
460
  plot_tree(
461
  model,
 
468
  st.pyplot(fig)
469
  st.caption("決定木の構造を表示しています。")
470
  else:
 
471
  from sklearn.metrics import mean_squared_error
 
 
472
  X_test_transformed = get_config('X_test_transformed')
473
  y_test = get_config('y_test')
474
 
 
475
  if selected_model in ['rf', 'et']:
476
  estimators = model.estimators_
477
  elif selected_model == 'gbr':
 
503
  best_score = mse
504
  best_estimator_index = idx
505
 
 
506
  if selected_model in ['rf', 'et', 'gbr']:
507
  best_tree = estimators[best_estimator_index]
 
508
  fig, ax = plt.subplots(figsize=(40, 20))
509
  plot_tree(
510
  best_tree,
 
517
  st.pyplot(fig)
518
  st.caption(f"ベストな決定木(ツリー番号: {best_estimator_index})の構造を表示しています。")
519
  elif selected_model == 'xgboost':
 
520
  import xgboost as xgb
521
  booster = model.get_booster()
522
  fig, ax = plt.subplots(figsize=(40, 20))
 
524
  st.pyplot(fig)
525
  st.caption(f"ベストな決定木(ツリー番号: {best_estimator_index})の構造を表示しています。")
526
  elif selected_model == 'lightgbm':
 
527
  import lightgbm as lgb
528
  graph = lgb.create_tree_digraph(model, tree_index=best_estimator_index)
529
  st.graphviz_chart(graph)
 
543
  progress_bar = st.progress(0)
544
  status_text = st.empty()
545
 
 
546
  status_text.text("モデルをファイナライズ中...")
547
  progress_bar.progress(30)
548
  final_model = finalize_model(model)
549
 
 
550
  status_text.text("最終評価を実行中...")
551
  progress_bar.progress(60)
552
  predictions = predict_model(final_model)
553
  final_scores = pull()
554
 
 
555
  st.subheader("ファイナルモデルの評価結果")
556
  col1, col2 = st.columns(2)
557
  with col1:
 
561
  st.write("ファイナライズ後の評価結果")
562
  st.dataframe(final_scores, use_container_width=True)
563
 
 
 
564
  final_model.target_column = target_variable
565
 
 
566
  status_text.text("モデルを保存中...")
567
  progress_bar.progress(90)
568
  model_name = f"{target_variable}_finalized_model"
569
 
 
570
  save_model(final_model, model_name)
571
 
 
572
  with open(f"{model_name}.pkl", 'rb') as f:
573
  model_bytes = f.read()
574
 
 
591
  st.error(f"予期せぬエラーが発生しました: {str(e)}")
592
 
593
  # コピーライト情報
594
+ common.display_copyright()
 
common.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+
4
+ def display_header():
5
+ st.caption("Created by Dit-Lab.(Daiki Ito)")
6
+
7
+ def set_font():
8
+ import matplotlib.pyplot as plt
9
+ import japanize_matplotlib
10
+ font_path = "ipaexg.ttf"
11
+ plt.rcParams['font.family'] = 'IPAexGothic'
12
+
13
+ def display_guide():
14
+ st.markdown("""
15
+ - [**情報探究ステップアップガイド**](https://dit-lab.notion.site/612d9665350544aa97a2a8514a03c77c?v=85ad37a3275b4717a0033516b9cfd9cc)
16
+ - [**中の人のページ(Dit-Lab.)**](https://dit-lab.notion.site/Dit-Lab-da906d09d3cf42a19a011cf4bf25a673?pvs=4)
17
+ """)
18
+
19
+ def display_link():
20
+ st.header("リンク")
21
+ st.markdown("""
22
+ - [**中の人のページ(Dit-Lab.)**](https://dit-lab.notion.site/Dit-Lab-da906d09d3cf42a19a011cf4bf25a673?pvs=4)
23
+ - [**進数変換学習アプリ**](https://easy-base-converter.streamlit.app)
24
+ - [**easyRSA**](https://easy-rsa.streamlit.app/)
25
+ - [**easyAutoML(回帰)**](https://huggingface.co/spaces/itou-daiki/pycaret_datascience_streamlit)
26
+ - [**pkl_predict_reg**](https://huggingface.co/spaces/itou-daiki/pkl_predict_reg)
27
+ - [**音のデータサイエンス**](https://audiovisualizationanalysis-bpeekdjwymuf6nkqcb4cqy.streamlit.app)
28
+ - [**3D RGB Cube Visualizer**](https://boxplot-4-mysteams.streamlit.app)
29
+ - [**上マーク角度計算補助ツール**](https://sailing-mark-angle.streamlit.app)
30
+ - [**Factor Score Calculator**](https://factor-score-calculator.streamlit.app/)
31
+ - [**easy Excel Merge**](https://easy-xl-merge.streamlit.app)
32
+ - [**フィードバックはこちらまで**](https://forms.gle/G5sMYm7dNpz2FQtU9)
33
+ - [**ソースコードはこちら(GitHub)**](https://github.com/itou-daiki/easy_stat)
34
+ """)
35
+
36
+ def display_copyright():
37
+ st.subheader("")
38
+ st.write('ご意見・ご要望は→', 'https://forms.gle/G5sMYm7dNpz2FQtU9', 'まで')
39
+ st.write("")
40
+ st.subheader('© 2022-2025 Dit-Lab.(Daiki Ito). All Rights Reserved.')
41
+ st.write("easyStat: Open Source for Ubiquitous Statistics")
42
+ st.write("Democratizing data, everywhere.")
43
+ st.write("")
44
+
45
+ def display_special_thanks():
46
+ st.subheader("In collaboration with our esteemed contributors:")
47
+ st.write("・Toshiyuki")
48
+ st.write("With heartfelt appreciation for their dedication and support.")