diff --git a/.gitattributes b/.gitattributes
index a6344aac8c09253b3b630fb776ae94478aa0275b..7e3444a52694ecdbcbfba152ecd086d9ffd8b623 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -33,3 +33,51 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text
*tfevents* filter=lfs diff=lfs merge=lfs -text
+UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png filter=lfs diff=lfs merge=lfs -text
+data.csv filter=lfs diff=lfs merge=lfs -text
+mental_xlmr_final/tokenizer.json filter=lfs diff=lfs merge=lfs -text
+clean_git_repo/mental_xlmr_final/tokenizer.json filter=lfs diff=lfs merge=lfs -text
+clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/History filter=lfs diff=lfs merge=lfs -text
+clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/Web[[:space:]]Data filter=lfs diff=lfs merge=lfs -text
+clean_git_repo/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill filter=lfs diff=lfs merge=lfs -text
+clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log filter=lfs diff=lfs merge=lfs -text
+clean_git_repo/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf filter=lfs diff=lfs merge=lfs -text
+clean_git_repo/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf filter=lfs diff=lfs merge=lfs -text
+clean_git_repo/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png filter=lfs diff=lfs merge=lfs -text
+temp_space/mental_xlmr_final/tokenizer.json filter=lfs diff=lfs merge=lfs -text
+temp_space/clean_git_repo/mental_xlmr_final/tokenizer.json filter=lfs diff=lfs merge=lfs -text
+temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/History filter=lfs diff=lfs merge=lfs -text
+temp_space/clean_git_repo/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill filter=lfs diff=lfs merge=lfs -text
+temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/Web[[:space:]]Data filter=lfs diff=lfs merge=lfs -text
+temp_space/clean_git_repo/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf filter=lfs diff=lfs merge=lfs -text
+temp_space/clean_git_repo/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf filter=lfs diff=lfs merge=lfs -text
+temp_space/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill filter=lfs diff=lfs merge=lfs -text
+temp_space/UI/safespace/.dart_tool/chrome-device/Default/History filter=lfs diff=lfs merge=lfs -text
+temp_space/UI/safespace/.dart_tool/chrome-device/Default/Web[[:space:]]Data filter=lfs diff=lfs merge=lfs -text
+temp_space/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log filter=lfs diff=lfs merge=lfs -text
+temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log filter=lfs diff=lfs merge=lfs -text
+temp_space/clean_git_repo/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png filter=lfs diff=lfs merge=lfs -text
+temp_space/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf filter=lfs diff=lfs merge=lfs -text
+temp_space/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf filter=lfs diff=lfs merge=lfs -text
+UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Affiliation[[:space:]]Database filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Google[[:space:]]Profile[[:space:]]Picture.png filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/History filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Web[[:space:]]Data filter=lfs diff=lfs merge=lfs -text
+temp_space/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Shared[[:space:]]Dictionary/cache/2bfff91f8dd9b032_0 filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/flutter_build/694c124069dece6f3ffa00a5aabab35e/app.dill filter=lfs diff=lfs merge=lfs -text
+UI/safespace/build/unit_test_assets/NOTICES.Z filter=lfs diff=lfs merge=lfs -text
+UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf filter=lfs diff=lfs merge=lfs -text
+UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422504525250674 filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422506231685404 filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422658855680597 filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422667094602974 filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000004.log filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000005.ldb filter=lfs diff=lfs merge=lfs -text
+UI/safespace/.dart_tool/chrome-device/Default/Accounts/Avatar[[:space:]]Images/100679184552698402258 filter=lfs diff=lfs merge=lfs -text
+UI/safespace/build/unit_test_assets/fonts/MaterialIcons-Regular.otf filter=lfs diff=lfs merge=lfs -text
+UI/safespace/build/unit_test_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf filter=lfs diff=lfs merge=lfs -text
+UI/safespace/build/test_cache/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill filter=lfs diff=lfs merge=lfs -text
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..569d42fc91a2ceb22bc7ca662c66442f26a939eb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+push_to_space.py
+temp_space/
+temp_hf_space/
+scrub_rules.txt
+.ipynb_checkpoints/
+*.ipynb
+repo.zip
+data.csv
+*.h5
+*.pkl
+mental_xlmr_final/
+UI/safespace/build/
+UI/safespace/.dart_tool/
+UI/safespace/.pub-cache/
+UI/safespace/.flutter-plugins
+UI/safespace/.flutter-plugins-dependencies
+UI/safespace/node_modules/
+*.log
+.DS_Store
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Accounts/Avatar Images/100679184552698402258 b/UI/safespace/.dart_tool/chrome-device/Default/Accounts/Avatar Images/100679184552698402258
new file mode 100644
index 0000000000000000000000000000000000000000..83416df476f0db4c14d3d9ab84b860926b99117d
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Accounts/Avatar Images/100679184552698402258
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0f2264d18025c482b6a86e40d5d048210837422c81b488022c5b77701234b7e6
+size 109914
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Affiliation Database b/UI/safespace/.dart_tool/chrome-device/Default/Affiliation Database
new file mode 100644
index 0000000000000000000000000000000000000000..9a91a6a018f835123e4454cf958e1ed2b45569c4
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Affiliation Database
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:970ee31de145a72835692447fe9f172c59443c794566dbc595ae16f0c30b6c39
+size 102400
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Google Profile Picture.png b/UI/safespace/.dart_tool/chrome-device/Default/Google Profile Picture.png
new file mode 100644
index 0000000000000000000000000000000000000000..83416df476f0db4c14d3d9ab84b860926b99117d
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Google Profile Picture.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0f2264d18025c482b6a86e40d5d048210837422c81b488022c5b77701234b7e6
+size 109914
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/History b/UI/safespace/.dart_tool/chrome-device/Default/History
new file mode 100644
index 0000000000000000000000000000000000000000..c3be89080a14bb389067f74c8bb450687b2593d1
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/History
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:83e3f671cea193224794e68f6397cfbdcfe7299614f4927e275ba9a284c01c52
+size 294912
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422504525250674 b/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422504525250674
new file mode 100644
index 0000000000000000000000000000000000000000..eb49b2792b775e592bc035e3edeeb6ab99c9a2df
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422504525250674
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3190858d674bf992e4bf326536b650fddbf4b368e50e6715039c8ae1647a7187
+size 145695
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422506231685404 b/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422506231685404
new file mode 100644
index 0000000000000000000000000000000000000000..aca7695dcd6d336548c9e2e1fe5d50e9e73c67cf
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422506231685404
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3bafa05f042888995de97c0169e3cbaca763be8104f86b2aefc48a2350e4783b
+size 103968
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422658855680597 b/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422658855680597
new file mode 100644
index 0000000000000000000000000000000000000000..6f4250bc5107f8908ee016224e68f9bf4d8f2793
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422658855680597
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8a04b79669055015fa2ed535518c6f99625ca4be895abb7b493e77bbe38d5689
+size 147567
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422667094602974 b/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422667094602974
new file mode 100644
index 0000000000000000000000000000000000000000..63e94bcfa5593a868a8a6f9261ea39b84619993d
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Sessions/Session_13422667094602974
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0d25e50423a6e1f42667d70bdae7d8bf81ffd7ef9d50a8444a37e5862122dd7e
+size 192253
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Shared Dictionary/cache/2bfff91f8dd9b032_0 b/UI/safespace/.dart_tool/chrome-device/Default/Shared Dictionary/cache/2bfff91f8dd9b032_0
new file mode 100644
index 0000000000000000000000000000000000000000..ff0fd6bcd1e1955729606ec994455bc2a4745b5c
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Shared Dictionary/cache/2bfff91f8dd9b032_0
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:664344ef4ca53efd67808330605a1cb522258b234ec112d03ef10e3b938073bf
+size 198743
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Sync Data/Nigori.bin b/UI/safespace/.dart_tool/chrome-device/Default/Sync Data/Nigori.bin
new file mode 100644
index 0000000000000000000000000000000000000000..3919ebdfbc40b251530e92c5e21be2cf1262424b
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Sync Data/Nigori.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:303a5a630227f630b5704f2289d0469b6c415e4adec542b08e62288fcf15acea
+size 990
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/Web Data b/UI/safespace/.dart_tool/chrome-device/Default/Web Data
new file mode 100644
index 0000000000000000000000000000000000000000..c937e0f424b1d9ecb0144f2e0fb987f0134575cf
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/Web Data
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1572acaab352554c98b7cb1765c5a92f838af0da6a3972dc196ecdc4b9fba844
+size 196608
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log b/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log
new file mode 100644
index 0000000000000000000000000000000000000000..3944bb6e3df6ec7aaf2f2bf6e1ae7872dd39b37a
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3632466e1e4586ea4ac9a782dbc2fe30bf25db8cd6019be0e705ddc1ef22e851
+size 437109
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000004.log b/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000004.log
new file mode 100644
index 0000000000000000000000000000000000000000..6be42e5b71e44b7a9be68ba27fd605ec2e2fd664
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000004.log
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3c98aca056f3ce1e53e1fd16adb35fb77e9c8376ba3be69a20289942876107bb
+size 352170
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000005.ldb b/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000005.ldb
new file mode 100644
index 0000000000000000000000000000000000000000..043f60a72dcb58f6d8d1295217d0743ac06ca9b9
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000005.ldb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a8bbd528dee536c8e86216027ae360a15d6ee05d745da3936fc3360d0429b5e8
+size 133527
diff --git a/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb b/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb
new file mode 100644
index 0000000000000000000000000000000000000000..39c9d5d4df9acafb6c0629251c63786a90123761
--- /dev/null
+++ b/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b87bf305aafae1f1ec7dd947176c9529b2a9cbd4a3bf296fce25fc009e725366
+size 84
diff --git a/UI/safespace/.dart_tool/flutter_build/694c124069dece6f3ffa00a5aabab35e/app.dill b/UI/safespace/.dart_tool/flutter_build/694c124069dece6f3ffa00a5aabab35e/app.dill
new file mode 100644
index 0000000000000000000000000000000000000000..16c21934f8309df2bb29c9d493b05ee5aa8ea82f
--- /dev/null
+++ b/UI/safespace/.dart_tool/flutter_build/694c124069dece6f3ffa00a5aabab35e/app.dill
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e86b5ab568a496d761eedcb4975ead5f277a06bd1c5d652968b2912c9d0b79ae
+size 31744696
diff --git a/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill b/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
new file mode 100644
index 0000000000000000000000000000000000000000..7a2d19bf3fc6ead1043fcca8b9e39d84ae493c9a
--- /dev/null
+++ b/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5a39ea79ca44e7928c9a077f63e6c575bd8d1d33efc85fa4a7d9bce7c6da0283
+size 50726856
diff --git a/UI/safespace/build/flutter_assets/AssetManifest.bin b/UI/safespace/build/flutter_assets/AssetManifest.bin
new file mode 100644
index 0000000000000000000000000000000000000000..520b873cb7d6b1c07028a6f67d14a7c8e1b7cc61
--- /dev/null
+++ b/UI/safespace/build/flutter_assets/AssetManifest.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0b49a2913e16c75a773c3b3952a15cb6e9ce5df0a46efa5df5f48d870e284e69
+size 27031
diff --git a/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf b/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf
new file mode 100644
index 0000000000000000000000000000000000000000..0e72af0d1c2d8662f7be287eb6d27210edbbfa1f
--- /dev/null
+++ b/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d9865b671a09d683d13a863089d8825e0f61a37696ce5d7d448bc8023aa62453
+size 1645184
diff --git a/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf b/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..e98baa9f284d21d1e6d3837523e5d879e73dca86
--- /dev/null
+++ b/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:67c44fe9183b002e79dde7f6977e2988661c9a3e4a3c5fce968787efdbed823c
+size 257628
diff --git a/UI/safespace/build/test_cache/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill b/UI/safespace/build/test_cache/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
new file mode 100644
index 0000000000000000000000000000000000000000..34e730911ffe2a3de6ef4319a00e41586df2cdd4
--- /dev/null
+++ b/UI/safespace/build/test_cache/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6a2e8b59bc8fbd6dd9a3dbcae74342f7c4afcb8853b54ef3d50fc1ed821df7f3
+size 48994592
diff --git a/UI/safespace/build/unit_test_assets/AssetManifest.bin b/UI/safespace/build/unit_test_assets/AssetManifest.bin
new file mode 100644
index 0000000000000000000000000000000000000000..520b873cb7d6b1c07028a6f67d14a7c8e1b7cc61
--- /dev/null
+++ b/UI/safespace/build/unit_test_assets/AssetManifest.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0b49a2913e16c75a773c3b3952a15cb6e9ce5df0a46efa5df5f48d870e284e69
+size 27031
diff --git a/UI/safespace/build/unit_test_assets/NOTICES.Z b/UI/safespace/build/unit_test_assets/NOTICES.Z
new file mode 100644
index 0000000000000000000000000000000000000000..3cbf6b0cc440478fe82c7cdeae89b7aa289e2d8b
--- /dev/null
+++ b/UI/safespace/build/unit_test_assets/NOTICES.Z
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:30a3990f4698bce1c4e14242e6f53a47a356585a20d434e1f52378f61682b113
+size 105255
diff --git a/UI/safespace/build/unit_test_assets/fonts/MaterialIcons-Regular.otf b/UI/safespace/build/unit_test_assets/fonts/MaterialIcons-Regular.otf
new file mode 100644
index 0000000000000000000000000000000000000000..0e72af0d1c2d8662f7be287eb6d27210edbbfa1f
--- /dev/null
+++ b/UI/safespace/build/unit_test_assets/fonts/MaterialIcons-Regular.otf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d9865b671a09d683d13a863089d8825e0f61a37696ce5d7d448bc8023aa62453
+size 1645184
diff --git a/UI/safespace/build/unit_test_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf b/UI/safespace/build/unit_test_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..e98baa9f284d21d1e6d3837523e5d879e73dca86
--- /dev/null
+++ b/UI/safespace/build/unit_test_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:67c44fe9183b002e79dde7f6977e2988661c9a3e4a3c5fce968787efdbed823c
+size 257628
diff --git a/UI/safespace/build/web/canvaskit/chromium/canvaskit.wasm b/UI/safespace/build/web/canvaskit/chromium/canvaskit.wasm
new file mode 100644
index 0000000000000000000000000000000000000000..706889894496c21fd90a5447a636128dbb0970ba
--- /dev/null
+++ b/UI/safespace/build/web/canvaskit/chromium/canvaskit.wasm
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f6c67bf7989fcb1b69a3203617882ac0d1541cc79e38f81c3f5d63ab4d73de33
+size 5686836
diff --git a/UI/safespace/build/web/canvaskit/skwasm.wasm b/UI/safespace/build/web/canvaskit/skwasm.wasm
new file mode 100644
index 0000000000000000000000000000000000000000..a384cfe8ad2069c6aa26809ab803fece5cde5b55
--- /dev/null
+++ b/UI/safespace/build/web/canvaskit/skwasm.wasm
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:461a759c657738e573f1c2f69e26489197e43db1bf6ec1e2c3b44c6721314cd1
+size 3549758
diff --git a/UI/safespace/build/web/canvaskit/skwasm_heavy.wasm b/UI/safespace/build/web/canvaskit/skwasm_heavy.wasm
new file mode 100644
index 0000000000000000000000000000000000000000..82f4e06871f6fa8f8c8de6be986acd8c5d91e5ea
--- /dev/null
+++ b/UI/safespace/build/web/canvaskit/skwasm_heavy.wasm
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4b0028e38d865b4673ec38c0c673299dff6b00d6cd8c5e53dda9f800f7bbdda2
+size 5140163
diff --git a/UI/safespace/build/web/canvaskit/wimp.wasm b/UI/safespace/build/web/canvaskit/wimp.wasm
new file mode 100644
index 0000000000000000000000000000000000000000..88c1ea17cd3a1b76d0b8932ba65387367d2b6532
--- /dev/null
+++ b/UI/safespace/build/web/canvaskit/wimp.wasm
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a9e168fe6556e09414e9ea58badaf13c54b630de13a6e03f92444340b5bec2fd
+size 3461867
diff --git a/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
new file mode 100644
index 0000000000000000000000000000000000000000..0066c008ba292c746ef170676f5643de1742f589
--- /dev/null
+++ b/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6232e5815af17e25e0268b2fec7aea9e068cc92ec709e9605c2b31df4ff2a313
+size 102994
diff --git a/api.py b/api.py
new file mode 100644
index 0000000000000000000000000000000000000000..094b1f3e22878a77bc8a68e8f370bb2864d6766f
--- /dev/null
+++ b/api.py
@@ -0,0 +1,669 @@
+import os
+from datetime import datetime
+import hashlib
+import logging
+import time
+
+import httpx
+from fastapi import FastAPI, HTTPException, Depends, Request
+from fastapi.responses import HTMLResponse
+from fastapi.middleware.cors import CORSMiddleware
+from pydantic import BaseModel, Field
+from typing import Optional
+
+from core_ai import predict_text, predict_survey, fuse_scores
+from recommendations import get_recommendations
+
+# --- DATABASE SETUP ---
+from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime, JSON, Text, Boolean, Index
+from sqlalchemy.orm import declarative_base, sessionmaker, Session
+
+DATABASE_URL = os.environ.get("DATABASE_URL")
+if DATABASE_URL and DATABASE_URL.startswith("postgres://"):
+ DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://", 1)
+
+engine = create_engine(DATABASE_URL, connect_args={'connect_timeout': 5}, pool_pre_ping=True) if DATABASE_URL else None
+SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) if engine else None
+Base = declarative_base()
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger("safespace.api")
+
+
+class DBUser(Base):
+ __tablename__ = "users"
+ id = Column(Integer, primary_key=True, index=True)
+ name = Column(String, nullable=True)
+ email = Column(String, unique=True, index=True)
+ password = Column(String)
+ created_at = Column(DateTime, default=datetime.utcnow)
+
+
+class DBAnalysis(Base):
+ __tablename__ = "analyses"
+ id = Column(Integer, primary_key=True, index=True)
+ user_id = Column(Integer, index=True, nullable=True)
+ primary_condition = Column(String)
+ clinical_scoring = Column(JSON)
+ created_at = Column(DateTime, default=datetime.utcnow)
+ text_input = Column(Text, nullable=True)
+ text_input_hash = Column(Text, nullable=True)
+ text_scores = Column(JSON, nullable=True)
+ survey_scores = Column(JSON, nullable=True)
+ fused_scores = Column(JSON, nullable=True)
+ severity = Column(Text, nullable=True)
+ cause = Column(Text, nullable=True)
+ suicidal_flag = Column(Boolean, default=False)
+ model_version = Column(Text, nullable=True)
+ app_version = Column(Text, nullable=True)
+ locale = Column(Text, nullable=True)
+
+
+Index("ix_analyses_user_id_created_at", DBAnalysis.user_id, DBAnalysis.created_at)
+
+
+class DBCheckin(Base):
+ __tablename__ = "checkins"
+ id = Column(Integer, primary_key=True, index=True)
+ user_id = Column(Integer, index=True, nullable=False)
+ mood = Column(Integer, nullable=False)
+ sleep = Column(Integer, nullable=False)
+ energy = Column(Float, nullable=False)
+ created_at = Column(DateTime, default=datetime.utcnow)
+
+
+Index("ix_checkins_user_id_created_at", DBCheckin.user_id, DBCheckin.created_at)
+
+
+class DBJournalEntry(Base):
+ __tablename__ = "journal_entries"
+ id = Column(Integer, primary_key=True, index=True)
+ user_id = Column(Integer, index=True, nullable=True)
+ content = Column(Text, nullable=False)
+ created_at = Column(DateTime, default=datetime.utcnow)
+ updated_at = Column(DateTime, nullable=True)
+
+# --- APP SETUP ---
+app = FastAPI(title="SafeSpace API", version="1.0.0")
+
+
+@app.middleware("http")
+async def log_requests(request: Request, call_next):
+ start_time = time.time()
+ response = await call_next(request)
+ duration_ms = int((time.time() - start_time) * 1000)
+ logger.info(
+ "%s %s %s %sms",
+ request.method,
+ request.url.path,
+ response.status_code,
+ duration_ms,
+ )
+ return response
+
+
+@app.on_event("startup")
+async def startup_event():
+ import asyncio
+ if engine:
+ try:
+ await asyncio.wait_for(
+ asyncio.to_thread(Base.metadata.create_all, bind=engine),
+ timeout=8.0
+ )
+ logger.info("Database connected and tables verified.")
+ except asyncio.TimeoutError:
+ logger.warning("Database connection timed out during startup - server will start without DB verification.")
+ except Exception as e:
+ logger.exception("Database connection failed during startup: %s", e)
+ logger.info("Application startup complete.")
+
+
+def get_db():
+ if not SessionLocal:
+ yield None
+ else:
+ db = SessionLocal()
+ try:
+ yield db
+ finally:
+ db.close()
+
+# Add CORS so Flutter app can communicate with it
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"],
+ allow_credentials=True,
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+
+# --- Password Hashing ---
+def hash_password(password: str) -> str:
+ return hashlib.sha256(password.encode()).hexdigest()
+
+# --- DASS-42 Clinical Scoring ---
+def calculate_dass_clinical_score(answers: list) -> dict:
+ dep_idx = [2, 4, 9, 12, 15, 16, 20, 23, 25, 30, 33, 36, 37, 41]
+ anx_idx = [1, 3, 6, 8, 14, 18, 19, 22, 24, 27, 29, 35, 39, 40]
+ str_idx = [0, 5, 7, 10, 11, 13, 17, 21, 26, 28, 31, 32, 34, 38]
+
+ dep_score = sum(answers[i] for i in dep_idx)
+ anx_score = sum(answers[i] for i in anx_idx)
+ str_score = sum(answers[i] for i in str_idx)
+
+ def get_severity(score, bounds):
+ if score <= bounds[0]: return "Normal"
+ if score <= bounds[1]: return "Mild"
+ if score <= bounds[2]: return "Moderate"
+ if score <= bounds[3]: return "Severe"
+ return "Extremely Severe"
+
+ return {
+ "depression": {"score": dep_score, "severity": get_severity(dep_score, [9, 13, 20, 27])},
+ "anxiety": {"score": anx_score, "severity": get_severity(anx_score, [7, 9, 14, 19])},
+ "stress": {"score": str_score, "severity": get_severity(str_score, [14, 18, 25, 33])}
+ }
+
+# --- API MODELS ---
+class AnalysisRequest(BaseModel):
+ user_id: str | int = Field(default=None, description="User identifier")
+ text: str = Field(..., min_length=1)
+ survey_answers: list[int] = Field(..., min_items=42, max_items=42)
+ locale: str = Field(default="en")
+ client_ts: str | None = None
+
+
+class AnalyzeRequest(BaseModel):
+ text: str = Field(..., description="The user's response in text (Arabic/English)")
+ survey_answers: list[int] = Field(..., min_items=42, max_items=42, description="List of 42 integers (0-4) representing DASS-42 survey answers")
+ user_id: int | None = Field(default=None, description="Optional user ID to link analysis to a user")
+ locale: str = Field(default="en")
+ client_ts: str | None = None
+ app_version: str | None = None
+ model_version: str | None = None
+
+
+class ChatRequest(BaseModel):
+ message: str
+ session_id: Optional[str] = "default"
+
+
+class ChatResponse(BaseModel):
+ reply: str
+
+
+class SignupRequest(BaseModel):
+ name: str = Field(..., min_length=1)
+ email: str = Field(..., min_length=5)
+ password: str = Field(..., min_length=4)
+
+
+class LoginRequest(BaseModel):
+ email: str = Field(..., min_length=5)
+ password: str = Field(..., min_length=1)
+
+
+class CheckinRequest(BaseModel):
+ mood: int = Field(..., ge=0, le=10)
+ sleep: int = Field(..., ge=0, le=10)
+ energy: float = Field(..., ge=0, le=10)
+ user_id: int | None = Field(default=None, description="Optional user ID to link check-in to a user")
+ client_ts: str | None = None
+
+
+class JournalEntryRequest(BaseModel):
+ content: str = Field(..., min_length=1)
+ user_id: int | None = Field(default=None, description="Optional user ID to link journal entry to a user")
+ client_ts: str | None = None
+
+
+class JournalEntryUpdateRequest(BaseModel):
+ content: str = Field(..., min_length=1)
+
+
+# --- ENDPOINTS ---
+@app.get("/")
+def root():
+ return {"status": "ok", "message": "SafeSpace API"}
+
+
+@app.get("/test", response_class=HTMLResponse)
+def test_page():
+ html_path = os.path.join(os.path.dirname(__file__), "index.html")
+ if not os.path.exists(html_path):
+ raise HTTPException(status_code=404, detail="index.html not found")
+ with open(html_path, "r", encoding="utf-8") as f:
+ return f.read()
+
+
+# --- AUTH ENDPOINTS ---
+@app.post("/api/v1/auth/signup")
+async def signup(request: SignupRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ # Check if email already exists
+ existing = db.query(DBUser).filter(DBUser.email == request.email).first()
+ if existing:
+ raise HTTPException(status_code=400, detail="Email already registered")
+
+ # Create new user
+ try:
+ new_user = DBUser(
+ name=request.name,
+ email=request.email,
+ password=hash_password(request.password),
+ )
+ db.add(new_user)
+ db.commit()
+ db.refresh(new_user)
+
+ return {
+ "user_id": new_user.id,
+ "email": new_user.email,
+ "name": new_user.name,
+ "message": "Account created successfully"
+ }
+ except Exception as e:
+ db.rollback()
+ raise HTTPException(status_code=500, detail=f"Failed to create account: {str(e)}")
+
+
+@app.post("/api/v1/auth/login")
+async def login(request: LoginRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ user = db.query(DBUser).filter(DBUser.email == request.email).first()
+ if not user:
+ raise HTTPException(status_code=401, detail="Email not found")
+
+ if user.password != hash_password(request.password):
+ # Also try plain-text match for legacy users who signed up before hashing
+ if user.password != request.password:
+ raise HTTPException(status_code=401, detail="Incorrect password")
+
+ return {
+ "user_id": user.id,
+ "email": user.email,
+ "name": user.name or "",
+ "message": "Login successful"
+ }
+
+
+# New-style endpoint (used by index.html test page)
+@app.post("/v1/analysis")
+def analyze(payload: AnalysisRequest, db: Session = Depends(get_db)):
+ # Shift 0-3 UI scale to 1-4 for the AI model (trained on data.csv)
+ shifted_answers = [a + 1 for a in payload.survey_answers]
+ text_scores = predict_text(payload.text)
+ survey_scores = predict_survey(shifted_answers)
+
+ final_scores = fuse_scores(text_scores, survey_scores)
+ primary = max(final_scores, key=final_scores.get)
+ clinical = calculate_dass_clinical_score(payload.survey_answers)
+ rec = get_recommendations(primary, final_scores[primary], payload.text)
+ created_at_dt = datetime.utcnow()
+ if payload.client_ts:
+ try:
+ created_at_dt = datetime.fromisoformat(payload.client_ts.replace("Z", "+00:00")).replace(tzinfo=None)
+ except ValueError:
+ pass
+ created_at = created_at_dt.isoformat() + "Z"
+
+ # Save to PostgreSQL if DB is connected
+ if db:
+ try:
+ text_input_hash = hashlib.sha256(payload.text.encode()).hexdigest()
+ new_analysis = DBAnalysis(
+ user_id=payload.user_id,
+ primary_condition=primary,
+ clinical_scoring=clinical,
+ created_at=created_at_dt,
+ text_input=payload.text,
+ text_input_hash=text_input_hash,
+ text_scores=text_scores,
+ survey_scores=survey_scores,
+ fused_scores=final_scores,
+ severity=rec.get("severity"),
+ cause=rec.get("cause"),
+ suicidal_flag=rec.get("suicidal_flag", False),
+ model_version=None,
+ app_version=None,
+ locale=payload.locale,
+ )
+ db.add(new_analysis)
+ db.commit()
+ except Exception as e:
+ logger.exception("DB save error: %s", e)
+
+ return {
+ "analysis_id": None,
+ "primary_condition": primary,
+ "fused_scores": final_scores,
+ "text_scores": text_scores,
+ "survey_scores": survey_scores,
+ "clinical_scoring": clinical,
+ "severity": rec.get("severity"),
+ "cause": rec.get("cause"),
+ "recommendations": {
+ "tips_en": rec.get("tips_en", []),
+ "tips_ar": rec.get("tips_ar", []),
+ "resources_en": rec.get("resources_en", []),
+ "resources_ar": rec.get("resources_ar", []),
+ "referral_en": rec.get("referral_en", ""),
+ "referral_ar": rec.get("referral_ar", ""),
+ },
+ "suicidal_flag": rec.get("suicidal_flag", False),
+ "created_at": created_at,
+ }
+
+# Flutter-compatible endpoint (used by api_service.dart)
+@app.post("/api/v1/analyze")
+async def analyze_mental_health(request: AnalyzeRequest, db: Session = Depends(get_db)):
+ try:
+ start_time = time.time()
+ # Shift 0-3 UI scale to 1-4 for the AI model (trained on data.csv)
+ shifted_answers = [a + 1 for a in request.survey_answers]
+ text_scores = predict_text(request.text)
+ survey_scores = predict_survey(shifted_answers)
+
+ final_scores = fuse_scores(text_scores, survey_scores)
+ primary = max(final_scores, key=final_scores.get)
+ clinical = calculate_dass_clinical_score(request.survey_answers)
+ rec = get_recommendations(primary, final_scores[primary], request.text)
+ created_at_dt = datetime.utcnow()
+ if request.client_ts:
+ try:
+ created_at_dt = datetime.fromisoformat(request.client_ts.replace("Z", "+00:00")).replace(tzinfo=None)
+ except ValueError:
+ pass
+ created_at = created_at_dt.isoformat() + "Z"
+
+ # Save to PostgreSQL if DB is connected
+ if db:
+ try:
+ text_input_hash = hashlib.sha256(request.text.encode()).hexdigest()
+ new_analysis = DBAnalysis(
+ user_id=request.user_id,
+ primary_condition=primary,
+ clinical_scoring=clinical,
+ created_at=created_at_dt,
+ text_input=request.text,
+ text_input_hash=text_input_hash,
+ text_scores=text_scores,
+ survey_scores=survey_scores,
+ fused_scores=final_scores,
+ severity=rec.get("severity"),
+ cause=rec.get("cause"),
+ suicidal_flag=rec.get("suicidal_flag", False),
+ model_version=request.model_version,
+ app_version=request.app_version,
+ locale=request.locale,
+ )
+ db.add(new_analysis)
+ db.commit()
+ except Exception as e:
+ logger.exception("DB save error: %s", e)
+
+ return {
+ "analysis_id": None,
+ "primary_condition": primary,
+ "fused_scores": final_scores,
+ "text_scores": text_scores,
+ "survey_scores": survey_scores,
+ "clinical_scoring": clinical,
+ "severity": rec.get("severity"),
+ "cause": rec.get("cause"),
+ "recommendations": {
+ "tips_en": rec.get("tips_en", []),
+ "tips_ar": rec.get("tips_ar", []),
+ "resources_en": rec.get("resources_en", []),
+ "resources_ar": rec.get("resources_ar", []),
+ "referral_en": rec.get("referral_en", ""),
+ "referral_ar": rec.get("referral_ar", ""),
+ },
+ "suicidal_flag": rec.get("suicidal_flag", False),
+ "created_at": created_at,
+ "duration_ms": int((time.time() - start_time) * 1000),
+ }
+ except Exception as e:
+ logger.exception("Analyze request failed: %s", e)
+ raise HTTPException(status_code=500, detail="Failed to analyze")
+
+# Flutter-compatible history endpoint
+@app.get("/api/v1/analyses/history")
+async def get_analyses_history(user_id: int = None, db: Session = Depends(get_db)):
+ try:
+ if not db:
+ return []
+
+ query = db.query(DBAnalysis)
+
+ # Filter by user_id if provided
+ if user_id is not None:
+ query = query.filter(DBAnalysis.user_id == user_id)
+
+ # Get the 10 most recent analyses, sorted by created_at ascending (oldest first for graphing)
+ records = query.order_by(DBAnalysis.created_at.desc()).limit(10).all()
+
+ history = []
+ for r in reversed(records): # Reverse so oldest is first
+ if r.clinical_scoring:
+ history.append({
+ "id": r.id,
+ "date": r.created_at.strftime("%b %d"),
+ "depression": r.clinical_scoring.get("depression", {}).get("score", 0),
+ "anxiety": r.clinical_scoring.get("anxiety", {}).get("score", 0),
+ "stress": r.clinical_scoring.get("stress", {}).get("score", 0),
+ "primary": r.primary_condition
+ })
+ return history
+ except Exception as e:
+ logger.exception("Analyze request failed: %s", e)
+ raise HTTPException(status_code=500, detail="Failed to analyze")
+
+@app.post("/api/v1/chat", response_model=ChatResponse)
+async def chat_with_ai(request: ChatRequest):
+ api_url = os.environ.get("AI_API_URL")
+ api_key = os.environ.get("AI_API_KEY")
+ chatflow_id = os.environ.get("AI_CHATFLOW_ID")
+
+ if not api_url or not api_key or not chatflow_id:
+ raise HTTPException(status_code=500, detail="AI API credentials are not configured in Secrets.")
+
+ endpoint = f"{api_url}/api/v1/prediction/{chatflow_id}"
+ headers = {"Authorization": f"Bearer {api_key}"}
+ payload = {"question": request.message, "overrideConfig": {"sessionId": request.session_id}}
+
+ async with httpx.AsyncClient() as client:
+ try:
+ response = await client.post(endpoint, json=payload, headers=headers, timeout=30.0)
+ response.raise_for_status()
+ data = response.json()
+ return ChatResponse(reply=data.get("text") or data.get("answer") or str(data))
+ except Exception as e:
+ raise HTTPException(status_code=502, detail=f"Failed to communicate with AI API: {str(e)}")
+
+
+@app.post("/api/v1/checkin")
+async def create_checkin(request: CheckinRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ if request.user_id is None:
+ raise HTTPException(status_code=400, detail="user_id is required")
+
+ created_at = datetime.utcnow()
+ if request.client_ts:
+ try:
+ created_at = datetime.fromisoformat(request.client_ts.replace("Z", "+00:00")).replace(tzinfo=None)
+ except ValueError:
+ pass
+
+ try:
+ new_checkin = DBCheckin(
+ user_id=request.user_id,
+ mood=request.mood,
+ sleep=request.sleep,
+ energy=request.energy,
+ created_at=created_at,
+ )
+ db.add(new_checkin)
+ db.commit()
+ db.refresh(new_checkin)
+
+ return {
+ "id": new_checkin.id,
+ "user_id": new_checkin.user_id,
+ "mood": new_checkin.mood,
+ "sleep": new_checkin.sleep,
+ "energy": new_checkin.energy,
+ "created_at": new_checkin.created_at.isoformat() + "Z",
+ }
+ except Exception as e:
+ db.rollback()
+ logger.exception("Failed to save check-in: %s", e)
+ raise HTTPException(status_code=500, detail="Failed to save check-in")
+
+
+@app.get("/api/v1/checkin/history")
+async def get_checkin_history(user_id: int | None = None, db: Session = Depends(get_db)):
+ try:
+ if not db:
+ return []
+
+ query = db.query(DBCheckin)
+ if user_id is not None:
+ query = query.filter(DBCheckin.user_id == user_id)
+
+ records = query.order_by(DBCheckin.created_at.desc()).limit(30).all()
+ return [
+ {
+ "id": r.id,
+ "user_id": r.user_id,
+ "mood": r.mood,
+ "sleep": r.sleep,
+ "energy": r.energy,
+ "created_at": r.created_at.isoformat() + "Z",
+ }
+ for r in records
+ ]
+ except Exception as e:
+ logger.exception("Failed to fetch check-in history: %s", e)
+ raise HTTPException(status_code=500, detail="Failed to fetch history")
+
+
+@app.post("/api/v1/journal")
+async def create_journal_entry(request: JournalEntryRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ if request.user_id is None:
+ raise HTTPException(status_code=400, detail="user_id is required")
+
+ created_at = datetime.utcnow()
+ if request.client_ts:
+ try:
+ created_at = datetime.fromisoformat(request.client_ts.replace("Z", "+00:00")).replace(tzinfo=None)
+ except ValueError:
+ pass
+
+ try:
+ entry = DBJournalEntry(
+ user_id=request.user_id,
+ content=request.content,
+ created_at=created_at,
+ )
+ db.add(entry)
+ db.commit()
+ db.refresh(entry)
+
+ return {
+ "id": entry.id,
+ "user_id": entry.user_id,
+ "content": entry.content,
+ "created_at": entry.created_at.isoformat() + "Z",
+ }
+ except Exception as e:
+ db.rollback()
+ logger.exception("Failed to save journal entry: %s", e)
+ raise HTTPException(status_code=500, detail="Failed to save journal entry")
+
+
+@app.get("/api/v1/journal/history")
+async def get_journal_history(user_id: int | None = None, db: Session = Depends(get_db)):
+ try:
+ if not db:
+ return []
+
+ query = db.query(DBJournalEntry)
+ if user_id is not None:
+ query = query.filter(DBJournalEntry.user_id == user_id)
+
+ records = query.order_by(DBJournalEntry.created_at.desc()).limit(50).all()
+ return [
+ {
+ "id": r.id,
+ "user_id": r.user_id,
+ "content": r.content,
+ "created_at": r.created_at.isoformat() + "Z",
+ }
+ for r in records
+ ]
+ except Exception as e:
+ logger.exception("Failed to fetch journal history: %s", e)
+ raise HTTPException(status_code=500, detail="Failed to fetch journal history")
+
+
+@app.put("/api/v1/journal/{entry_id}")
+async def update_journal_entry(entry_id: int, request: JournalEntryUpdateRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ try:
+ entry = db.query(DBJournalEntry).filter(DBJournalEntry.id == entry_id).first()
+ if not entry:
+ raise HTTPException(status_code=404, detail="Journal entry not found")
+
+ entry.content = request.content
+ entry.updated_at = datetime.utcnow()
+ db.add(entry)
+ db.commit()
+ db.refresh(entry)
+
+ return {
+ "id": entry.id,
+ "user_id": entry.user_id,
+ "content": entry.content,
+ "created_at": entry.created_at.isoformat() + "Z",
+ "updated_at": entry.updated_at.isoformat() + "Z",
+ }
+ except HTTPException:
+ raise
+ except Exception as e:
+ db.rollback()
+ logger.exception("Failed to update journal entry: %s", e)
+ raise HTTPException(status_code=500, detail="Failed to update journal entry")
+
+
+@app.delete("/api/v1/journal/{entry_id}")
+async def delete_journal_entry(entry_id: int, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ try:
+ entry = db.query(DBJournalEntry).filter(DBJournalEntry.id == entry_id).first()
+ if not entry:
+ raise HTTPException(status_code=404, detail="Journal entry not found")
+
+ db.delete(entry)
+ db.commit()
+ return {"status": "deleted", "id": entry_id}
+ except HTTPException:
+ raise
+ except Exception as e:
+ db.rollback()
+ logger.exception("Failed to delete journal entry: %s", e)
+ raise HTTPException(status_code=500, detail="Failed to delete journal entry")
diff --git a/app.py b/app.py
new file mode 100644
index 0000000000000000000000000000000000000000..00d7f9e012a131ed50efe27c268cfeaa2358d301
--- /dev/null
+++ b/app.py
@@ -0,0 +1,508 @@
+"""
+app.py
+======
+Mental Health AI — Full Pipeline
+Files needed:
+ mental_xlmr_final/ ← XLM-R model folder
+ mental_model.h5 ← Survey Keras model
+ scaler.pkl ← Survey scaler
+ recommendations.py ← same directory
+
+Install:
+ pip install streamlit transformers torch tensorflow scikit-learn deep-translator
+"""
+import sys, os
+sys.path.append(os.path.dirname(__file__))
+import re, pickle, warnings
+import numpy as np
+import streamlit as st
+import torch
+from transformers import AutoTokenizer, AutoModelForSequenceClassification
+from deep_translator import GoogleTranslator
+sys.path.insert(0, os.path.dirname(__file__))
+from recommendations import get_recommendations
+
+warnings.filterwarnings("ignore")
+
+# ── PAGE CONFIG ───────────────────────────────────────────────────────────────
+st.set_page_config(page_title="Mental Health AI", page_icon="🧠", layout="wide")
+
+st.markdown("""
+
+""", unsafe_allow_html=True)
+
+# ── CONSTANTS ─────────────────────────────────────────────────────────────────
+CLASSES = ["anxiety", "depression", "stress"]
+ARABIC_LABELS = {"anxiety": "القلق", "depression": "الاكتئاب", "stress": "الضغط النفسي"}
+COLORS = {"anxiety": "#ffa657", "depression": "#79c0ff", "stress": "#56d364"}
+SEVERITY_AR = {
+ "normal": "طبيعي", "mild": "خفيف", "moderate": "متوسط",
+ "severe": "شديد", "extremely_severe": "شديد جداً", "crisis": "أزمة",
+}
+SEVERITY_COLORS = {
+ "normal": "#56d364", "mild": "#e3b341", "moderate": "#ffa657",
+ "severe": "#f85149", "extremely_severe": "#ff0000", "crisis": "#ff0000",
+}
+
+CAUSE_AR = {
+ "work": "ضغط العمل", "relationships": "العلاقات", "financial": "الضغط المالي",
+ "academic": "الضغط الأكاديمي", "health": "المخاوف الصحية", "social": "القلق الاجتماعي",
+ "self_worth": "الثقة بالنفس", "trauma": "الصدمة النفسية", "general": "عام",
+}
+
+# ── LOAD MODELS ───────────────────────────────────────────────────────────────
+@st.cache_resource
+def load_xlmr():
+ token = st.secrets["HF_TOKEN"]
+ xlmr_tokenizer = AutoTokenizer.from_pretrained(
+ "tasneem33355/mental-xlmr", token=token
+ )
+ model = AutoModelForSequenceClassification.from_pretrained(
+ "tasneem33355/mental-xlmr", token=token
+ )
+ model.eval()
+ # Hardcoded — LabelEncoder على ['anxiety','depression','stress'] دايماً بترتّب alphabetically
+ # 0=anxiety, 1=depression, 2=stress
+ classes = ["anxiety", "depression", "stress"]
+ return xlmr_tokenizer, model, classes
+
+@st.cache_resource
+def load_survey():
+ scaler = pickle.load(open(os.path.join(os.path.dirname(__file__), "scaler.pkl"), "rb"))
+ weights = pickle.load(open(os.path.join(os.path.dirname(__file__), "model_weights.pkl"), "rb"))
+
+ def predict(x):
+ for w in weights:
+ if len(w) == 2:
+ x = np.dot(x, w[0]) + w[1]
+ x = np.maximum(0, x) # ReLU
+ x = np.exp(x) / np.sum(np.exp(x)) # Softmax
+ return x
+
+ return scaler, predict
+
+xlmr_tokenizer, xlmr_model, le = load_xlmr()
+scaler, survey_predict = load_survey()
+
+# ── HELPERS ───────────────────────────────────────────────────────────────────
+def clean_text(text):
+ text = re.sub(r'(.)\1{2,}', r'\1\1', text)
+ text = re.sub(r'[^\w\s\u0600-\u06FF\[\]]', ' ', text)
+ return re.sub(r'\s+', ' ', text).strip()
+
+def translate_to_en(text):
+ try:
+ return GoogleTranslator(source="auto", target="en").translate(text)
+ except Exception:
+ return ""
+
+# ── KEYWORD OVERRIDE ─────────────────────────────────────────────────────────
+DEPRESSION_KEYWORDS = [
+ # عربي فصيح
+ "اكتئاب", "مكتئب", "مكتئبة", "حزن", "حزين", "حزينة", "يأس", "يائس", "يائسة",
+ "فراغ", "إحساس بالفراغ", "بلا معنى", "لا معنى", "مالهاش معنى", "بلا هدف",
+ "لا أمل", "مفيش أمل", "تعبت من الحياة", "زهقت من الحياة",
+ "مش لاقي معنى", "مش لاقية معنى", "حاسس بالفراغ", "حاسة بالفراغ",
+ "مفيش طاقة", "مفيش رغبة", "بكاء", "عايز أبكي", "عايزة أبكي",
+ "وحيد", "وحيدة", "عزلة", "منعزل", "منعزلة",
+ "إرهاق نفسي", "إرهاق عاطفي", "مش حاسس بحاجة", "مش حاسة بحاجة",
+ # عامية مصرية وشامية
+ "زهقت", "تعبت", "مش طايق", "مش طايقة", "نفسيتي وحشة", "نفسيتي في الأرض",
+ "مش قادر أكمل", "مش قادرة أكمل", "مش عايش", "مش قادر أعيش",
+ "مش عايز أصحى", "مش عايزة أصحى", "دموع", "بدمع", "قلبي تقيل",
+ "مش حاسس بنفسي", "مش حاسة بنفسي", "ما بحس بشي", "ما في فايدة",
+ "مافي امل", "ما في امل", "حياتي خربت", "خسرت كل حاجة",
+ # إنجليزي
+ "depressed", "depression", "hopeless", "hopelessness", "empty", "emptiness",
+ "worthless", "meaningless", "no meaning", "no purpose", "cannot go on",
+ "cant go on", "no energy", "no motivation", "crying", "feel nothing",
+ "numb", "isolated", "lonely", "loneliness", "sad", "sadness",
+ "despair", "grief", "miserable", "broken", "lost all hope",
+]
+
+ANXIETY_KEYWORDS = [
+ # عربي
+ "قلق", "قلقان", "قلقانة", "خوف", "خايف", "خايفة", "توتر", "متوتر", "متوترة",
+ "هلع", "مش مرتاح", "مش مرتاحة", "ذعر", "رهاب", "وسواس",
+ # إنجليزي
+ "panic", "anxious", "anxiety", "worried", "worry", "fear",
+ "scared", "nervous", "restless", "tense", "phobia", "ocd",
+]
+
+STRESS_KEYWORDS = [
+ # عربي
+ "ضغط", "ضغوط", "مضغوط", "مضغوطة", "إجهاد", "مجهد", "مجهدة",
+ # إنجليزي
+ "overwhelmed", "stressed", "stress", "burnout", "exhausted", "overloaded",
+]
+
+def keyword_boost(text: str, scores: dict) -> dict:
+ """
+ يعوّض الـ stress bias في الموديل عن طريق override قوي
+ لما تكون كلمات depression أو anxiety أو stress واضحة في النص.
+ """
+ text_lower = text.lower()
+
+ dep_hits = sum(1 for kw in DEPRESSION_KEYWORDS if kw.lower() in text_lower)
+ anx_hits = sum(1 for kw in ANXIETY_KEYWORDS if kw.lower() in text_lower)
+ str_hits = sum(1 for kw in STRESS_KEYWORDS if kw.lower() in text_lower)
+
+ if dep_hits == 0 and anx_hits == 0 and str_hits == 0:
+ return scores
+
+ s = dict(scores)
+
+ if dep_hits > 0 and dep_hits >= anx_hits and dep_hits >= str_hits:
+ # depression كلمات واضحة — override قوي
+ boost = min(0.55 + dep_hits * 0.10, 0.85)
+ s["depression"] = boost
+ remaining = 1.0 - boost
+ total_rest = s["anxiety"] + s["stress"]
+ if total_rest > 0:
+ s["anxiety"] = round(remaining * s["anxiety"] / total_rest, 4)
+ s["stress"] = round(remaining * s["stress"] / total_rest, 4)
+ s["depression"] = round(boost, 4)
+
+ elif anx_hits > 0 and anx_hits >= dep_hits and anx_hits >= str_hits:
+ # anxiety كلمات واضحة — override قوي
+ boost = min(0.55 + anx_hits * 0.10, 0.85)
+ s["anxiety"] = boost
+ remaining = 1.0 - boost
+ total_rest = s["depression"] + s["stress"]
+ if total_rest > 0:
+ s["depression"] = round(remaining * s["depression"] / total_rest, 4)
+ s["stress"] = round(remaining * s["stress"] / total_rest, 4)
+ s["anxiety"] = round(boost, 4)
+
+ elif str_hits > 0 and str_hits >= dep_hits and str_hits >= anx_hits:
+ # stress كلمات واضحة — override قوي
+ boost = min(0.55 + str_hits * 0.10, 0.85)
+ s["stress"] = boost
+ remaining = 1.0 - boost
+ total_rest = s["depression"] + s["anxiety"]
+ if total_rest > 0:
+ s["depression"] = round(remaining * s["depression"] / total_rest, 4)
+ s["anxiety"] = round(remaining * s["anxiety"] / total_rest, 4)
+ s["stress"] = round(boost, 4)
+
+ # normalize
+ total = sum(s.values())
+ if total > 0:
+ s = {k: round(v / total, 4) for k, v in s.items()}
+
+ return s
+
+
+def predict_text(text: str) -> dict:
+ cleaned = clean_text(text)
+ text_en = translate_to_en(cleaned)
+ combined = (text_en + " [SEP] " + cleaned) if text_en else cleaned
+ inputs = xlmr_tokenizer(combined, return_tensors="pt",
+ truncation=True, max_length=192, padding=True)
+ with torch.no_grad():
+ probs = torch.softmax(xlmr_model(**inputs).logits, dim=-1).squeeze().numpy()
+ raw_scores = {c: round(float(p), 4) for c, p in zip(le, probs)}
+ # طبّق الـ keyword boost على النص الأصلي + الترجمة
+ boosted = keyword_boost(text + " " + text_en, raw_scores)
+ return boosted
+
+def predict_survey(answers: list) -> dict:
+ data = scaler.transform(np.array(answers).reshape(1, -1))
+ pred = survey_predict(data)[0]
+ return {
+ "depression": round(float(pred[0]), 4),
+ "anxiety": round(float(pred[1]), 4),
+ "stress": round(float(pred[2]), 4),
+ }
+
+def fuse_scores(text_s, survey_s, w_text=0.4, w_survey=0.6):
+ return {c: round(w_text * text_s[c] + w_survey * survey_s[c], 4) for c in CLASSES}
+
+# ── SURVEY QUESTIONS ─────────────────────────────────────────────────────────
+SURVEY_Q = [
+ ("I found it hard to wind down", "وجدت صعوبة في الاسترخاء"),
+ ("I was aware of dryness of my mouth", "لاحظت جفافاً في فمي"),
+ ("I couldn't seem to experience any positive feeling at all", "لم أستطع الشعور بأي مشاعر إيجابية"),
+ ("I experienced breathing difficulty", "أحسست بصعوبة في التنفس"),
+ ("I found it difficult to work up the initiative to do things", "وجدت صعوبة في اتخاذ المبادرة للقيام بالأشياء"),
+ ("I tended to over-react to situations", "كنت أبالغ في ردود أفعالي تجاه المواقف"),
+ ("I experienced trembling", "شعرت بالرعشة"),
+ ("I felt that I was using a lot of nervous energy", "شعرت أنني أستهلك الكثير من الطاقة العصبية"),
+ ("I was worried about situations in which I might panic", "كنت قلقاً من مواقف قد أصاب فيها بالذعر"),
+ ("I felt that I had nothing to look forward to", "شعرت أنه لا يوجد شيء أتطلع إليه"),
+ ("I found myself getting agitated", "وجدت نفسي أشعر بالانفعال"),
+ ("I found it difficult to relax", "وجدت صعوبة في الاسترخاء"),
+ ("I felt down-hearted and blue", "شعرت بالإحباط والكآبة"),
+ ("I was intolerant of anything that kept me from getting on", "كنت غير متسامح مع أي شيء يعيقني"),
+ ("I felt I was close to panic", "شعرت أنني على وشك الذعر"),
+ ("I was unable to become enthusiastic", "لم أستطع أن أتحمس لأي شيء"),
+ ("I felt I wasn't worth much as a person", "شعرت أنني لست شخصاً ذا قيمة"),
+ ("I felt that I was rather touchy", "شعرت أنني متقلب المزاج"),
+ ("I was aware of the action of my heart", "كنت واعياً لنبضات قلبي"),
+ ("I felt scared without any good reason", "شعرت بالخوف دون سبب واضح"),
+ ("I felt that life was meaningless", "شعرت أن الحياة بلا معنى"),
+ ("I found it hard to calm down", "وجدت صعوبة في التهدئة"),
+ ("I felt nervous", "شعرت بالتوتر"),
+ ("I felt sad and depressed", "شعرت بالحزن والاكتئاب"),
+ ("I found myself getting impatient", "وجدت نفسي أشعر بنفاد الصبر"),
+ ("I felt that I was rather emotional", "شعرت أنني عاطفي بشكل مفرط"),
+ ("I felt restless", "شعرت بعدم الهدوء"),
+ ("I had difficulty concentrating", "وجدت صعوبة في التركيز"),
+ ("I felt lonely", "شعرت بالوحدة"),
+ ("I found it difficult to relax", "وجدت صعوبة في الاسترخاء"),
+ ("I felt hopeless", "شعرت باليأس"),
+ ("I felt worried about many things", "كنت قلقاً بشأن أشياء كثيرة"),
+ ("I felt that I had no energy", "شعرت بعدم وجود طاقة"),
+ ("I felt tense", "شعرت بالتوتر والضيق"),
+ ("I felt tired for no reason", "شعرت بالتعب دون سبب"),
+ ("I felt uneasy", "شعرت بعدم الارتياح"),
+ ("I felt worthless", "شعرت بأنني لا قيمة لي"),
+ ("I felt anxious", "شعرت بالقلق"),
+ ("I felt discouraged", "شعرت بالإحباط"),
+ ("I felt stressed", "شعرت بالضغط"),
+ ("I felt overwhelmed", "شعرت بالإرهاق"),
+ ("I felt emotionally exhausted", "شعرت بالإنهاك العاطفي"),
+]
+
+# ── UI ────────────────────────────────────────────────────────────────────────
+st.title("🧠 Mental Health AI")
+st.markdown(
+ "
"
+ "Write how you feel and answer the survey for a complete assessment"
+ "اكتب ما تشعر به وأجب على الأسئلة للحصول على تقييم شامل
",
+ unsafe_allow_html=True,
+)
+st.markdown("---")
+
+# ── PART 1: TEXT ─────────────────────────────────────────────────────────────
+st.markdown("", unsafe_allow_html=True)
+st.markdown("### 💬 How are you feeling? / كيف تشعر؟")
+st.markdown(
+ "
"
+ "Write in any language — Arabic (any dialect), English, or both "
+ "اكتب بأي لغة — عربي (أي لهجة)، إنجليزي، أو الاتنين
",
+ unsafe_allow_html=True,
+)
+user_text = st.text_area(
+ label="",
+ placeholder="e.g. I've been feeling very overwhelmed at work and can't sleep...\nمثال: أنا تعبان جداً من الشغل ومش قادر أنام...",
+ height=120,
+ label_visibility="collapsed",
+)
+st.markdown("
", unsafe_allow_html=True)
+
+# ── PART 2: SURVEY ────────────────────────────────────────────────────────────
+st.markdown("", unsafe_allow_html=True)
+st.markdown("### 📋 DASS-42 Survey / استبيان DASS-42")
+st.markdown(
+ "
"
+ "0 = Never | 1 = Sometimes | 2 = Often | "
+ "3 = Most of the time | 4 = Always "
+ "0 = لم يحدث أبداً | 1 = أحياناً | 2 = كثيراً | 3 = معظم الوقت | 4 = دائماً
",
+ unsafe_allow_html=True,
+)
+
+survey_answers = []
+for i in range(0, len(SURVEY_Q), 2):
+ cols = st.columns(2)
+ for j, (en, ar) in enumerate(SURVEY_Q[i:i+2]):
+ with cols[j]:
+ val = st.slider(
+ f"{i+j+1}. {en}\n{ar}",
+ min_value=0, max_value=3, value=0,
+ key=f"q_{i+j}",
+ )
+ survey_answers.append(val)
+
+st.markdown("
", unsafe_allow_html=True)
+
+# ── PREDICT BUTTON ────────────────────────────────────────────────────────────
+_, col_btn, _ = st.columns([1, 2, 1])
+with col_btn:
+ predict_btn = st.button("🔍 Analyze / تحليل")
+
+# ── RESULTS ──────────────────────────────────────────────────────────────────
+if predict_btn:
+ if not user_text.strip():
+ st.warning("Please write how you feel first. / من فضلك اكتب ما تشعر به أولاً.")
+ st.stop()
+
+ with st.spinner("Analyzing... / جاري التحليل..."):
+ text_scores = predict_text(user_text)
+ survey_scores = predict_survey(survey_answers)
+ final_scores = fuse_scores(text_scores, survey_scores)
+ primary = max(final_scores, key=final_scores.get)
+ rec = get_recommendations(primary, final_scores[primary], user_text)
+
+ st.markdown("---")
+ st.markdown("## 📊 Results / النتائج")
+
+ # ── SCORE CARDS ───────────────────────────────────────────────────────────
+ cols = st.columns(3)
+ for col, cls in zip(cols, CLASSES):
+ pct = int(final_scores[cls] * 100)
+ is_primary = cls == primary
+ card_class = "result-card primary" if is_primary else "result-card"
+ sev = rec["severity"] if is_primary else ""
+ badge = ""
+ if is_primary and sev:
+ sev_color = SEVERITY_COLORS.get(sev, "#8b949e")
+ badge = (f""
+ f"{sev.replace('_',' ').title()} / {SEVERITY_AR.get(sev,'')}
")
+ col.markdown(f"""
+
+
{cls.title()} / {ARABIC_LABELS[cls]}
+
{pct}%
+ {badge}
+
""", unsafe_allow_html=True)
+
+ # ── PRIMARY LABEL ─────────────────────────────────────────────────────────
+ if not rec["suicidal_flag"]:
+ cause_label = CAUSE_AR.get(rec["cause"], rec["cause"])
+ st.markdown(
+ f""
+ f"Primary: {primary.title()} / {ARABIC_LABELS[primary]} "
+ f" | Cause detected / السبب المكتشف: "
+ f"{rec['cause'].replace('_',' ').title()} / {cause_label}
",
+ unsafe_allow_html=True,
+ )
+
+ # ── CRISIS BOX ────────────────────────────────────────────────────────────
+ if rec["suicidal_flag"]:
+ st.markdown("""
+
+
🚨 Crisis Support Needed / مطلوب دعم أزمة
+ """, unsafe_allow_html=True)
+
+ # ── SCORE DETAILS ─────────────────────────────────────────────────────────
+ with st.expander("Show score breakdown / عرض تفاصيل النتائج"):
+ c1, c2 = st.columns(2)
+ c1.markdown("**Text model / موديل النص:**")
+ for cls in CLASSES:
+ c1.markdown(f"- {cls} / {ARABIC_LABELS[cls]}: **{int(text_scores[cls]*100)}%**")
+ c2.markdown("**Survey model / موديل السيرفاي:**")
+ for cls in CLASSES:
+ c2.markdown(f"- {cls} / {ARABIC_LABELS[cls]}: **{int(survey_scores[cls]*100)}%**")
+
+ # ── RECOMMENDATIONS ───────────────────────────────────────────────────────
+ st.markdown("---")
+ st.markdown("## 💡 Recommendations / التوصيات")
+
+ col_tips, col_res = st.columns(2)
+
+ with col_tips:
+ st.markdown("", unsafe_allow_html=True)
+ st.markdown("
✅ Practical Tips / نصائح عملية
",
+ unsafe_allow_html=True)
+ tips_en = rec.get("tips_en", [])
+ tips_ar = rec.get("tips_ar", [])
+ for en, ar in zip(tips_en, tips_ar):
+ st.markdown(
+ f"
",
+ unsafe_allow_html=True,
+ )
+ st.markdown("
", unsafe_allow_html=True)
+
+ with col_res:
+ st.markdown("", unsafe_allow_html=True)
+ st.markdown("
📚 Resources / موارد مفيدة
",
+ unsafe_allow_html=True)
+ res_en = rec.get("resources_en", [])
+ res_ar = rec.get("resources_ar", [])
+ for en, ar in zip(res_en, res_ar):
+ st.markdown(
+ f"
",
+ unsafe_allow_html=True,
+ )
+ st.markdown("
", unsafe_allow_html=True)
+
+ # ── REFERRAL ──────────────────────────────────────────────────────────────
+ ref_en = rec.get("referral_en", "")
+ ref_ar = rec.get("referral_ar", "")
+ if ref_en:
+ box_class = "crisis-box" if rec["suicidal_flag"] else "referral-box"
+ st.markdown(
+ f""
+ f"🏥 When to seek help / متى تطلب المساعدة: "
+ f"{ref_en} "
+ f"{ref_ar} "
+ f"
",
+ unsafe_allow_html=True,
+ )
+
+ st.markdown(
+ ""
+ "⚠️ This system is for awareness only and is not a substitute for professional medical diagnosis. "
+ "هذا النظام للتوعية فقط وليس بديلاً عن التشخيص الطبي المتخصص.
",
+ unsafe_allow_html=True,
+ )
diff --git a/check_db.py b/check_db.py
new file mode 100644
index 0000000000000000000000000000000000000000..58a988cf6fd79269ab30eab849a57753fbfb57a0
--- /dev/null
+++ b/check_db.py
@@ -0,0 +1,23 @@
+import os
+from sqlalchemy import create_engine, Column, Integer, String, DateTime
+from sqlalchemy.orm import declarative_base, sessionmaker
+
+DATABASE_URL = "postgresql://safespace:AdminAdmin@postgresql-208383-0.cloudclusters.net:19712/safespace"
+
+engine = create_engine(DATABASE_URL)
+SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
+Base = declarative_base()
+
+class DBUser(Base):
+ __tablename__ = "users"
+ id = Column(Integer, primary_key=True, index=True)
+ name = Column(String, nullable=True)
+ email = Column(String, unique=True, index=True)
+ password = Column(String)
+
+db = SessionLocal()
+users = db.query(DBUser).all()
+print(f"Total users: {len(users)}")
+for u in users:
+ print(f"ID: {u.id}, Email: {u.email}, Password Hash: {u.password}")
+db.close()
diff --git a/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/History b/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/History
new file mode 100644
index 0000000000000000000000000000000000000000..46bfb67d7a4defe714194092b8549715e375da1b
--- /dev/null
+++ b/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/History
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:18bb7fac167630752b1cfa38fdbd37883c97701d67639db61141b814498b3388
+size 163840
diff --git a/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/Web Data b/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/Web Data
new file mode 100644
index 0000000000000000000000000000000000000000..26a6944507a4bfcfaa63e79599510b3a2bc2c2b6
--- /dev/null
+++ b/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/Web Data
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3743dd646541935eebc92ec44dc065a71a5beefd8165facae2a5a73eeb6ae656
+size 157696
diff --git a/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log b/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log
new file mode 100644
index 0000000000000000000000000000000000000000..8669d1b19b76c715c1ca9c34a57353bf6af20be8
--- /dev/null
+++ b/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:224b7af78f931fbc5e380e4970816885ce968e38da0eb46f510b4a661f7b55db
+size 111699
diff --git a/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb b/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb
new file mode 100644
index 0000000000000000000000000000000000000000..39c9d5d4df9acafb6c0629251c63786a90123761
--- /dev/null
+++ b/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b87bf305aafae1f1ec7dd947176c9529b2a9cbd4a3bf296fce25fc009e725366
+size 84
diff --git a/clean_git_repo/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill b/clean_git_repo/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
new file mode 100644
index 0000000000000000000000000000000000000000..9dbf20fbb73c80ab708d144f6ce9bc0b96d6dd9f
--- /dev/null
+++ b/clean_git_repo/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae0b1b0e267ea854918ca7afbf3c5be6a073deae0894ad6ad67ffd9f78b46c7a
+size 41863640
diff --git a/clean_git_repo/UI/safespace/build/flutter_assets/AssetManifest.bin b/clean_git_repo/UI/safespace/build/flutter_assets/AssetManifest.bin
new file mode 100644
index 0000000000000000000000000000000000000000..1811cbdd65eaf822a27ec3cb6c1f26a069e55a89
--- /dev/null
+++ b/clean_git_repo/UI/safespace/build/flutter_assets/AssetManifest.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:00af55ad3d6f21898fe77e0ff092d1a1cda52c941b6860e9928d45c8af8c095d
+size 117
diff --git a/clean_git_repo/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf b/clean_git_repo/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf
new file mode 100644
index 0000000000000000000000000000000000000000..0e72af0d1c2d8662f7be287eb6d27210edbbfa1f
--- /dev/null
+++ b/clean_git_repo/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d9865b671a09d683d13a863089d8825e0f61a37696ce5d7d448bc8023aa62453
+size 1645184
diff --git a/clean_git_repo/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf b/clean_git_repo/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..e98baa9f284d21d1e6d3837523e5d879e73dca86
--- /dev/null
+++ b/clean_git_repo/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:67c44fe9183b002e79dde7f6977e2988661c9a3e4a3c5fce968787efdbed823c
+size 257628
diff --git a/clean_git_repo/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/clean_git_repo/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
new file mode 100644
index 0000000000000000000000000000000000000000..0066c008ba292c746ef170676f5643de1742f589
--- /dev/null
+++ b/clean_git_repo/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6232e5815af17e25e0268b2fec7aea9e068cc92ec709e9605c2b31df4ff2a313
+size 102994
diff --git a/clean_git_repo/data.csv b/clean_git_repo/data.csv
new file mode 100644
index 0000000000000000000000000000000000000000..0847e02e19d0c56ffac0e1c3a236b920fc543bee
--- /dev/null
+++ b/clean_git_repo/data.csv
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d6b39f44704ef71efab7fb6223ffaa68bc84af9c7c42875310c043242dac593d
+size 20819959
diff --git a/clean_git_repo/mental_model.h5 b/clean_git_repo/mental_model.h5
new file mode 100644
index 0000000000000000000000000000000000000000..693a1c764002481b5135c428003eaf8eb872d8f0
--- /dev/null
+++ b/clean_git_repo/mental_model.h5
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d83c61efe6d2ff698925835f970cce7d65026107d6adcbe8eb31b58ed1ac4325
+size 259632
diff --git a/clean_git_repo/mental_xlmr_final/label_encoder.pkl b/clean_git_repo/mental_xlmr_final/label_encoder.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..16a91edce0554ab569252f4a5ab2b709edf178b9
--- /dev/null
+++ b/clean_git_repo/mental_xlmr_final/label_encoder.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7459c4d557907ee7efd7151ef3618a1a47b74750e839c56c50d450f6a2553c20
+size 275
diff --git a/clean_git_repo/mental_xlmr_final/tokenizer.json b/clean_git_repo/mental_xlmr_final/tokenizer.json
new file mode 100644
index 0000000000000000000000000000000000000000..b4f6f590cde1393c600866cd86431644f2acbae0
--- /dev/null
+++ b/clean_git_repo/mental_xlmr_final/tokenizer.json
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:542cda5f12d1c653dd46ac4d8c992d71e0047e65e7bf2cdda17c2d43b1d94b37
+size 17781767
diff --git a/clean_git_repo/mental_xlmr_final/training_args.bin b/clean_git_repo/mental_xlmr_final/training_args.bin
new file mode 100644
index 0000000000000000000000000000000000000000..6c71739c0891e0e9a564ade3b6560d7e6ed26905
--- /dev/null
+++ b/clean_git_repo/mental_xlmr_final/training_args.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d487b97c54aa8b5c1582f059ef3c809014c6d48eabd7a6c0be396fc96cf835f2
+size 5201
diff --git a/clean_git_repo/model_weights.pkl b/clean_git_repo/model_weights.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..13e811fccdc58b055dd08dc019eb889377c128a3
--- /dev/null
+++ b/clean_git_repo/model_weights.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c7f5e42ca4cda8a43af36c8b72b4ac1dfe500fbab6c7359d26c1eaa9048b37f7
+size 68153
diff --git a/clean_git_repo/scaler.pkl b/clean_git_repo/scaler.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..448673ece4b713d1a799c2afb888346fc35d1e59
--- /dev/null
+++ b/clean_git_repo/scaler.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fe630eaf06688d9090bba2e118657f64d1fbdf3506175f640cf4990effbfdb22
+size 1467
diff --git a/core_ai.py b/core_ai.py
new file mode 100644
index 0000000000000000000000000000000000000000..7c6a888f4bbdb441cab4c1c313b262c74160b0ce
--- /dev/null
+++ b/core_ai.py
@@ -0,0 +1,180 @@
+import os
+import re
+import pickle
+import warnings
+from functools import lru_cache
+
+import numpy as np
+import torch
+from transformers import AutoTokenizer, AutoModelForSequenceClassification
+from deep_translator import GoogleTranslator
+
+warnings.filterwarnings("ignore")
+
+CLASSES = ["anxiety", "depression", "stress"]
+
+
+# ── KEYWORD OVERRIDE ─────────────────────────────────────────────────────────
+DEPRESSION_KEYWORDS = [
+ # Arabic (Fusha + dialects)
+ "اكتئاب", "مكتئب", "مكتئبة", "حزن", "حزين", "حزينة", "يأس", "يائس", "يائسة",
+ "فراغ", "إحساس بالفراغ", "بلا معنى", "لا معنى", "مالهاش معنى", "بلا هدف",
+ "لا أمل", "مفيش أمل", "تعبت من الحياة", "زهقت من الحياة",
+ "مش لاقي معنى", "مش لاقية معنى", "حاسس بالفراغ", "حاسة بالفراغ",
+ "مفيش طاقة", "مفيش رغبة", "بكاء", "عايز أبكي", "عايزة أبكي",
+ "وحيد", "وحيدة", "عزلة", "منعزل", "منعزلة",
+ "إرهاق نفسي", "إرهاق عاطفي", "مش حاسس بحاجة", "مش حاسة بحاجة",
+ "زهقت", "تعبت", "مش طايق", "مش طايقة", "نفسيتي وحشة", "نفسيتي في الأرض",
+ "مش قادر أكمل", "مش قادرة أكمل", "مش عايش", "مش قادر أعيش",
+ "مش عايز أصحى", "مش عايزة أصحى", "دموع", "بدمع", "قلبي تقيل",
+ "مش حاسس بنفسي", "مش حاسة بنفسي", "ما بحس بشي", "ما في فايدة",
+ "مافي امل", "ما في امل", "حياتي خربت", "خسرت كل حاجة",
+ # English
+ "depressed", "depression", "hopeless", "hopelessness", "empty", "emptiness",
+ "worthless", "meaningless", "no meaning", "no purpose", "cannot go on",
+ "cant go on", "no energy", "no motivation", "crying", "feel nothing",
+ "numb", "isolated", "lonely", "loneliness", "sad", "sadness",
+ "despair", "grief", "miserable", "broken", "lost all hope",
+]
+
+ANXIETY_KEYWORDS = [
+ # Arabic
+ "قلق", "قلقان", "قلقانة", "خوف", "خايف", "خايفة", "توتر", "متوتر", "متوترة",
+ "هلع", "مش مرتاح", "مش مرتاحة", "ذعر", "رهاب", "وسواس",
+ # English
+ "panic", "anxious", "anxiety", "worried", "worry", "fear",
+ "scared", "nervous", "restless", "tense", "phobia", "ocd",
+]
+
+STRESS_KEYWORDS = [
+ # Arabic
+ "ضغط", "ضغوط", "مضغوط", "مضغوطة", "إجهاد", "مجهد", "مجهدة",
+ # English
+ "overwhelmed", "stressed", "stress", "burnout", "exhausted", "overloaded",
+]
+
+
+def keyword_boost(text: str, scores: dict) -> dict:
+ text_lower = text.lower()
+
+ dep_hits = sum(1 for kw in DEPRESSION_KEYWORDS if kw.lower() in text_lower)
+ anx_hits = sum(1 for kw in ANXIETY_KEYWORDS if kw.lower() in text_lower)
+ str_hits = sum(1 for kw in STRESS_KEYWORDS if kw.lower() in text_lower)
+
+ if dep_hits == 0 and anx_hits == 0 and str_hits == 0:
+ return scores
+
+ s = dict(scores)
+
+ if dep_hits > 0 and dep_hits >= anx_hits and dep_hits >= str_hits:
+ boost = min(0.55 + dep_hits * 0.10, 0.85)
+ s["depression"] = boost
+ remaining = 1.0 - boost
+ total_rest = s["anxiety"] + s["stress"]
+ if total_rest > 0:
+ s["anxiety"] = round(remaining * s["anxiety"] / total_rest, 4)
+ s["stress"] = round(remaining * s["stress"] / total_rest, 4)
+ s["depression"] = round(boost, 4)
+
+ elif anx_hits > 0 and anx_hits >= dep_hits and anx_hits >= str_hits:
+ boost = min(0.55 + anx_hits * 0.10, 0.85)
+ s["anxiety"] = boost
+ remaining = 1.0 - boost
+ total_rest = s["depression"] + s["stress"]
+ if total_rest > 0:
+ s["depression"] = round(remaining * s["depression"] / total_rest, 4)
+ s["stress"] = round(remaining * s["stress"] / total_rest, 4)
+ s["anxiety"] = round(boost, 4)
+
+ elif str_hits > 0 and str_hits >= dep_hits and str_hits >= anx_hits:
+ boost = min(0.55 + str_hits * 0.10, 0.85)
+ s["stress"] = boost
+ remaining = 1.0 - boost
+ total_rest = s["depression"] + s["anxiety"]
+ if total_rest > 0:
+ s["depression"] = round(remaining * s["depression"] / total_rest, 4)
+ s["anxiety"] = round(remaining * s["anxiety"] / total_rest, 4)
+ s["stress"] = round(boost, 4)
+
+ total = sum(s.values())
+ if total > 0:
+ s = {k: round(v / total, 4) for k, v in s.items()}
+
+ return s
+
+
+@lru_cache(maxsize=1)
+def load_xlmr():
+ model_id = os.getenv("HF_MODEL_ID", "AliSakr9997/Mental-XLMR-Model")
+ token = os.getenv("HF_TOKEN")
+ kwargs = {"token": token} if token else {}
+ local_dir = os.path.join(os.path.dirname(__file__), "mental_xlmr_final")
+ local_weights = any(
+ os.path.exists(os.path.join(local_dir, fname))
+ for fname in ("pytorch_model.bin", "model.safetensors")
+ )
+ source = local_dir if local_weights else model_id
+ tokenizer = AutoTokenizer.from_pretrained(source, **kwargs)
+ model = AutoModelForSequenceClassification.from_pretrained(source, **kwargs)
+ le_path = os.path.join(os.path.dirname(__file__), "mental_xlmr_final", "label_encoder.pkl")
+ with open(le_path, "rb") as f:
+ le = pickle.load(f)
+ model.eval()
+ return tokenizer, model, le
+
+
+@lru_cache(maxsize=1)
+def load_survey():
+ scaler = pickle.load(open(os.path.join(os.path.dirname(__file__), "scaler.pkl"), "rb"))
+ weights = pickle.load(open(os.path.join(os.path.dirname(__file__), "model_weights.pkl"), "rb"))
+
+ def predict(x):
+ for w in weights:
+ if len(w) == 2:
+ x = np.dot(x, w[0]) + w[1]
+ x = np.maximum(0, x)
+ x = np.exp(x) / np.sum(np.exp(x))
+ return x
+
+ return scaler, predict
+
+
+def clean_text(text: str) -> str:
+ text = re.sub(r"(.)\1{2,}", r"\1\1", text)
+ text = re.sub(r"[^\w\s\u0600-\u06FF\[\]]", " ", text)
+ return re.sub(r"\s+", " ", text).strip()
+
+
+def translate_to_en(text: str) -> str:
+ try:
+ return GoogleTranslator(source="auto", target="en").translate(text)
+ except Exception:
+ return ""
+
+
+def predict_text(text: str) -> dict:
+ tokenizer, model, le = load_xlmr()
+ cleaned = clean_text(text)
+ text_en = translate_to_en(cleaned)
+ combined = (text_en + " [SEP] " + cleaned) if text_en else cleaned
+ inputs = tokenizer(combined, return_tensors="pt", truncation=True, max_length=192, padding=True)
+ with torch.no_grad():
+ probs = torch.softmax(model(**inputs).logits, dim=-1).squeeze().numpy()
+ raw_scores = {c: round(float(p), 4) for c, p in zip(le.classes_, probs)}
+ boosted = keyword_boost(text + " " + text_en, raw_scores)
+ return boosted
+
+
+def predict_survey(answers: list) -> dict:
+ scaler, survey_predict = load_survey()
+ data = scaler.transform(np.array(answers).reshape(1, -1))
+ pred = survey_predict(data)[0]
+ return {
+ "depression": round(float(pred[0]), 4),
+ "anxiety": round(float(pred[1]), 4),
+ "stress": round(float(pred[2]), 4),
+ }
+
+
+def fuse_scores(text_s, survey_s, w_text=0.4, w_survey=0.6):
+ return {c: round(w_text * text_s[c] + w_survey * survey_s[c], 4) for c in CLASSES}
diff --git a/data.csv b/data.csv
new file mode 100644
index 0000000000000000000000000000000000000000..0847e02e19d0c56ffac0e1c3a236b920fc543bee
--- /dev/null
+++ b/data.csv
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d6b39f44704ef71efab7fb6223ffaa68bc84af9c7c42875310c043242dac593d
+size 20819959
diff --git a/mental_model.h5 b/mental_model.h5
new file mode 100644
index 0000000000000000000000000000000000000000..693a1c764002481b5135c428003eaf8eb872d8f0
--- /dev/null
+++ b/mental_model.h5
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d83c61efe6d2ff698925835f970cce7d65026107d6adcbe8eb31b58ed1ac4325
+size 259632
diff --git a/mental_xlmr_final/label_encoder.pkl b/mental_xlmr_final/label_encoder.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..16a91edce0554ab569252f4a5ab2b709edf178b9
--- /dev/null
+++ b/mental_xlmr_final/label_encoder.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7459c4d557907ee7efd7151ef3618a1a47b74750e839c56c50d450f6a2553c20
+size 275
diff --git a/mental_xlmr_final/tokenizer.json b/mental_xlmr_final/tokenizer.json
new file mode 100644
index 0000000000000000000000000000000000000000..b4f6f590cde1393c600866cd86431644f2acbae0
--- /dev/null
+++ b/mental_xlmr_final/tokenizer.json
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:542cda5f12d1c653dd46ac4d8c992d71e0047e65e7bf2cdda17c2d43b1d94b37
+size 17781767
diff --git a/mental_xlmr_final/training_args.bin b/mental_xlmr_final/training_args.bin
new file mode 100644
index 0000000000000000000000000000000000000000..6c71739c0891e0e9a564ade3b6560d7e6ed26905
--- /dev/null
+++ b/mental_xlmr_final/training_args.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d487b97c54aa8b5c1582f059ef3c809014c6d48eabd7a6c0be396fc96cf835f2
+size 5201
diff --git a/model_weights.pkl b/model_weights.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..13e811fccdc58b055dd08dc019eb889377c128a3
--- /dev/null
+++ b/model_weights.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c7f5e42ca4cda8a43af36c8b72b4ac1dfe500fbab6c7359d26c1eaa9048b37f7
+size 68153
diff --git a/scaler.pkl b/scaler.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..448673ece4b713d1a799c2afb888346fc35d1e59
--- /dev/null
+++ b/scaler.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fe630eaf06688d9090bba2e118657f64d1fbdf3506175f640cf4990effbfdb22
+size 1467
diff --git a/temp_space/README.md b/temp_space/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..b54744bf3f7f4966aa9e87618f1d1cdfd26c3fd6
--- /dev/null
+++ b/temp_space/README.md
@@ -0,0 +1,72 @@
+---
+title: SafeSpace API
+emoji: 🧠
+colorFrom: blue
+colorTo: green
+sdk: docker
+python_version: "3.11"
+pinned: false
+---
+
+# 🧠 Mental Health Prediction System
+
+## 📌 Project Overview
+
+This project builds a **Machine Learning system** that predicts mental health conditions based on questionnaire answers.
+
+The system predicts:
+
+- Depression Level
+- Anxiety Level
+- Stress Level
+
+The model takes questionnaire answers as input and outputs:
+
+- Percentage of Depression
+- Percentage of Anxiety
+- Percentage of Stress
+
+---
+
+# 🗺️ Project Roadmap
+
+## Phase 1 — Problem Definition
+
+### Goal
+
+Build a Machine Learning model that predicts mental health conditions from questionnaire answers.
+
+The system should:
+
+- Accept user answers
+- Predict mental health scores
+- Show percentages
+- Classify severity levels
+
+Predicted Conditions:
+
+- Depression
+- Anxiety
+- Stress
+
+---
+
+## Phase 2 — Dataset
+
+### Dataset Description
+
+The dataset contains questionnaire answers and mental health scores.
+
+### Dataset Size
+
+- Samples: **39,775**
+- Features: **42 questions**
+- Targets: **3 scores**
+
+Targets:
+
+- Depression Score
+- Anxiety Score
+- Stress Score
+
+Example Features:
diff --git a/temp_space/Requirements.txt b/temp_space/Requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4220da1335844290da4c3144d05acdb90a04e454
--- /dev/null
+++ b/temp_space/Requirements.txt
@@ -0,0 +1,15 @@
+streamlit>=1.32.0
+transformers>=4.41.0
+torch>=2.0.0
+tensorflow>=2.12.0
+scikit-learn>=1.3.0
+deep-translator>=1.11.4
+numpy>=1.24.0
+fastapi>=0.100.0
+uvicorn>=0.23.0
+pydantic>=2.4.0
+python-multipart>=0.0.6
+sentencepiece>=0.1.99
+sqlalchemy>=2.0.0
+psycopg2-binary>=2.9.0
+httpx>=0.25.0
\ No newline at end of file
diff --git a/temp_space/UI/safespace/.dart_tool/chrome-device/Default/History b/temp_space/UI/safespace/.dart_tool/chrome-device/Default/History
new file mode 100644
index 0000000000000000000000000000000000000000..46bfb67d7a4defe714194092b8549715e375da1b
--- /dev/null
+++ b/temp_space/UI/safespace/.dart_tool/chrome-device/Default/History
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:18bb7fac167630752b1cfa38fdbd37883c97701d67639db61141b814498b3388
+size 163840
diff --git a/temp_space/UI/safespace/.dart_tool/chrome-device/Default/Web Data b/temp_space/UI/safespace/.dart_tool/chrome-device/Default/Web Data
new file mode 100644
index 0000000000000000000000000000000000000000..26a6944507a4bfcfaa63e79599510b3a2bc2c2b6
--- /dev/null
+++ b/temp_space/UI/safespace/.dart_tool/chrome-device/Default/Web Data
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3743dd646541935eebc92ec44dc065a71a5beefd8165facae2a5a73eeb6ae656
+size 157696
diff --git a/temp_space/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log b/temp_space/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log
new file mode 100644
index 0000000000000000000000000000000000000000..8669d1b19b76c715c1ca9c34a57353bf6af20be8
--- /dev/null
+++ b/temp_space/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:224b7af78f931fbc5e380e4970816885ce968e38da0eb46f510b4a661f7b55db
+size 111699
diff --git a/temp_space/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb b/temp_space/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb
new file mode 100644
index 0000000000000000000000000000000000000000..39c9d5d4df9acafb6c0629251c63786a90123761
--- /dev/null
+++ b/temp_space/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b87bf305aafae1f1ec7dd947176c9529b2a9cbd4a3bf296fce25fc009e725366
+size 84
diff --git a/temp_space/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill b/temp_space/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
new file mode 100644
index 0000000000000000000000000000000000000000..9dbf20fbb73c80ab708d144f6ce9bc0b96d6dd9f
--- /dev/null
+++ b/temp_space/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae0b1b0e267ea854918ca7afbf3c5be6a073deae0894ad6ad67ffd9f78b46c7a
+size 41863640
diff --git a/temp_space/UI/safespace/build/flutter_assets/AssetManifest.bin b/temp_space/UI/safespace/build/flutter_assets/AssetManifest.bin
new file mode 100644
index 0000000000000000000000000000000000000000..1811cbdd65eaf822a27ec3cb6c1f26a069e55a89
--- /dev/null
+++ b/temp_space/UI/safespace/build/flutter_assets/AssetManifest.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:00af55ad3d6f21898fe77e0ff092d1a1cda52c941b6860e9928d45c8af8c095d
+size 117
diff --git a/temp_space/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf b/temp_space/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf
new file mode 100644
index 0000000000000000000000000000000000000000..0e72af0d1c2d8662f7be287eb6d27210edbbfa1f
--- /dev/null
+++ b/temp_space/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d9865b671a09d683d13a863089d8825e0f61a37696ce5d7d448bc8023aa62453
+size 1645184
diff --git a/temp_space/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf b/temp_space/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..e98baa9f284d21d1e6d3837523e5d879e73dca86
--- /dev/null
+++ b/temp_space/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:67c44fe9183b002e79dde7f6977e2988661c9a3e4a3c5fce968787efdbed823c
+size 257628
diff --git a/temp_space/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/temp_space/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
new file mode 100644
index 0000000000000000000000000000000000000000..0066c008ba292c746ef170676f5643de1742f589
--- /dev/null
+++ b/temp_space/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6232e5815af17e25e0268b2fec7aea9e068cc92ec709e9605c2b31df4ff2a313
+size 102994
diff --git a/temp_space/Untitled.ipynb b/temp_space/Untitled.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..08919f806ca5a2bc43e2ecfdcb67b8bfd43c26c0
--- /dev/null
+++ b/temp_space/Untitled.ipynb
@@ -0,0 +1,4063 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "efa50ec2-988b-4f3a-a1a8-29aab0f3e1f4",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(39775, 172)"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "\n",
+ "df = pd.read_csv(\"data.csv\", sep=\"\\t\", engine=\"python\")\n",
+ "\n",
+ "df.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "7efef343-f8b4-4474-8d03-f74a3a91a828",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(['Q1A', 'Q2A', 'Q3A', 'Q4A', 'Q5A', 'Q6A', 'Q7A', 'Q8A', 'Q9A', 'Q10A'], 42)"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[q for q in df.columns if \"Q\" in q and \"A\" in q][:10], len([q for q in df.columns if \"A\" in q])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "77f4e0df-23dd-4568-bce3-98d7622877bb",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(39775, 42)"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "cols = [f\"Q{i}A\" for i in range(1,43)]\n",
+ "data = df[cols].copy()\n",
+ "\n",
+ "data.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "3272cc68-5a5f-4634-86eb-4a792682a4b6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(np.int64(0), array([dtype('int64')], dtype=object), np.int64(1), np.int64(4))"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data.isnull().sum().sum(), data.dtypes.unique(), data.min().min(), data.max().max()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "ed451387-3cd9-4bee-bc88-4c1ef439ee28",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(np.int64(0), np.int64(3))"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data = data - 1\n",
+ "\n",
+ "data.min().min(), data.max().max()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "43a8c09b-1443-49f9-91c2-cb3de8e76897",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " Depression_Score \n",
+ " Anxiety_Score \n",
+ " Stress_Score \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " count \n",
+ " 39775.000000 \n",
+ " 39775.000000 \n",
+ " 39775.000000 \n",
+ " \n",
+ " \n",
+ " mean \n",
+ " 21.060088 \n",
+ " 16.054758 \n",
+ " 21.153891 \n",
+ " \n",
+ " \n",
+ " std \n",
+ " 12.321566 \n",
+ " 10.249169 \n",
+ " 10.523291 \n",
+ " \n",
+ " \n",
+ " min \n",
+ " 0.000000 \n",
+ " 0.000000 \n",
+ " 0.000000 \n",
+ " \n",
+ " \n",
+ " 25% \n",
+ " 11.000000 \n",
+ " 8.000000 \n",
+ " 13.000000 \n",
+ " \n",
+ " \n",
+ " 50% \n",
+ " 21.000000 \n",
+ " 15.000000 \n",
+ " 21.000000 \n",
+ " \n",
+ " \n",
+ " 75% \n",
+ " 32.000000 \n",
+ " 23.000000 \n",
+ " 29.000000 \n",
+ " \n",
+ " \n",
+ " max \n",
+ " 42.000000 \n",
+ " 42.000000 \n",
+ " 42.000000 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Depression_Score Anxiety_Score Stress_Score\n",
+ "count 39775.000000 39775.000000 39775.000000\n",
+ "mean 21.060088 16.054758 21.153891\n",
+ "std 12.321566 10.249169 10.523291\n",
+ "min 0.000000 0.000000 0.000000\n",
+ "25% 11.000000 8.000000 13.000000\n",
+ "50% 21.000000 15.000000 21.000000\n",
+ "75% 32.000000 23.000000 29.000000\n",
+ "max 42.000000 42.000000 42.000000"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "depression_items = [3,5,10,13,16,17,21,24,26,31,34,37,38,42]\n",
+ "anxiety_items = [2,4,7,9,15,19,20,23,25,28,30,36,40,41]\n",
+ "stress_items = [1,6,8,11,12,14,18,22,27,29,32,33,35,39]\n",
+ "\n",
+ "data[\"Depression_Score\"] = data[[f\"Q{i}A\" for i in depression_items]].sum(axis=1)\n",
+ "data[\"Anxiety_Score\"] = data[[f\"Q{i}A\" for i in anxiety_items]].sum(axis=1)\n",
+ "data[\"Stress_Score\"] = data[[f\"Q{i}A\" for i in stress_items]].sum(axis=1)\n",
+ "\n",
+ "data[[\"Depression_Score\",\"Anxiety_Score\",\"Stress_Score\"]].describe()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "01db3116-44a0-4fd4-9f4f-5544190b266e",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Depression_Label 0.682162\n",
+ "Anxiety_Label 0.685933\n",
+ "Stress_Label 0.579610\n",
+ "dtype: float64"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data[\"Depression_Label\"] = (data[\"Depression_Score\"] >= 14).astype(int)\n",
+ "data[\"Anxiety_Label\"] = (data[\"Anxiety_Score\"] >= 10).astype(int)\n",
+ "data[\"Stress_Label\"] = (data[\"Stress_Score\"] >= 19).astype(int)\n",
+ "\n",
+ "data[[\"Depression_Label\",\"Anxiety_Label\",\"Stress_Label\"]].mean()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "f67639f9-f4ce-420b-973b-ce94be9f92ba",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " Depression_Label \n",
+ " Anxiety_Label \n",
+ " Stress_Label \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " Depression_Label \n",
+ " 1.000000 \n",
+ " 0.510057 \n",
+ " 0.561400 \n",
+ " \n",
+ " \n",
+ " Anxiety_Label \n",
+ " 0.510057 \n",
+ " 1.000000 \n",
+ " 0.585488 \n",
+ " \n",
+ " \n",
+ " Stress_Label \n",
+ " 0.561400 \n",
+ " 0.585488 \n",
+ " 1.000000 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Depression_Label Anxiety_Label Stress_Label\n",
+ "Depression_Label 1.000000 0.510057 0.561400\n",
+ "Anxiety_Label 0.510057 1.000000 0.585488\n",
+ "Stress_Label 0.561400 0.585488 1.000000"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data[[\"Depression_Label\",\"Anxiety_Label\",\"Stress_Label\"]].corr()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "5494959b-5ce8-4818-8bd7-2af97a69603b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Total_Disorders\n",
+ "3 0.489654\n",
+ "0 0.196933\n",
+ "2 0.165330\n",
+ "1 0.148083\n",
+ "Name: proportion, dtype: float64"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "data[\"Total_Disorders\"] = data[[\"Depression_Label\",\"Anxiety_Label\",\"Stress_Label\"]].sum(axis=1)\n",
+ "\n",
+ "data[\"Total_Disorders\"].value_counts(normalize=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "ce012c29-e98b-4a4c-8abd-6026946d6600",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "((31820, 42), (7955, 42))"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.model_selection import train_test_split\n",
+ "\n",
+ "X = data[[f\"Q{i}A\" for i in range(1,43)]]\n",
+ "y = data[[\"Depression_Label\",\"Anxiety_Label\",\"Stress_Label\"]]\n",
+ "\n",
+ "X_train, X_test, y_train, y_test = train_test_split(\n",
+ " X, y, test_size=0.2, random_state=42, stratify=data[\"Total_Disorders\"]\n",
+ ")\n",
+ "\n",
+ "X_train.shape, X_test.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "98ee78b3-69eb-4dea-b419-e06e86829f63",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "((31820, 42), (7955, 42))"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.preprocessing import StandardScaler\n",
+ "\n",
+ "scaler = StandardScaler()\n",
+ "\n",
+ "X_train_scaled = scaler.fit_transform(X_train)\n",
+ "X_test_scaled = scaler.transform(X_test)\n",
+ "\n",
+ "X_train_scaled.shape, X_test_scaled.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "6b59cd71-e919-49ce-88af-ba611aeeea78",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Depression_Label 0.463325\n",
+ "Anxiety_Label 0.460370\n",
+ "Stress_Label 0.725316\n",
+ "dtype: float64"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pos_weights = (len(y_train) - y_train.sum()) / y_train.sum()\n",
+ "pos_weights"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "e2b680f6-7d2d-4387-97e6-e651b8c0f4c1",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import tensorflow as tf\n",
+ "\n",
+ "pos_weights_tf = tf.constant(\n",
+ " pos_weights.values,\n",
+ " dtype=tf.float32\n",
+ ")\n",
+ "\n",
+ "def weighted_binary_crossentropy(y_true, y_pred):\n",
+ " epsilon = tf.keras.backend.epsilon()\n",
+ " y_pred = tf.clip_by_value(y_pred, epsilon, 1. - epsilon)\n",
+ " loss = (\n",
+ " y_true * tf.math.log(y_pred) * pos_weights_tf +\n",
+ " (1 - y_true) * tf.math.log(1 - y_pred)\n",
+ " )\n",
+ " return -tf.reduce_mean(loss)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "50cb9044-881f-40e6-9053-047defdc4d51",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "E:\\conda\\envs\\tf\\lib\\site-packages\\keras\\src\\layers\\core\\dense.py:95: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n",
+ " super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "Model: \"sequential\" \n",
+ " \n"
+ ],
+ "text/plain": [
+ "\u001b[1mModel: \"sequential\"\u001b[0m\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n",
+ "┃ Layer (type) ┃ Output Shape ┃ Param # ┃\n",
+ "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n",
+ "│ dense (Dense ) │ (None , 128 ) │ 5,504 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization │ (None , 128 ) │ 512 │\n",
+ "│ (BatchNormalization ) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dropout (Dropout ) │ (None , 128 ) │ 0 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_1 (Dense ) │ (None , 64 ) │ 8,256 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_1 │ (None , 64 ) │ 256 │\n",
+ "│ (BatchNormalization ) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dropout_1 (Dropout ) │ (None , 64 ) │ 0 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_2 (Dense ) │ (None , 32 ) │ 2,080 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_2 │ (None , 32 ) │ 128 │\n",
+ "│ (BatchNormalization ) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_3 (Dense ) │ (None , 3 ) │ 99 │\n",
+ "└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n",
+ " \n"
+ ],
+ "text/plain": [
+ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n",
+ "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
+ "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n",
+ "│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m5,504\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m512\u001b[0m │\n",
+ "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dropout (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m8,256\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_1 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m256\u001b[0m │\n",
+ "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dropout_1 (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_2 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m2,080\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_2 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m128\u001b[0m │\n",
+ "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_3 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m3\u001b[0m) │ \u001b[38;5;34m99\u001b[0m │\n",
+ "└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Total params: 16,835 (65.76 KB)\n",
+ " \n"
+ ],
+ "text/plain": [
+ "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m16,835\u001b[0m (65.76 KB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Trainable params: 16,387 (64.01 KB)\n",
+ " \n"
+ ],
+ "text/plain": [
+ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m16,387\u001b[0m (64.01 KB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Non-trainable params: 448 (1.75 KB)\n",
+ " \n"
+ ],
+ "text/plain": [
+ "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m448\u001b[0m (1.75 KB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from tensorflow.keras.models import Sequential\n",
+ "from tensorflow.keras.layers import Dense, Dropout, BatchNormalization\n",
+ "from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\n",
+ "\n",
+ "model = Sequential([\n",
+ " Dense(128, activation=\"relu\", input_shape=(42,)),\n",
+ " BatchNormalization(),\n",
+ " Dropout(0.4),\n",
+ "\n",
+ " Dense(64, activation=\"relu\"),\n",
+ " BatchNormalization(),\n",
+ " Dropout(0.3),\n",
+ "\n",
+ " Dense(32, activation=\"relu\"),\n",
+ " BatchNormalization(),\n",
+ "\n",
+ " Dense(3, activation=\"sigmoid\")\n",
+ "])\n",
+ "\n",
+ "model.compile(\n",
+ " optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n",
+ " loss=weighted_binary_crossentropy,\n",
+ " metrics=[tf.keras.metrics.AUC(name=\"auc\")]\n",
+ ")\n",
+ "\n",
+ "model.summary()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "867c8f7b-75e9-4114-b059-286653b85542",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 1/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8s\u001b[0m 13ms/step - auc: 0.9494 - loss: 0.2072 - val_auc: 0.9724 - val_loss: 0.3442 - learning_rate: 0.0010\n",
+ "Epoch 2/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 8ms/step - auc: 0.9878 - loss: 0.1032 - val_auc: 0.9939 - val_loss: 0.1354 - learning_rate: 0.0010\n",
+ "Epoch 3/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9924 - loss: 0.0793 - val_auc: 0.9981 - val_loss: 0.0605 - learning_rate: 0.0010\n",
+ "Epoch 4/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9940 - loss: 0.0697 - val_auc: 0.9991 - val_loss: 0.0390 - learning_rate: 0.0010\n",
+ "Epoch 5/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9953 - loss: 0.0614 - val_auc: 0.9995 - val_loss: 0.0353 - learning_rate: 0.0010\n",
+ "Epoch 6/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - auc: 0.9958 - loss: 0.0578 - val_auc: 0.9994 - val_loss: 0.0355 - learning_rate: 0.0010\n",
+ "Epoch 7/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9965 - loss: 0.0525 - val_auc: 0.9998 - val_loss: 0.0242 - learning_rate: 0.0010\n",
+ "Epoch 8/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9968 - loss: 0.0496 - val_auc: 0.9998 - val_loss: 0.0236 - learning_rate: 0.0010\n",
+ "Epoch 9/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9968 - loss: 0.0493 - val_auc: 0.9999 - val_loss: 0.0230 - learning_rate: 0.0010\n",
+ "Epoch 10/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9972 - loss: 0.0464 - val_auc: 0.9999 - val_loss: 0.0208 - learning_rate: 0.0010\n",
+ "Epoch 11/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9975 - loss: 0.0435 - val_auc: 1.0000 - val_loss: 0.0197 - learning_rate: 0.0010\n",
+ "Epoch 12/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9978 - loss: 0.0417 - val_auc: 0.9998 - val_loss: 0.0192 - learning_rate: 0.0010\n",
+ "Epoch 13/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9980 - loss: 0.0398 - val_auc: 1.0000 - val_loss: 0.0179 - learning_rate: 0.0010\n",
+ "Epoch 14/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9981 - loss: 0.0381 - val_auc: 0.9999 - val_loss: 0.0172 - learning_rate: 0.0010\n",
+ "Epoch 15/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 10ms/step - auc: 0.9980 - loss: 0.0390 - val_auc: 0.9998 - val_loss: 0.0179 - learning_rate: 0.0010\n",
+ "Epoch 16/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9982 - loss: 0.0373 - val_auc: 1.0000 - val_loss: 0.0147 - learning_rate: 0.0010\n",
+ "Epoch 17/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9981 - loss: 0.0378 - val_auc: 1.0000 - val_loss: 0.0159 - learning_rate: 0.0010\n",
+ "Epoch 18/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9983 - loss: 0.0358 - val_auc: 0.9999 - val_loss: 0.0224 - learning_rate: 0.0010\n",
+ "Epoch 19/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9986 - loss: 0.0323 - val_auc: 1.0000 - val_loss: 0.0135 - learning_rate: 0.0010\n",
+ "Epoch 20/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9986 - loss: 0.0326 - val_auc: 0.9999 - val_loss: 0.0152 - learning_rate: 0.0010\n",
+ "Epoch 21/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9986 - loss: 0.0324 - val_auc: 1.0000 - val_loss: 0.0130 - learning_rate: 0.0010\n",
+ "Epoch 22/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - auc: 0.9983 - loss: 0.0365 - val_auc: 1.0000 - val_loss: 0.0144 - learning_rate: 0.0010\n",
+ "Epoch 23/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - auc: 0.9986 - loss: 0.0317 - val_auc: 1.0000 - val_loss: 0.0146 - learning_rate: 0.0010\n",
+ "Epoch 24/50\n",
+ "\u001b[1m122/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 6ms/step - auc: 0.9986 - loss: 0.0321\n",
+ "Epoch 24: ReduceLROnPlateau reducing learning rate to 0.0005000000237487257.\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9986 - loss: 0.0327 - val_auc: 0.9999 - val_loss: 0.0149 - learning_rate: 0.0010\n",
+ "Epoch 25/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9987 - loss: 0.0313 - val_auc: 1.0000 - val_loss: 0.0136 - learning_rate: 5.0000e-04\n",
+ "Epoch 26/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9986 - loss: 0.0323 - val_auc: 1.0000 - val_loss: 0.0121 - learning_rate: 5.0000e-04\n",
+ "Epoch 27/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 7ms/step - auc: 0.9986 - loss: 0.0320 - val_auc: 1.0000 - val_loss: 0.0126 - learning_rate: 5.0000e-04\n",
+ "Epoch 28/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9988 - loss: 0.0300 - val_auc: 1.0000 - val_loss: 0.0120 - learning_rate: 5.0000e-04\n",
+ "Epoch 29/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9991 - loss: 0.0262 - val_auc: 1.0000 - val_loss: 0.0119 - learning_rate: 5.0000e-04\n",
+ "Epoch 30/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9989 - loss: 0.0292 - val_auc: 1.0000 - val_loss: 0.0110 - learning_rate: 5.0000e-04\n",
+ "Epoch 31/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9986 - loss: 0.0316 - val_auc: 1.0000 - val_loss: 0.0114 - learning_rate: 5.0000e-04\n",
+ "Epoch 32/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9988 - loss: 0.0303 - val_auc: 1.0000 - val_loss: 0.0123 - learning_rate: 5.0000e-04\n",
+ "Epoch 33/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 7ms/step - auc: 0.9989 - loss: 0.0287\n",
+ "Epoch 33: ReduceLROnPlateau reducing learning rate to 0.0002500000118743628.\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9988 - loss: 0.0298 - val_auc: 1.0000 - val_loss: 0.0109 - learning_rate: 5.0000e-04\n",
+ "Epoch 34/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9989 - loss: 0.0276 - val_auc: 1.0000 - val_loss: 0.0107 - learning_rate: 2.5000e-04\n",
+ "Epoch 35/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9987 - loss: 0.0310 - val_auc: 1.0000 - val_loss: 0.0108 - learning_rate: 2.5000e-04\n",
+ "Epoch 36/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9988 - loss: 0.0294 - val_auc: 1.0000 - val_loss: 0.0116 - learning_rate: 2.5000e-04\n",
+ "Epoch 37/50\n",
+ "\u001b[1m124/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 8ms/step - auc: 0.9991 - loss: 0.0269\n",
+ "Epoch 37: ReduceLROnPlateau reducing learning rate to 0.0001250000059371814.\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - auc: 0.9990 - loss: 0.0270 - val_auc: 1.0000 - val_loss: 0.0108 - learning_rate: 2.5000e-04\n",
+ "Epoch 38/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 12ms/step - auc: 0.9988 - loss: 0.0284 - val_auc: 1.0000 - val_loss: 0.0113 - learning_rate: 1.2500e-04\n",
+ "Epoch 39/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9991 - loss: 0.0264 - val_auc: 1.0000 - val_loss: 0.0105 - learning_rate: 1.2500e-04\n",
+ "Epoch 40/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - auc: 0.9991 - loss: 0.0259 - val_auc: 1.0000 - val_loss: 0.0104 - learning_rate: 1.2500e-04\n",
+ "Epoch 41/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9991 - loss: 0.0255 - val_auc: 1.0000 - val_loss: 0.0108 - learning_rate: 1.2500e-04\n",
+ "Epoch 42/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - auc: 0.9990 - loss: 0.0273 - val_auc: 1.0000 - val_loss: 0.0106 - learning_rate: 1.2500e-04\n",
+ "Epoch 43/50\n",
+ "\u001b[1m124/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 8ms/step - auc: 0.9988 - loss: 0.0296\n",
+ "Epoch 43: ReduceLROnPlateau reducing learning rate to 6.25000029685907e-05.\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - auc: 0.9991 - loss: 0.0262 - val_auc: 1.0000 - val_loss: 0.0105 - learning_rate: 1.2500e-04\n",
+ "Epoch 44/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - auc: 0.9989 - loss: 0.0289 - val_auc: 1.0000 - val_loss: 0.0104 - learning_rate: 6.2500e-05\n",
+ "Epoch 45/50\n",
+ "\u001b[1m125/125\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 9ms/step - auc: 0.9991 - loss: 0.0263 - val_auc: 1.0000 - val_loss: 0.0107 - learning_rate: 6.2500e-05\n"
+ ]
+ }
+ ],
+ "source": [
+ "early_stop = EarlyStopping(\n",
+ " monitor=\"val_loss\",\n",
+ " patience=5,\n",
+ " restore_best_weights=True\n",
+ ")\n",
+ "\n",
+ "lr_reduce = ReduceLROnPlateau(\n",
+ " monitor=\"val_loss\",\n",
+ " factor=0.5,\n",
+ " patience=3,\n",
+ " min_lr=1e-6,\n",
+ " verbose=1\n",
+ ")\n",
+ "\n",
+ "history = model.fit(\n",
+ " X_train, y_train,\n",
+ " validation_data=(X_test, y_test),\n",
+ " epochs=50,\n",
+ " batch_size=256,\n",
+ " callbacks=[early_stop, lr_reduce],\n",
+ " verbose=1\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "6221ba8d-00a9-450b-b668-0a0c32a08238",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "plt.figure()\n",
+ "plt.plot(history.history[\"loss\"], label=\"Train Loss\")\n",
+ "plt.plot(history.history[\"val_loss\"], label=\"Val Loss\")\n",
+ "plt.legend()\n",
+ "plt.title(\"Loss Curve\")\n",
+ "plt.show()\n",
+ "\n",
+ "plt.figure()\n",
+ "plt.plot(history.history[\"auc\"], label=\"Train AUC\")\n",
+ "plt.plot(history.history[\"val_auc\"], label=\"Val AUC\")\n",
+ "plt.legend()\n",
+ "plt.title(\"AUC Curve\")\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "6413c96a-0dc8-4700-adf9-d08f82e16049",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Depression AUC: 1.0000\n",
+ "Anxiety AUC: 1.0000\n",
+ "Stress AUC: 1.0000\n"
+ ]
+ }
+ ],
+ "source": [
+ "from sklearn.metrics import roc_auc_score\n",
+ "\n",
+ "y_test_np = y_test.values\n",
+ "\n",
+ "y_pred_np = y_pred_prob\n",
+ "\n",
+ "labels = [\"Depression\", \"Anxiety\", \"Stress\"]\n",
+ "\n",
+ "for i, label in enumerate(labels):\n",
+ " auc = roc_auc_score(y_test_np[:, i], y_pred_np[:, i])\n",
+ " print(f\"{label} AUC: {auc:.4f}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "ddf87286-3c5a-4387-8863-790f68afa4fb",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjAAAAGzCAYAAAAxPS2EAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAMUFJREFUeJzt3QucTfX+//GPGWZcZ8ZtDLmWyp2MQlKRTBrdcEqEQlLDCUWU41YdjpSUW6WiU45Lh4oplwinKFJTLpluRD8MXRjE3Kz/4/N9PNb+773NlT1mvjOv5+Oxjb3Xd6+99net2eu9v5c1JRzHcQQAAMAiQQW9AQAAAHlFgAEAANYhwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArEOAAQqRCRMmSIkSJaQou//++6V8+fIBXafW2ZAhQ3IsN3/+fFN23759nsduvPFGc3PpMi2jZQsj3TY9TvLbhg0bzGvpT5fWU5MmTeRiKOz7AQWPAIMC5Z5Q3Fvp0qWlRo0aEhMTIy+99JKcOHGCPXSReO+HoKAgsx86d+7scwIrrj788MN8CQ1169b1qfOIiAhp2rSpDBo0SL744ouAvc7ChQvlxRdflMKoMG8bCrcS/C0kFHSAeeCBB2TSpElSr149SUtLk8OHD5uT5tq1a6V27drywQcfSLNmzYrFjkpPTzc3DXIXm55Eb775Zunbt6/on0jbu3evzJ49W44cOSLx8fHSpUuXgLXAvPvuu3Ly5EkJ5LbHxcXJzJkzsy2XkZFhjrHQ0FBPS5fb+uIGNX3vKSkpUqpUKQkODjaPaevOrFmzzLJAB5iKFSvKY489Zu5rYP/uu+9k6dKl5vdg+PDh8sILL/g858yZM1KyZElzy62uXbvKzp07fVqecnL27FlJTU2VkJAQE67cuvrtt9/MugIlq23LbD8A3nL/GwDkIz05tmrVynN/zJgxsn79evPhdvvtt5sP9TJlyly0faAfnnqiuJivqfJ6Ygq0K664Qu677z7P/bvuusuER/2GnFWA0XryPskVZnoizOlk6LYEXiyXXHKJT52rf/3rX9KrVy+ZPn26XH755fLwww97luX3tnnvz4II0gW1H2Cfwv+Jg2KrY8eO8o9//EN++eUXefvtt32W7dmzR3r06CGVKlUyH3IafrSlJrPuqU2bNslDDz0klStXlrCwMNPC8Oeff57zTVjD0urVq826NLi88sorZtmxY8dk2LBhUqtWLfPNvX79+uYEo99QvS1atEiio6OlQoUK5nW0K2DGjBme5frNf+LEieaEpNus23PdddeZlqbsxsBoi8zTTz8tl112mXl93dYnn3zSfDvN7D18+umncs0115jXuPTSS+Wtt946732g76FKlSqmNcZ7XIS+17Fjx5qTb9myZSU5Odks15YDrQOtP32enpj/7//+L9N1//zzz6arsFy5cqa7Slvh/Fs4pk2bJtdee62pK12nrltbb7LyzjvvyJVXXmneu5bVfZ/TGJicxl5oi5G2vvh3s+m2ap3fcccdmYaA8PBwc9ydD32v//73v83x/eyzz/rUi/8YGG210eNTt0WPj8jISNOS9tVXX3laTbQFTX+P3G3Xsjntz8zGwLi2b99u9otup7aczp07N1f17L/O7LYtqzEw+sWmffv25rjRLjetf/2C4839Pfrxxx/N/tNyuj+0tfevv/46r32CwocWGBRqffr0MSfrNWvWyIMPPmge27Vrl7Rr18582I4ePdp8kC1ZskTuvPNO+e9//2taDbxp879+gOmHWmJiosyZM8d8YLofpi5ddu+995qTjr6Wngj1w+6GG24wJ2F9XLu0Nm/ebFqIDh065Om71xCiz73ppptMuFH6ofrZZ5/Jo48+au7r60+ePFkGDhxoAoaeJL788ktzotETTla0/IIFC0xg064GHRuh69H1L1++3KesfmBruQEDBki/fv3kjTfeMB/gejJv3Lhxnutfg57eNLR500Cl39Iff/xxE6T0/2534NVXX222LykpyQQ4rYOvv/7a7APvrpxbbrlF2rRpI1OnTpVVq1bJ+PHjTVjTIOPS52sLXO/evU13hp5o//a3v8nKlSslNjbWZ5s2btwoixcvlr///e/mRK7dX/oaW7duvaCBp7rfDx48aPaxhgqXHjsa0HT7//jjDxM2XCtWrDD7179lJS90oLMey6+//rrs3r07y/03ePBgE+r0OG/UqJH8/vvvJsTq8dGyZUt56qmn5Pjx4/Lrr7+aFh133Tntz6zo8XDrrbfK3XffbY55/d3TFiJ9Tv/+/fP0HnOzbd4+/vhj0xKowVx/n06fPi0vv/yy+TzQ3yM3/Lh0GzVg6fGoy+fNm2cCnvs7CsvpGBigoLz55pv61dLZtm1b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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjAAAAGzCAYAAAAxPS2EAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAL71JREFUeJzt3QucjHX///EP1q7j7jqtQ47lLmeyCkVFsrHpQHcHkkJFy511R9yJ6MBNSI5JoUfKoTsVm1NEdyHaUiI6Ed3alcQi9uT6PT7f/+Oa/8yY3bXMtvvdfT0fjzE7c33nmmu+c5nrPd/DNcUcx3EEAADAIsXzewMAAAByiwADAACsQ4ABAADWIcAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAANcoAceeEDq1q1bJOvvhhtukCZNmgRtffv375dixYrJCy+8kGPZp59+2pT1pu+Dvh+ujRs3mjJ6XdC4r3XBggV5/lz6HPpc+pzedXXLLbfIX6Egvw+wHwEGhcKsWbPMB2Xr1q3Flu0N9gHMPTC6lxIlSkjt2rXljjvukB07dkhR9+abb8qLL74Y9PV613lISIhUrFhRoqOj5bHHHpPdu3cX6H2mKGwbCq9i/BYSCoNrr71WDh06ZA7i33//vdSvXz/PnzM9PV3Onj0rYWFhuX6stl5Urlw5qN9M9bXXq1dP7r33XunatatkZmbKt99+K7Nnz5bU1FTZunWrtGjRImgtMEeOHJFvvvkmqNs+adIkefzxx7Mtm5GRYS6lSpXyaVXQbXIPovq+pKWlSWhoqBQv/v++p2mrg26vd2tEMGhwuemmm+T+++8X/Wm548ePy1dffSXLli2TU6dOyb///W8ZOnSop7yW0fejZMmSJmTm5T6j+4Dup7qPuq1WWle6rpUrV+byleZ+2wK9D0CwhARtTUA+2bdvn2zevFneeecdeeSRR2TRokUyZsyYPH9ePQAVRC1btpT77rvPJ9zdeuutJsi8/PLLAR+jB9qyZcuKDbSVQy/Z0YOld8DJa5dffrlPnasJEyZIt27d5J///Kc0aNDAhEqlQSKvt819PzUg5SYkBdtf/T6gaCESw3oaWCpUqCCxsbFy5513mtvZjbGYO3euXHbZZeZb6VVXXSXbt2/3lDt8+LBUqVLFfJv3/qH2H374wRwQ7r777mzHwOg3Tu2maNy4sfngrlq1qglVf/zxh6eMPmbXrl2yadMmT9eDPt9PP/1k/p46deo5268BTZe99dZbua6fjh07eoKe97gIff5HH31UoqKipGbNmj7dAbr9Wj81atSQuLg4OXbsWMB1JyYmyjXXXCOlS5c2LShz5szxWa7fvkePHm26VCIiIkwdtm/fXj766KMst1dff506dcw6r7/++nNaeQKNgclp7IXWb0JCgvz888+eOtf34eTJk2abtLvH3y+//GIO/uPHj5cLUalSJVm8eLEJW88991y2Y2CSkpLkwQcfNO+D1nv16tXltttu87QWZbXP5PR+BhoD41q7dq1pkdP9tFGjRuYLwPnUs/86s9u2rMbAaOuU7hP6HmvLjYa///3vfz5l9P9XuXLlzP233367+Vv/b2oLnbYsAbTAwHoaWLp3726aqbX7RFsaNJRoOAk0DuLEiRMmVOgH68SJE81jNTxoi4p++Ovj//73v8v06dPlH//4hwkl+mFavnx5c3DPjq5XP+D1YKSP1dAwY8YM+fLLL+XTTz81z6EBZ/DgweYD+cknnzSP06Bz6aWXmtYSfT3x8fHnvEZ9fj2o5daPP/7oOaB604OdHhA0YOg3dvegNXbsWOnUqZMMHDhQ9u7d66lPd/tdGsq0VeGuu+4y9b506VLzGH0f+vbta8qkpKTIvHnzzPKHHnrI1P2rr74qMTExsm3btnO6tF5//XVTRkPTmTNnZNq0aSaA7dy509TRhdJ61q4dDSVuQNT614uOEVqyZIlMmTLFp7VCw6KG2F69el3w8+oYJA1hGti0LsLDwwOW69GjhwkBul9oINAgvW7dOjlw4IC5ndU+k9P7mRXtZtUwPmDAAOnTp4/Mnz/f7POrV6823WG5cT7b5s39/6H/PzUcJicnm/dZ9y/9fxIZGekpq0FF9xUd26ZfPj788EOZPHmy+QKi+xqKOB0DA9jq888/12YSZ926deb22bNnnZo1azqPPfaYT7l9+/aZcpUqVXKOHj3quf+9994z969YscKn/L333uuUKVPG+e6775xJkyaZMu+++65PmT59+jh16tTx3P7vf/9ryi1atMin3OrVq8+5v3Hjxs71119/zut5+eWXTdlvv/3Wc19aWppTuXJl83zZcV/j2LFjnd9++81JSkpyNm7c6Fx55ZXm/v/85z+m3Pz5883tdu3aORkZGZ7H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SpUqZX4Ve9u2bdlW4rJly6RBgwamfNOmTeWDDz7Iq/erSNf1K6+8Iu3bt5cKFSqYi/64Z07vDXJfz94WL15sforj9ttvpyqDvD+rY8eOSVxcnFSvXt1MR7388sv5/MiDetbziF1xxRVSunRpc/r7+Ph4OXPmDPt0Nj7++GPp1q2bOZ2/fga8++67kpONGzdKy5Ytzb5cv359WbBggeQpnUaN/2/x4sVOaGio89prrzm7du1yHnroIScyMtJJTk4OWE2ffvqpU6JECWfixInO7t27nVGjRjklS5Z0du7cSbUGua579uzpzJw50/nyyy+db7/91nnggQeciIgI55dffqGug1jPrn379jmXXHKJ0759e+e2226jjoO8P6empjqtWrVyunbt6nzyySemvjdu3Ojs2LGDug5iPS9atMgJCwsz11rHa9ascapXr+7Ex8dTz9n44IMPnCeffNJ555139FQrzvLly7Mr7vz0009OmTJlnKFDh5pj4fTp082xcfXq1U5eIcD4ufrqq524uDjP7czMTKdGjRrO+PHjA1bgXXfd5cTGxvrc17p1a+eRRx7Ji/erSNe1v4yMDKd8+fLOwoUL83Ari2Y9a91ec801zrx585w+ffoQYPKgnmfPnu1ceumlTlpaWu7e0CIut/WsZTt27Ohznx5kr7322jzf1sJCziPADB8+3GncuLHPfXfffbcTExOTZ9tFF5KXtLQ0SUxMNF0TruLFi5vbW7ZsCdiCpfd7l1cxMTFZlseF17W/P//8U9LT06VixYpUa5Dredy4cRIVFSX9+vWjbvOont9//33z227ahaRnGG/SpIk8//zzkpmZSZ0HsZ6vueYa8xi3m+mnn34y3XRdu3alnoMoP46FBfanBPLDkSNHzIeH/88V6O09e/YEfIz+zEGg8no/glvX/p544gnTP+v/nwYXV8+ffPKJvPrqq7Jjxw6qMg/rWQ+kGzZskF69epkD6g8//CCPPvqoCeV6inYEp5579uxpHteuXTvtcZCMjAwZMGCA/Otf/6KKgyirY2FKSoqcPn3ajD8KNlpgYKUJEyaYAabLly83A/kQHCdOnJDevXubAdOVK1emWvPQ2bNnTSvX3LlzJTo62vz+25NPPilz5syh3oNIB5Zqy9asWbPkiy++kHfeeUcSEhLkmWeeoZ4tRwuMF/3ALlGihCQnJ/tUkt6uVq1awArU+3NTHhde164XXnjBBJgPP/xQmjVrRpUGsZ5//PFH2b9/v5l94H2gVSEhIbJ371657LLLqPOLrGelM49KlixpHudq2LCh+SarXSWhoaHUcxDq+amnnjKhvH///ua2zhQ9deqUPPzwwyYwahcULl5Wx8Lw8PA8aX1RvHNe9ANDvwmtX7/e58Nbb2tfdSB6v3d5tW7duizL48LrWk2cONF8c9JfJm/VqhXVGeR61tMB7Ny503QfuZdbb71VOnToYP7WKai4+HpW1157rek2cgOi+u6770ywIbwEZ392x8r5hxQ3NPJbxsGTL8fCPBsebPEUPZ1yt2DBAjMV7OGHHzZT9JKSkszy3r17OyNGjPCZRh0SEuK88MILZmrvmDFjmEadR3U9YcIEM33y7bffdn799VfP5cSJE8HdCYp4PftjFlLe1POBAwfMLLpBgwY5e/fudVauXOlERUU5zz777EW+44VbbutZP5O1nt966y0z1Xft2rXOZZddZmaQImv6uaqnrNCLRoUpU6aYv3/++WezXOtY69p/GvWwYcPMsVBPecE06nyg89dr165tDpY6ZW/r1q2eZddff735QPe2dOlS5/LLLzfldRpZQkJCPmx14a/rOnXqmP9I/hf9gELw6tkfASZv9me1efNmc9oFPSDrlOrnnnvOTGFH8Oo5PT3defrpp01oKVWqlFOrVi3n0Ucfdf744w+qORsfffRRwM9bt271Wuva/zEtWrQw74vuz/Pnz3fyUjH9J+/adwAAAIKPMTAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAENv8H6mluCiePt0LAAAAAElFTkSuQmCC",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "for i, label in enumerate([\"Depression\", \"Anxiety\", \"Stress\"]):\n",
+ " plt.figure()\n",
+ " plt.hist(y_pred_prob[:, i], bins=50)\n",
+ " plt.title(f\"{label} Probability Distribution\")\n",
+ " plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "c83041bd-3b2a-4bb9-8a70-cacd6fcf435f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "depression_items = [3,5,10,13,16,17,21,24,26,31,34,37,38,42]\n",
+ "anxiety_items = [2,4,7,9,15,19,20,23,25,28,30,36,40,41]\n",
+ "stress_items = [1,6,8,11,12,14,18,22,27,29,32,33,35,39]\n",
+ "\n",
+ "df[\"Depression_Score\"] = df[[f\"Q{i}A\" for i in depression_items]].sum(axis=1)\n",
+ "df[\"Anxiety_Score\"] = df[[f\"Q{i}A\" for i in anxiety_items]].sum(axis=1)\n",
+ "df[\"Stress_Score\"] = df[[f\"Q{i}A\" for i in stress_items]].sum(axis=1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "id": "a9307ad9-27cb-411c-9f27-7cd81a928b36",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " Depression_Score \n",
+ " Anxiety_Score \n",
+ " Stress_Score \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " count \n",
+ " 39775.000000 \n",
+ " 39775.000000 \n",
+ " 39775.000000 \n",
+ " \n",
+ " \n",
+ " mean \n",
+ " 35.060088 \n",
+ " 30.054758 \n",
+ " 35.153891 \n",
+ " \n",
+ " \n",
+ " std \n",
+ " 12.321566 \n",
+ " 10.249169 \n",
+ " 10.523291 \n",
+ " \n",
+ " \n",
+ " min \n",
+ " 14.000000 \n",
+ " 14.000000 \n",
+ " 14.000000 \n",
+ " \n",
+ " \n",
+ " 25% \n",
+ " 25.000000 \n",
+ " 22.000000 \n",
+ " 27.000000 \n",
+ " \n",
+ " \n",
+ " 50% \n",
+ " 35.000000 \n",
+ " 29.000000 \n",
+ " 35.000000 \n",
+ " \n",
+ " \n",
+ " 75% \n",
+ " 46.000000 \n",
+ " 37.000000 \n",
+ " 43.000000 \n",
+ " \n",
+ " \n",
+ " max \n",
+ " 56.000000 \n",
+ " 56.000000 \n",
+ " 56.000000 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Depression_Score Anxiety_Score Stress_Score\n",
+ "count 39775.000000 39775.000000 39775.000000\n",
+ "mean 35.060088 30.054758 35.153891\n",
+ "std 12.321566 10.249169 10.523291\n",
+ "min 14.000000 14.000000 14.000000\n",
+ "25% 25.000000 22.000000 27.000000\n",
+ "50% 35.000000 29.000000 35.000000\n",
+ "75% 46.000000 37.000000 43.000000\n",
+ "max 56.000000 56.000000 56.000000"
+ ]
+ },
+ "execution_count": 25,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df[[\"Depression_Score\", \"Anxiety_Score\", \"Stress_Score\"]].describe()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "0a33092e-8d40-4d3b-b1d8-d40429e0e515",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(np.float64(0.25), np.float64(1.0))"
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "y_scores = df[[\"Depression_Score\", \"Anxiety_Score\", \"Stress_Score\"]].values\n",
+ "y_scores_norm = y_scores / 56.0\n",
+ "\n",
+ "y_scores_norm.min(), y_scores_norm.max()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "70b4f444-4fd4-496a-a62f-7a29c78570c1",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(39775, 42)"
+ ]
+ },
+ "execution_count": 28,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.preprocessing import StandardScaler\n",
+ "\n",
+ "X = df[[f\"Q{i}A\" for i in range(1,43)]].values\n",
+ "\n",
+ "scaler = StandardScaler()\n",
+ "X_scaled = scaler.fit_transform(X)\n",
+ "\n",
+ "X_scaled.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "2de610b7-7c25-4792-886a-7dab76fbe2cc",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "((31820, 42), (7955, 42))"
+ ]
+ },
+ "execution_count": 29,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.model_selection import train_test_split\n",
+ "\n",
+ "X_train_r, X_test_r, y_train_r, y_test_r = train_test_split(\n",
+ " X_scaled,\n",
+ " y_scores_norm,\n",
+ " test_size=0.2,\n",
+ " random_state=42\n",
+ ")\n",
+ "\n",
+ "X_train_r.shape, X_test_r.shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "524906b7-a84c-430c-9b1b-bd15928c1f6d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "E:\\conda\\envs\\tf\\lib\\site-packages\\keras\\src\\layers\\core\\dense.py:95: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n",
+ " super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "Model: \"sequential_1\" \n",
+ " \n"
+ ],
+ "text/plain": [
+ "\u001b[1mModel: \"sequential_1\"\u001b[0m\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n",
+ "┃ Layer (type) ┃ Output Shape ┃ Param # ┃\n",
+ "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n",
+ "│ dense_4 (Dense ) │ (None , 128 ) │ 5,504 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_3 │ (None , 128 ) │ 512 │\n",
+ "│ (BatchNormalization ) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dropout_2 (Dropout ) │ (None , 128 ) │ 0 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_5 (Dense ) │ (None , 64 ) │ 8,256 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_4 │ (None , 64 ) │ 256 │\n",
+ "│ (BatchNormalization ) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dropout_3 (Dropout ) │ (None , 64 ) │ 0 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_6 (Dense ) │ (None , 32 ) │ 2,080 │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_5 │ (None , 32 ) │ 128 │\n",
+ "│ (BatchNormalization ) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_7 (Dense ) │ (None , 3 ) │ 99 │\n",
+ "└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n",
+ " \n"
+ ],
+ "text/plain": [
+ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓\n",
+ "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
+ "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩\n",
+ "│ dense_4 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m5,504\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_3 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m512\u001b[0m │\n",
+ "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dropout_2 (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_5 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m8,256\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_4 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m256\u001b[0m │\n",
+ "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dropout_3 (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_6 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m2,080\u001b[0m │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ batch_normalization_5 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m128\u001b[0m │\n",
+ "│ (\u001b[38;5;33mBatchNormalization\u001b[0m) │ │ │\n",
+ "├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤\n",
+ "│ dense_7 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m3\u001b[0m) │ \u001b[38;5;34m99\u001b[0m │\n",
+ "└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Total params: 16,835 (65.76 KB)\n",
+ " \n"
+ ],
+ "text/plain": [
+ "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m16,835\u001b[0m (65.76 KB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Trainable params: 16,387 (64.01 KB)\n",
+ " \n"
+ ],
+ "text/plain": [
+ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m16,387\u001b[0m (64.01 KB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ " Non-trainable params: 448 (1.75 KB)\n",
+ " \n"
+ ],
+ "text/plain": [
+ "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m448\u001b[0m (1.75 KB)\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from tensorflow.keras.models import Sequential\n",
+ "from tensorflow.keras.layers import Dense, Dropout, BatchNormalization\n",
+ "from tensorflow.keras.optimizers import Adam\n",
+ "\n",
+ "model_r = Sequential()\n",
+ "\n",
+ "model_r.add(Dense(128, activation='relu', input_shape=(42,)))\n",
+ "model_r.add(BatchNormalization())\n",
+ "model_r.add(Dropout(0.3))\n",
+ "\n",
+ "model_r.add(Dense(64, activation='relu'))\n",
+ "model_r.add(BatchNormalization())\n",
+ "model_r.add(Dropout(0.3))\n",
+ "\n",
+ "model_r.add(Dense(32, activation='relu'))\n",
+ "model_r.add(BatchNormalization())\n",
+ "\n",
+ "model_r.add(Dense(3, activation='sigmoid'))\n",
+ "\n",
+ "model_r.compile(\n",
+ " optimizer=Adam(learning_rate=0.001),\n",
+ " loss='mse',\n",
+ " metrics=['mae']\n",
+ ")\n",
+ "\n",
+ "model_r.summary()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "ed2bb854-60bb-4e2a-af20-9861be98dfbf",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 1/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 9ms/step - loss: 0.0248 - mae: 0.1211 - val_loss: 0.0054 - val_mae: 0.0568 - learning_rate: 0.0010\n",
+ "Epoch 2/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0065 - mae: 0.0640 - val_loss: 0.0021 - val_mae: 0.0372 - learning_rate: 0.0010\n",
+ "Epoch 3/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0035 - mae: 0.0471 - val_loss: 0.0014 - val_mae: 0.0299 - learning_rate: 0.0010\n",
+ "Epoch 4/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0027 - mae: 0.0412 - val_loss: 0.0010 - val_mae: 0.0258 - learning_rate: 0.0010\n",
+ "Epoch 5/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 12ms/step - loss: 0.0023 - mae: 0.0376 - val_loss: 8.4653e-04 - val_mae: 0.0240 - learning_rate: 0.0010\n",
+ "Epoch 6/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0020 - mae: 0.0354 - val_loss: 4.8166e-04 - val_mae: 0.0175 - learning_rate: 0.0010\n",
+ "Epoch 7/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0019 - mae: 0.0341 - val_loss: 5.0163e-04 - val_mae: 0.0183 - learning_rate: 0.0010\n",
+ "Epoch 8/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0017 - mae: 0.0324 - val_loss: 5.0481e-04 - val_mae: 0.0184 - learning_rate: 0.0010\n",
+ "Epoch 9/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0016 - mae: 0.0314 - val_loss: 3.5799e-04 - val_mae: 0.0153 - learning_rate: 0.0010\n",
+ "Epoch 10/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 13ms/step - loss: 0.0016 - mae: 0.0312 - val_loss: 2.8060e-04 - val_mae: 0.0133 - learning_rate: 0.0010\n",
+ "Epoch 11/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0015 - mae: 0.0302 - val_loss: 2.7185e-04 - val_mae: 0.0132 - learning_rate: 0.0010\n",
+ "Epoch 12/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0014 - mae: 0.0298 - val_loss: 2.3608e-04 - val_mae: 0.0121 - learning_rate: 0.0010\n",
+ "Epoch 13/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0014 - mae: 0.0293 - val_loss: 2.2121e-04 - val_mae: 0.0117 - learning_rate: 0.0010\n",
+ "Epoch 14/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0013 - mae: 0.0287 - val_loss: 2.0351e-04 - val_mae: 0.0111 - learning_rate: 0.0010\n",
+ "Epoch 15/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0013 - mae: 0.0287 - val_loss: 2.0708e-04 - val_mae: 0.0114 - learning_rate: 0.0010\n",
+ "Epoch 16/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0012 - mae: 0.0277 - val_loss: 2.2262e-04 - val_mae: 0.0120 - learning_rate: 0.0010\n",
+ "Epoch 17/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0012 - mae: 0.0277 - val_loss: 2.0442e-04 - val_mae: 0.0114 - learning_rate: 0.0010\n",
+ "Epoch 18/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0012 - mae: 0.0273 - val_loss: 1.5911e-04 - val_mae: 0.0096 - learning_rate: 5.0000e-04\n",
+ "Epoch 19/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0012 - mae: 0.0277 - val_loss: 1.5663e-04 - val_mae: 0.0095 - learning_rate: 5.0000e-04\n",
+ "Epoch 20/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0012 - mae: 0.0270 - val_loss: 1.6065e-04 - val_mae: 0.0097 - learning_rate: 5.0000e-04\n",
+ "Epoch 21/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0012 - mae: 0.0271 - val_loss: 1.5141e-04 - val_mae: 0.0093 - learning_rate: 5.0000e-04\n",
+ "Epoch 22/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0012 - mae: 0.0270 - val_loss: 1.4556e-04 - val_mae: 0.0090 - learning_rate: 5.0000e-04\n",
+ "Epoch 23/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0012 - mae: 0.0270 - val_loss: 1.4206e-04 - val_mae: 0.0089 - learning_rate: 2.5000e-04\n",
+ "Epoch 24/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0266 - val_loss: 1.3936e-04 - val_mae: 0.0088 - learning_rate: 2.5000e-04\n",
+ "Epoch 25/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0012 - mae: 0.0270 - val_loss: 1.4127e-04 - val_mae: 0.0089 - learning_rate: 2.5000e-04\n",
+ "Epoch 26/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 13ms/step - loss: 0.0011 - mae: 0.0265 - val_loss: 1.4169e-04 - val_mae: 0.0090 - learning_rate: 2.5000e-04\n",
+ "Epoch 27/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0012 - mae: 0.0266 - val_loss: 1.3596e-04 - val_mae: 0.0086 - learning_rate: 2.5000e-04\n",
+ "Epoch 28/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0261 - val_loss: 1.3965e-04 - val_mae: 0.0089 - learning_rate: 2.5000e-04\n",
+ "Epoch 29/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0011 - mae: 0.0263 - val_loss: 1.4111e-04 - val_mae: 0.0090 - learning_rate: 2.5000e-04\n",
+ "Epoch 30/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0011 - mae: 0.0263 - val_loss: 1.3619e-04 - val_mae: 0.0087 - learning_rate: 2.5000e-04\n",
+ "Epoch 31/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0012 - mae: 0.0267 - val_loss: 1.3164e-04 - val_mae: 0.0085 - learning_rate: 2.5000e-04\n",
+ "Epoch 32/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0262 - val_loss: 1.3284e-04 - val_mae: 0.0086 - learning_rate: 2.5000e-04\n",
+ "Epoch 33/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0011 - mae: 0.0266 - val_loss: 1.3145e-04 - val_mae: 0.0085 - learning_rate: 1.2500e-04\n",
+ "Epoch 34/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2864e-04 - val_mae: 0.0084 - learning_rate: 1.2500e-04\n",
+ "Epoch 35/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.2700e-04 - val_mae: 0.0083 - learning_rate: 1.2500e-04\n",
+ "Epoch 36/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0261 - val_loss: 1.3337e-04 - val_mae: 0.0087 - learning_rate: 1.2500e-04\n",
+ "Epoch 37/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0262 - val_loss: 1.3023e-04 - val_mae: 0.0085 - learning_rate: 1.2500e-04\n",
+ "Epoch 38/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - loss: 0.0011 - mae: 0.0260 - val_loss: 1.2551e-04 - val_mae: 0.0082 - learning_rate: 6.2500e-05\n",
+ "Epoch 39/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.2789e-04 - val_mae: 0.0084 - learning_rate: 6.2500e-05\n",
+ "Epoch 40/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2879e-04 - val_mae: 0.0084 - learning_rate: 6.2500e-05\n",
+ "Epoch 41/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0260 - val_loss: 1.2772e-04 - val_mae: 0.0084 - learning_rate: 6.2500e-05\n",
+ "Epoch 42/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0010 - mae: 0.0253 - val_loss: 1.2655e-04 - val_mae: 0.0084 - learning_rate: 6.2500e-05\n",
+ "Epoch 43/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0256 - val_loss: 1.2648e-04 - val_mae: 0.0083 - learning_rate: 3.1250e-05\n",
+ "Epoch 44/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0261 - val_loss: 1.2418e-04 - val_mae: 0.0082 - learning_rate: 3.1250e-05\n",
+ "Epoch 45/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2480e-04 - val_mae: 0.0083 - learning_rate: 3.1250e-05\n",
+ "Epoch 46/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.2516e-04 - val_mae: 0.0083 - learning_rate: 3.1250e-05\n",
+ "Epoch 47/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.2427e-04 - val_mae: 0.0082 - learning_rate: 3.1250e-05\n",
+ "Epoch 48/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.2405e-04 - val_mae: 0.0082 - learning_rate: 1.5625e-05\n",
+ "Epoch 49/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.2471e-04 - val_mae: 0.0082 - learning_rate: 1.5625e-05\n",
+ "Epoch 50/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0261 - val_loss: 1.2506e-04 - val_mae: 0.0082 - learning_rate: 1.5625e-05\n",
+ "Epoch 51/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0260 - val_loss: 1.2389e-04 - val_mae: 0.0082 - learning_rate: 1.5625e-05\n",
+ "Epoch 52/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 13ms/step - loss: 0.0010 - mae: 0.0252 - val_loss: 1.2466e-04 - val_mae: 0.0082 - learning_rate: 1.5625e-05\n",
+ "Epoch 53/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2393e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 54/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0259 - val_loss: 1.2311e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 55/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0010 - mae: 0.0252 - val_loss: 1.2335e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 56/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0010 - mae: 0.0252 - val_loss: 1.2240e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 57/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0256 - val_loss: 1.2327e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 58/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0256 - val_loss: 1.2301e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 59/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.2407e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 60/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0261 - val_loss: 1.2364e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 61/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2308e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 62/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0010 - mae: 0.0249 - val_loss: 1.2321e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 63/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.2371e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 64/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2339e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 65/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0256 - val_loss: 1.2216e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 66/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.2134e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 67/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0253 - val_loss: 1.2135e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 68/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2167e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 69/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0255 - val_loss: 1.2168e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 70/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0256 - val_loss: 1.2136e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 71/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0255 - val_loss: 1.2122e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 72/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2051e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 73/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0256 - val_loss: 1.2208e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 74/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.2177e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 75/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0256 - val_loss: 1.2078e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 76/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2128e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 77/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0010 - mae: 0.0252 - val_loss: 1.2247e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 78/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0262 - val_loss: 1.2278e-04 - val_mae: 0.0082 - learning_rate: 1.0000e-05\n",
+ "Epoch 79/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.2170e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 80/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0010 - mae: 0.0251 - val_loss: 1.2076e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 81/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.2088e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 82/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.1996e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 83/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.1975e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 84/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 12ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.2014e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 85/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0010 - mae: 0.0250 - val_loss: 1.1987e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 86/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.1936e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 87/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0257 - val_loss: 1.1970e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 88/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0010 - mae: 0.0250 - val_loss: 1.2030e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 89/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0253 - val_loss: 1.1924e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 90/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.1891e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 91/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.1963e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 92/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0255 - val_loss: 1.2000e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 93/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0010 - mae: 0.0251 - val_loss: 1.2050e-04 - val_mae: 0.0081 - learning_rate: 1.0000e-05\n",
+ "Epoch 94/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - loss: 0.0011 - mae: 0.0258 - val_loss: 1.1856e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 95/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0010 - mae: 0.0252 - val_loss: 1.1981e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 96/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0010 - mae: 0.0252 - val_loss: 1.1858e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 97/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0010 - mae: 0.0253 - val_loss: 1.1844e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 98/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 9ms/step - loss: 0.0011 - mae: 0.0254 - val_loss: 1.1902e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 99/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0011 - mae: 0.0253 - val_loss: 1.1789e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n",
+ "Epoch 100/100\n",
+ "\u001b[1m100/100\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 8ms/step - loss: 0.0010 - mae: 0.0249 - val_loss: 1.1836e-04 - val_mae: 0.0080 - learning_rate: 1.0000e-05\n"
+ ]
+ }
+ ],
+ "source": [
+ "from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\n",
+ "\n",
+ "early_stop = EarlyStopping(\n",
+ " monitor='val_loss',\n",
+ " patience=10,\n",
+ " restore_best_weights=True\n",
+ ")\n",
+ "\n",
+ "reduce_lr = ReduceLROnPlateau(\n",
+ " monitor='val_loss',\n",
+ " factor=0.5,\n",
+ " patience=5,\n",
+ " min_lr=0.00001\n",
+ ")\n",
+ "\n",
+ "history_r = model_r.fit(\n",
+ " X_train_r,\n",
+ " y_train_r,\n",
+ " validation_split=0.2,\n",
+ " epochs=100,\n",
+ " batch_size=256,\n",
+ " callbacks=[early_stop, reduce_lr],\n",
+ " verbose=1\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "id": "58a861f1-8ce5-45cb-a025-e0710c6a3823",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\u001b[1m249/249\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 3ms/step\n",
+ "Depression MAE: 0.49 points\n",
+ "Anxiety MAE: 0.4 points\n",
+ "Stress MAE: 0.44 points\n"
+ ]
+ }
+ ],
+ "source": [
+ "from sklearn.metrics import mean_absolute_error\n",
+ "\n",
+ "y_pred_r = model_r.predict(X_test_r)\n",
+ "\n",
+ "labels = [\"Depression\", \"Anxiety\", \"Stress\"]\n",
+ "\n",
+ "for i, label in enumerate(labels):\n",
+ " mae = mean_absolute_error(y_test_r[:, i], y_pred_r[:, i])\n",
+ " print(f\"{label} MAE:\", round(mae*56, 2), \"points\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "b643af16-9361-4367-b505-471d6996085c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " Feature \n",
+ " Importance \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 37 \n",
+ " Q13I \n",
+ " 0.103261 \n",
+ " \n",
+ " \n",
+ " 33 \n",
+ " Q12A \n",
+ " 0.102243 \n",
+ " \n",
+ " \n",
+ " 20 \n",
+ " Q7E \n",
+ " 0.098683 \n",
+ " \n",
+ " \n",
+ " 29 \n",
+ " Q10E \n",
+ " 0.098430 \n",
+ " \n",
+ " \n",
+ " 8 \n",
+ " Q3E \n",
+ " 0.097269 \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " Q1A \n",
+ " 0.095973 \n",
+ " \n",
+ " \n",
+ " 36 \n",
+ " Q13A \n",
+ " 0.095652 \n",
+ " \n",
+ " \n",
+ " 16 \n",
+ " Q6I \n",
+ " 0.095452 \n",
+ " \n",
+ " \n",
+ " 9 \n",
+ " Q4A \n",
+ " 0.095192 \n",
+ " \n",
+ " \n",
+ " 19 \n",
+ " Q7I \n",
+ " 0.095064 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Feature Importance\n",
+ "37 Q13I 0.103261\n",
+ "33 Q12A 0.102243\n",
+ "20 Q7E 0.098683\n",
+ "29 Q10E 0.098430\n",
+ "8 Q3E 0.097269\n",
+ "0 Q1A 0.095973\n",
+ "36 Q13A 0.095652\n",
+ "16 Q6I 0.095452\n",
+ "9 Q4A 0.095192\n",
+ "19 Q7I 0.095064"
+ ]
+ },
+ "execution_count": 34,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "\n",
+ "weights = model_r.layers[0].get_weights()[0]\n",
+ "\n",
+ "importance = np.mean(np.abs(weights), axis=1)\n",
+ "\n",
+ "feature_names = df.columns[:42]\n",
+ "\n",
+ "feature_importance = pd.DataFrame({\n",
+ " \"Feature\": feature_names,\n",
+ " \"Importance\": importance\n",
+ "}).sort_values(by=\"Importance\", ascending=False)\n",
+ "\n",
+ "feature_importance.head(10)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "31a404e8-7476-4955-afc7-cb82deef2cf4",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkcAAAHHCAYAAAC1G/yyAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAToRJREFUeJzt3Q1clfX9//EPqCCKSiKGLPCGmyQtYxqJc1ZLRLNlZkOdWYLrTiqyfm5jbhDNDV1lNRm6Nm9qY4o2Nfu1xJuVOszFTDMNDSOUTMwQtcyw9Pwfn+9+5/yvgyA3AecceD0fj2t6rus617muC+Z59/1+vt/Ly2az2QQAAACG93//AAAAAOEIAACgGlqOAAAALAhHAAAAFoQjAAAAC8IRAACABeEIAADAgnAEAABgQTgCAACwIBwBAABYEI6AZuTl5VWv5c0332z2n8PChQvlRz/6kYSFhZnPnDZtWo37LVu2rNbzLC8vr/NzbrzxRhk4cKB4qk8++USeeOIJ2b17d7N/1pdffmk+q74/f92vtp/NpEmTmuUc33//fXOOpaWlzXJ8wB21d/UJAK3ZX/7yF6fXL730kmzcuPGi9dHR0c1+LvPmzZPPP/9cYmNj5ejRo3Xu/+STT0rfvn2d1gUEBEhrp+EoMzNT+vTpI9dee22zhyP9LHuorK9HHnlErrvuOqd1er7NFY70HPX8muszAHdDOAKa0V133eX0eseOHSYcVV/fErZs2eJoNfL3969z/zFjxsiQIUOkrfjmm2/kwoUL4gm+//3vy5133ime7MyZM9K5c2dXnwZQI7rVADf4knj88cclNDRUfH195corr5Snn35abDab034aah566CHJzc01+3Ts2FEGDx4sW7durdfn9O7d2xyjIbSl6fz58/Jt2c991apVctVVV4mfn5/ExcXJe++9Z7b/8Y9/lIiICHNN2kJRvQvH3lW3c+dOGTZsmHm/tmotWrToos/69NNPZfr06XL55Zeb4w0aNEhefPFFp330+HpOep+fe+45CQ8PN/c+JyfH0SKTlJTk6LLSrka1bds2R9ek7q8/s5kzZ8rZs2edjq9dlhpAjxw5Irfffrv5e1BQkPzP//yP437qOeg6pS0z9s/SLqxv69///reMHj1aunXrJp06dZIbbrhBCgoKnPY5dOiQzJgxw/wu6f0MDAw012a993rduk7ddNNNF3UD13a+2sJk7ba1d9VqQNfP7Nmzp1xxxRWO7a+//roJfBqWunTpImPHjpV9+/Y5HVO7dPVnou/Te9+rVy8ZN24c3X1oFrQcAS6kAei2226TN954w3yhazdOfn6+zJo1y3yxPvvss07765dLXl6e6Vaxf5nrl+Dbb7/d5HU++mX4xRdfiI+PjyQkJMgzzzwjkZGRjT6eBot169ZJSkqKeZ2VlSW33nqr/PSnPzXXoV+alZWV8rvf/U6Sk5Pln//8p9P7ddstt9wiiYmJMnnyZFm5cqU8+OCD5vx0f6UhRYPUwYMHTRjTAKWBTL+oT548KampqU7HXLp0qXz11Vdy3333mfs5fvx4EwjT09PNOv3CVhrIlB5Lu8L0czVM6H1fsGCBfPzxx2ablYYgvW/XX3+9CWGbNm0y91CDmL5fg5HWgenf9XPvuOMO875rrrmmznup5/jZZ585revevbt4e3ub+6atfhqcMzIyzDq9zh/84AfmZ6DdqqqwsFC2b99uapU0cGgo0vPR+6ddaRqqRowYYX7Xfv/738svfvELR/dvY7uB9Wes1633V/+jQGkX8z333GPulXb96v3V8xg+fLjs2rXL0ZU3YcIEE5gefvhhs05DsLbCHj58mO4+ND0bgBaTkpKizUGO12vXrjWv58yZ47TfnXfeafPy8rIdPHjQsU730+U///mPY92hQ4dsHTt2tI0fP75B59G5c2fbPffcU+O2vLw827Rp02wvvviibc2aNbZf/vKXtk6dOtl69OhhO3z4cJ3HvuGGG2wDBgxwWqfn7evra/voo48c6/74xz+a9cHBwbbTp0871qelpZn11n31mLrumWeecayrqqqyXXvttbaePXvazp07Z9Y999xzZr+//vWvjv10W1xcnM3f39/xOXps3a9r1662Tz/91OlcCwsLzbalS5dedG1ffvnlReuysrLMz0p/FnZ6b/UYTz75pNO+MTExtsGDBzteHz9+3OyXkZFhq4833njD8XtQfdFrunDhgi0yMtKWkJBg/m497759+9ri4+MveS1vvfWWOdZLL73kWLdq1SqzTj+7utrOvXfv3k6/X3ovdd/hw4fbvvnmG8f6zz//3BYQEGC79957nd5fXl5u69atm2N9ZWWlef9TTz1Vr/sEfFt0qwEu9I9//EPatWtn/uvcSrvZ9LtHuxustCtKWwTstHtHuxa0takpur+UtsxoS8Pdd99tuoR+/etfm+NXVFTIb37zm0Yf9+abb3b6L3xtUbG3CGhXSvX1JSUlTu9v37693H///Y7X2mKkr7UFQbvb7PczODjYtCzZdejQwdxfbQXTljcr/Wx711Z9aPeTnbZ8aOuNtirpz0pbOap74IEHnF5rS1T162oMbXnRVhProtetI+yKi4vlxz/+sfl56fnpoueq91+7YO11VdZr+frrr83+2rWpRffvvPOONId7773X/L7b6Xlri57+vOznqovuo78H2qJqP1f9eWt3nrYgAs2NbjXAhbTuIyQkxCkcWLstdLtVTd1aUVFRpivi+PHj5guyOWgXh35ZaddQY2mQs9J6GKV1OzWtr/4lqPepegGvXrvSLqGhQ4ea+6X3SLuS6nM/q4/Gq4t24Wgw0e7B6ud36tQpp9da71Q9eF122WVN8uV+9dVXy8iRIy9ar8FIaTdVbfQ89Ty0C1K7NjUIaxeutcat+rU0ler3236+2uVXk65du5o/tctTu9z0Pxq0lkx/1tolqwG+uX7n0bYRjgDUi4aYAwcONPpuWVsM6rO+ekF6c7C2ntRFW+bi4+PlxIkT8rOf/Uz69+9vwpoGC61pqj7Srbbrak72c3jqqadqnYbAPlJRa3c0GD366KOmRVJDqX2+pG87aq+2Vszq99v+OVp3VFPI0dZCOz3PH/7wh7J27VrTkvmrX/3KhDutsYqJiflW5wtURzgCXEhHkGlrjBbYWluP9u/f79he039pW33wwQemeLYh3UONod1Bzf0Zdc0/VH34t167snfX6f3as2eP+dK1th7Vdj9rUtuIPh1Zp5+nI9+0xcLaNdRYDR09WBct9ra3uNTUsmT18ssvmxYmLRK30+J07eaq7zlqC1T1/c+dO1evebSs56uj1+o6X/v+2nqki/5/QQOgnv9f//rXen0eUF/UHAEupKOv9L+ys7OzndbrKDX9UtJRR1ZvvfWWUz1IWVmZvPLKKzJq1Kgma6nQ7rnqtJZH63p0ZJwr5yHSIf/WL2F9rYHNXoel91OHfOuIPuv7dESZtpjokPa62MNX9S99+/21tmjp359//vlGX5OG2po+q7H0PmiA0NFxWmN1qZ+tXk/11jm9T9VbfWq7H0o/q/pUEi+88EK96990hJoGud/+9rem7qm289VuYw1u1T9b/4OiqqqqXp8FNAQtR4ALaTeBDpmfPXu2qZvROXk2bNhgAo92I9j/y9pOh+vrF4p1KL+yz7J8Ka+++qq8++675u/6RaQtLHPmzDGvdToB+xByLTDWbgqdAFK7WjSMLVmyxHSr6XBuV9GaI6070fuktUYagLQAWb+Mteha6fB7DUzazaVhTluUtIVE5/jR+Yyq13bVRO+5FiXrHEq6v4YDrbfSbjTdpnMVaVeafqn//e9//1Y1RNrNpPM+6bXoNelwfP0ZN3ZaBm0t+/Of/2xC9YABA8y8QN/5znfM+Wpxs56z/h4ordnR7iz9Ges5aPDWVkydosBKW2c0SOm911ok/b3TGiFt7fnJT35iis61sF27HPX3S7u8evToUa/z1fPRYftTp06V7373u6ZLT8Ou1na99tpr8r3vfc/8h4O22GlBuQ4W0HPV7rY1a9bIsWPHmu2xKWjjvvV4NwCNHspvH848c+ZMW0hIiK1Dhw5mKLYOWbYOxVb6Pn2/DlPXfXRovA4Nr2mIdU3sw8trWqzD1mfPnm2GyOtQaj2fsLAw24MPPmiGV9dHbUP59dyt7MPpqw/Ptg9X1yHk1Y+p0xjosHydvkCHi2dnZ1/0+ceOHbMlJSWZqQd8fHxsV1999UXD8mv7bLtXXnnFdtVVV9nat2/vdH/ef/9928iRI820AHp8HWr+7rvvXnQP9V7rdAnV6bD36j//7du3m+H9eq51Deuv6d7UZNeuXbY77rjDFhgYaH5P9F4lJibaNm/e7NhHh8fb75Nejw7/379//0XD8NWf/vQnW79+/Wzt2rVzGtZ//vx5289+9jNzDJ3uQY+h00/UNpRfp0mo7br0vfo7pz/b8PBwM52EfdqKzz77zPz+9O/f39xX3e/666+3rVy58pL3AWgsL/0fVwc0AHXTbjadQLF6F1xboBMT6hDvvXv3uvpUALQB1BwBAABYEI4AAAAsCEcAAAAW1BwBAABY0HIEAABgQTgCAACwYBLIBtLHEuhjDHRyuKae+h8AADQPnblIH9WkE8pWfzh1dYSjBtJgVP0p4gAAwDPoY5euuOKKS+5DOGog++MH9Obq1PcAAMD9nT592jRu1OcxQoSjBrJ3pWkwIhwBAOBZ6lMSQ0E2AACABeEIAADAgnAEAABgQTgCAACwIBwBAABYEI4AAAAsCEcAAAAWhCMAAAALwhEAAIAF4QgAAMCCcAQAAGBBOAIAALAgHAEAAFgQjgAAACzaW1+g/gZm5Iu3byduGQDALZXOHevqU/BYtBwBAABYEI4AAAAsCEcAAAAWhCMAAIDWEo7KysokOTlZQkJCxMfHR3r37i2pqalSUVFR4/4PPPCAeHl5yXPPPee0XtetXbu2hc4aAAC4M48NRyUlJTJkyBApLi6W5cuXy8GDB2XRokWyefNmiYuLkxMnTjjtv2bNGtmxY4cJUgAAAK0uHKWkpJjWog0bNsgNN9wgYWFhMmbMGNm0aZMcOXJEZs+e7dhXXz/88MOSm5srHTp0cOl5AwAA9+aR4UhbhfLz82XGjBni5+fntC04OFimTJkieXl5YrPZ5MKFCzJ16lSZNWuWDBgwoMGfVVVVJadPn3ZaAABA6+WR4Ui70jT4REdH17hd11dWVsrx48dl3rx50r59e3nkkUca9VlZWVnSrVs3xxIaGvotzx4AALgzjwxHdhqQ6irYfv7552XZsmWm6Lox0tLS5NSpU45FjwkAAFovjwxHERERJuwUFRXVuF3XBwUFybZt2+TTTz819UjaeqTLoUOH5PHHH5c+ffrU67N8fX2la9euTgsAAGi9PDIcBQYGSnx8vOTk5MjZs2edtpWXl5vC62nTpplaoz179sju3bsdi45W0/ojrVkCAABoNQ+ezc7OlmHDhklCQoLMmTNH+vbtK/v27TPBJyoqStLT08Xf398EKSsdraZF21deeaXLzh0AALgvj2w5UpGRkVJYWCj9+vWTxMREMwGkDuXXYFRQUGCCEQAAQJtpOVJaN6TF1nYZGRkyf/5805U2dOjQGt9TWlra4MJuAADQdnh0OKouMzPTBCadCTs2Nla8vT22YQwAALhIqwpHKikpydWnAAAAPFirC0ctZW9mAsP6AQBoheh3AgAAsCAcAQAAWBCOAAAALAhHAAAAFhRkN9LAjHzx9u3U2LcDANBiSueO5W43AC1HAAAAFoQjAAAAC8IRAACABeEIAADAncJRWVmZJCcnS0hIiPj4+Ejv3r0lNTVVKioqHPusXr1aRo0aJYGBgeLl5SW7d+++6DhfffWVpKSkmH38/f1lwoQJcuzYsRo/MyEhQdq1ayeFhYXNem0AAMDzuDQclZSUyJAhQ6S4uFiWL18uBw8elEWLFsnmzZslLi5OTpw4YfY7c+aMDB8+XObNm1frsWbOnCmvvvqqrFq1SrZs2SKffPKJ3HHHHRftd/jwYdm+fbs89NBDsmTJkma9PgAA4Hm8bDabzVUfPmbMGNm7d6988MEH4ufn51hfXl4u4eHhcvfdd8vChQsd60tLS6Vv376ya9cuufbaax3rT506JUFBQfK3v/1N7rzzTrNu//79Eh0dLW+99ZYMHTrUsW9mZqbZlpGRYdYfPXrU6bPrcvr0aenWrZuEPrqSofwAAI/AUH5xfH9rZujatat7thxpq1B+fr7MmDHjonASHBwsU6ZMkby8PKlPdtu5c6d8/fXXMnLkSMe6/v37S1hYmAlHdnqspUuXyl133WW2R0REyMsvv3zJY1dVVZkbal0AAEDr5bJwpF1pGla0dacmur6yslKOHz9e57G0pUnrlQICApzWX3755Wab3aZNm+TLL780NUdKQ9LixYsveeysrCyTNO1LaGhoPa8QAAB4IpcXZNfVMqShp6lojdHEiROlffv/Tgw+efJkKSgokA8//LDW96SlpZkmOPuiBeQAAKD1clk40i4tHXlWVFRU43Zdr3VE1VuDaqLdcOfOnZOTJ086rdfRarrN3o23Zs0aycnJMeFIl+985zvyzTffXLIw29fX1/RNWhcAANB6uSwc6ZD7+Ph4E1bOnj3rtE27wnJzc2XatGn1OtbgwYOlQ4cOZpSb3YEDB8zINB31pvR4V1xxhbz77rtmKgD78swzz8iyZcvk/PnzTXyFAADAE7n0wbPZ2dkybNgwUwM0Z84cMxJt3759MmvWLImKipL09HRHq48GHR2ebw8+SluFdNFaoOnTp8tjjz0m3bt3N607Dz/8sAlG9pFqWlukI9kGDhzodA5aQ6RdZ+vXr5exY3kwHwAAbZ1La44iIyPNRIz9+vWTxMREMwGkDu/XYKS1QDqZo1q3bp3ExMQ4wsukSZPMa50Tye7ZZ5+VW2+91Uz+OGLECBOadPJI+2g2bTHSbdVpsLr55pvrLMwGAABtg0vnOaqJzj80f/582bhxo9P8RO6CeY4AAJ6GeY6kQfMcubRbrSY6SWOfPn1kx44dEhsbK97eLh9QBwAA2hC3C0cqKSnJ1acAAADaKLcMR55gb2YCw/oBAGiF6LMCAACwIBwBAABYEI4AAAAsqDlqpIEZ+eLt26mxbwcAoMUxpL9+aDkCAACwIBwBAABYEI4AAAAsCEcAAAAWhCMAAABPDEdlZWWSnJwsISEh4uPjI71795bU1FSpqKiocf8HHnhAvLy85LnnnnNar+tqWlasWNFCVwIAANyZRwzlLykpkbi4OImKipLly5dL3759Zd++fTJr1ix5/fXXzUNqu3fv7th/zZo1Zp0GqZosXbpURo8e7bQuICCg2a8DAAC4P48IRykpKaa1aMOGDeLn52fWhYWFSUxMjISHh8vs2bNl4cKFZv2RI0fk4Ycflvz8fBk7dmyNx9MgFBwcXK/PrqqqMovd6dOnm+SaAACAe3L7brUTJ06YoDNjxgxHMLLTgDNlyhTJy8sTm80mFy5ckKlTp5oWpQEDBjTJ52dlZUm3bt0cS2hoaJMcFwAAuCe3D0fFxcUm+ERHR9e4XddXVlbK8ePHZd68edK+fXt55JFHLnnMyZMni7+/v9Ny+PDhGvdNS0uTU6dOORatfQIAAK2XR3SrKQ1Il6Kh5fnnn5d33nnHFFhfyrPPPisjR450WldbfZKvr69ZAABA2+D2LUcREREm7BQVFdW4XdcHBQXJtm3b5NNPPzW1SNp6pMuhQ4fk8ccflz59+lzUHafHtS66PwAAgNuHo8DAQImPj5ecnBw5e/as07by8nLJzc2VadOmmVqjPXv2yO7dux2LtgZp/ZHWLAEAANSHRzSXZGdny7BhwyQhIUHmzJnjNJRfh/enp6ebuiENUlYdOnQwrURXXnml0/qTJ0+aYGXVpUsX6dy5c4tcDwAAcF9u33KkIiMjpbCwUPr16yeJiYlmAsgxY8aYYFRQUGCCUUMkJSVJr169nJYFCxY02/kDAADP4REtR0rrhpYtW+Z4nZGRIfPnzzddaUOHDq3xPaWlpQ0u7AYAAG2bx4Sj6jIzM01g0pmwY2NjxdvbIxrBAACAm/Oy0ZTSIDpDtk4GqXMede3atbl+LgAAwEXf3zS3AAAAWBCOAAAALAhHAAAAFoQjAACA1jBazdUGZuSLt28nV58GAAD1Vjp3LHerHmg5AgAAsCAcAQAAWBCOAAAALAhHAAAArSUclZWVSXJysoSEhIiPj495IG1qaqpUVFQ49pk2bZp4eXk5LaNHj3Y6jq5bu3atC64AAAC4G48NRyUlJTJkyBApLi6W5cuXy8GDB2XRokWyefNmiYuLkxMnTjj21TB09OhRx6L7AwAAtKqh/CkpKaa1aMOGDeLn52fWhYWFSUxMjISHh8vs2bNl4cKFZr2vr68EBwe7+IwBAIAn8MiWI20Vys/PlxkzZjiCkZ2GoClTpkheXp7Yn6n75ptvSs+ePeXKK6+UBx980KnbrS5VVVXmYXXWBQAAtF4eGY60K02DT3R0dI3bdX1lZaUcP37cdKm99NJLprtt3rx5smXLFhkzZoycP3++Xp+VlZVlnuJrX0JDQ5v4agAAgDvx2G41ZW8Zqo12u02aNMnx+uqrr5ZrrrnGdLtpa9LNN99c52ekpaXJY4895nitLUcEJAAAWi+PbDmKiIgwI8yKiopq3K7rg4KCJCAg4KJt/fr1kx49epgC7vrQeqWuXbs6LQAAoPXyyHAUGBgo8fHxkpOTI2fPnnXaVl5eLrm5uWYIf00+/vhjU3PUq1evFjpbAADgSTwyHKns7GxTLJ2QkCBbt241cx6tX7/ehKaoqChJT0+XL774QmbNmiU7duyQ0tJSU3c0btw40/Kk7wMAAGg14SgyMlIKCwtNN1liYqKZAFILrTUYFRQUiL+/v7Rr10727Nkjt912m1k/ffp0GTx4sGzbts10lwEAALSqguw+ffrIsmXLHK8zMjJk/vz5JhANHTrUDPPXIf/ftrAbAAC0HR4djqrLzMw0gUm70WJjY8Xb22MbxgAAgIu0qnCkkpKSXH0KAADAg7W6cNRS9mYmMKwfAIBWiH4nAAAAC8IRAACABeEIAADAgnAEAABgQUF2Iw3MyBdv306NfTsAAC5VOncsP4Fa0HIEAABgQTgCAACwIBwBAABYEI4AAAA8IRyVlZVJcnKyhISEiI+Pj/Tu3VtSU1OloqLCsc/q1atl1KhREhgYKF5eXrJ79+6LjvPCCy/IjTfeaGaz1n1Onjx50T66fu3atc1+TQAAwP25ZTgqKSmRIUOGSHFxsSxfvlwOHjwoixYtks2bN0tcXJycOHHC7HfmzBkZPny4zJs3r9ZjffnllzJ69Gj5xS9+0YJXAAAAPJVbDuVPSUkxrUUbNmwQPz8/sy4sLExiYmIkPDxcZs+eLQsXLpSpU6eabaWlpbUe69FHHzV/vvnmmy109gAAwJO5XcuRtgrl5+fLjBkzHMHILjg4WKZMmSJ5eXlis9la5Hyqqqrk9OnTTgsAAGi93C4caVeaBp/o6Ogat+v6yspKOX78eIucT1ZWlnTr1s2xhIaGtsjnAgAA13C7cGRXV8uQdru1hLS0NDl16pRj0UJxAADQerldOIqIiDCjx4qKimrcruuDgoIkICCgRc7H19fXjHSzLgAAoPVyu3Ckw/Lj4+MlJydHzp4967StvLxccnNzZdq0aS47PwAA0Lq5XThS2dnZphA6ISFBtm7darqy1q9fb0JTVFSUpKenO4q3dW6j999/37w+cOCAea0hyk7/rut0OgD13nvvmdf26QAAAADcPhxFRkZKYWGh9OvXTxITE80EkGPGjDHBqKCgQPz9/c1+69atM8P7x47975OFJ02aZF7rnEh2+nddd++995rXI0aMMK/1vQAAANV52VpqTPy3lJGRIfPnz5eNGzfK0KFDXXYeOpTfjFp7dKV4+3Zy2XkAAPBtlM79b8NCW3H6/76/dXBVXfXDbjkJZE0yMzOlT58+smPHDomNjRVvb7ds9AIAAB7OY8KRSkpKcvUpAACAVs6jwpE72ZuZwLB+AABaIfqmAAAALAhHAAAAFoQjAAAAC2qOGmlgRj5D+QEAHqutDeVvCFqOAAAALAhHAAAAFoQjAAAAC8IRAACABeEIAACgtYSjsrIySU5OlpCQEPHx8ZHevXtLamqqVFRUOPbx8vKqcXnqqaec9lm7dq2LrgIAALgTjw1HJSUlMmTIECkuLpbly5fLwYMHZdGiRbJ582aJi4uTEydOmP2OHj3qtCxZssSEoQkTJrj6EgAAgBvy2HmOUlJSTGvRhg0bxM/Pz6wLCwuTmJgYCQ8Pl9mzZ8vChQslODjY6X2vvPKK3HTTTdKvXz8XnTkAAHBnHtlypK1C+fn5MmPGDEcwstMwNGXKFMnLyxObzea07dixY/Laa6/J9OnT6/1ZVVVVcvr0aacFAAC0Xh4ZjrQrTYNPdHR0jdt1fWVlpRw/ftxp/YsvvihdunSRO+64o96flZWVJd26dXMsoaGh3/r8AQCA+/LIcGRXvWWoOu12s9J6I21V6tixY70/Iy0tTU6dOuVYtAgcAAC0Xh4ZjiIiIkxRdVFRUY3bdX1QUJAEBAQ41m3btk0OHDggP/nJTxr0Wb6+vtK1a1enBQAAtF4eGY4CAwMlPj5ecnJy5OzZs07bysvLJTc3V6ZNm+a0fvHixTJ48GAZNGhQC58tAADwJB4ZjlR2drYplk5ISJCtW7ea7q7169eb0BQVFSXp6emOfbWIetWqVQ1uNQIAAG2Px4ajyMhIKSwsNEPyExMTzQSQY8aMMcGooKBA/P39HfuuWLHC1CdNnjzZpecMAADcn8eGI9WnTx9ZtmyZ6Uq7cOGCaS3SeY/27NnjtN99990nX375pRltVhMNTrfffnsLnTUAAHBnHjsJZE0yMzNNYNqxY4fExsaKt7dHZz8AAOACrSocqaSkJFefAgAA8GCtLhy1lL2ZCQzrBwCgFaLfCQAAwIJwBAAAYEE4AgAAsKDmqJEGZuSLt2+nxr4dAACXK5071tWn4JZoOQIAALAgHAEAAFgQjgAAACwIRwAAAJ4WjsrKyiQ5OVlCQkLEx8fHPGQ2NTVVKioqatz/gQceEC8vL3nuuedq3H7//fdLu3btZNWqVc185gAAwNO4fTgqKSmRIUOGSHFxsSxfvlwOHjwoixYtks2bN0tcXJycOHHCaf81a9aYZ6tpkKqJPoB2xYoV8tOf/lSWLFnSQlcBAAA8hduHo5SUFNNatGHDBrnhhhskLCxMxowZI5s2bZIjR47I7NmzHfvq64cfflhyc3OlQ4cONR5PW4uuuuoq+fnPfy5bt241rVIAAAAeEY60VSg/P19mzJghfn5+TtuCg4NlypQpkpeXJzabTS5cuCBTp06VWbNmyYABA2o95uLFi+Wuu+6Sbt26mZC1bNmyS55DVVWVnD592mkBAACtV6PD0V/+8hf53ve+Z7qvDh06ZNZpjc8rr7zSZCenXWkafKKjo2vcrusrKyvl+PHjMm/ePGnfvr088sgjlzyedrlNnDjRvNaQtHTpUvMZtcnKyjJByr6EhoY2wZUBAIBWFY4WLlwojz32mNxyyy1y8uRJOX/+vFkfEBBQaxH0t3Gp8KK0a+z55583rUBaiF0brTFKSEiQHj16mNd6/qdOnZJ//vOftb4nLS3N7GNf6IYDAKB1a1Q4WrBggfzpT38y9T466stOC6ffe++9Jju5iIgIE3aKiopq3K7rg4KCZNu2bfLpp5+aeiRtPdJFW7Mef/xx6dOnj9lXA9yLL74or732mmOfTp06ma67SxVm+/r6SteuXZ0WAADQejXq2WofffSRxMTE1Bgkzpw5I00lMDBQ4uPjJScnR2bOnOlUd1ReXm4Kr7VgW2uNRo4c6fRebSHS9UlJSeb1P/7xD/n8889l165dToFu7969Zh9tAdOWLwAA0LY1quWob9++snv37ovWr1+/vtb6oMbKzs42RdEaduyjy/RzNDRFRUVJenq6CVEDBw50WnS0mhZtX3nllY5C7LFjx8qgQYOc9ktMTDShSIMWAABAo8KR1htpi419pNjbb78tv/nNb0x9js4f1JQiIyOlsLBQ+vXrZ4KMTgCpo8w0GBUUFIi/v3+dxzh27JjpTpswYcJF27y9vWX8+PEmPAEAAHjZ6qp2roW2tDzxxBPy4Ycfmtc6ai0zM1OmT5/e7Hc1IyND5s+fLxs3bpShQ4dKS9Kh/GbU2qMrxdu3U4t+NgAATal07tg2c0NP/9/3tw6uqqt+uME1R99884387W9/M91cOs+Qzjj9xRdfSM+ePaWlaAjTQmsdlh8bG2tafwAAAJpCg8ORjvLSZ5fZR5DpiC9dWpq90BoAAMDlo9W0tUZHfWn9T1u1NzOBYf0AALRCjQpH+jgPnUPo448/lsGDB0vnzp2dtl9zzTVNdX4AAADuX5BdU42PTtaoh9I/7TNmt/WCLgAA0AYKsu2TQAIAALRGjQpHbbnWCAAAtG6NCkcvvfTSJbfffffd0toNzMhnniMAgMdrS3MdNWs4Sk1NdXr99ddfm/mOfHx8zLD+thCOAABA69So2RMrKyudFp0E8sCBAzJ8+HBZvnx5058lAABAC/FuymegzZ0796JWJQAAAE/SpM/d0NmzP/nkk6Y8JAAAgPuHo3Xr1jktr7zyiixatEjuuusu+d73victpaysTJKTk81Db7XeSUfRactVRUWF0376qJPbbrvNzG+gE1Zed911cvjwYcd2fU7bc88912LnDQAAWllB9u233+70Wid+DAoKkh/84AfyzDPPSEsoKSmRuLg4iYqKMnVOffv2lX379smsWbPk9ddfNw+l7d69u3z44YemFmr69OnmgbU68ZPu17FjxxY5TwAA0AbC0YULF8TVUlJSTGvRhg0bxM/Pz6wLCwuTmJgYCQ8Pl9mzZ8vChQvNn7fccov87ne/c7xXtwMAADRZt9qTTz5phu5Xd/bsWbOtuZ04cULy8/PNM97swcguODhYpkyZInl5eeYxJq+99pppXUpISJCePXvK9ddfL2vXrq33Z1VVVZkpx60LAABovRoVjrR7SofvV6eBSbc1t+LiYvMct+jo6Bq363qdYuDIkSPmPHUU3ejRo00r0/jx4+WOO+6QLVu21OuzsrKyTK2SfQkNDW3iqwEAAB4fjuwPmK3u3XffNXU+LaWuZ+bq6Dk1btw4mTlzplx77bXy85//XG699VZTQF4faWlp5iF19kWLwAEAQOvVoJqjyy67zIQiXbSryhqQtAtLW2keeOABaW4RERHms3UUmrYEVafrtUC8R48eJiBdddVVF7Us/etf/6rXZ/n6+poFAAC0DQ0KRzrcXVtrdPi8dp9pN5OdFkfrkHgdQdbcAgMDJT4+XnJyckyLkLXuqLy8XHJzcx0F2zpsX2fvtvrggw94eC4AAPj24eiee+4xf+qw+WHDhkmHDh3EVbKzs805aKH1nDlznIbya6tWenq62U9fT5w4UUaMGCE33XSTrF+/Xl599VV58803XXbuAACgldUc3XDDDY5g9NVXX7lkNJc+rqSwsFD69esniYmJpiVozJgxJhgVFBSIv7+/2U+73bS+SIfyX3311fLnP/9Z/v73v5u5jwAAAKrzstVV1VwDHZX205/+VFauXHnRbNT2+iNXyMjIkPnz58vGjRtl6NChzfIZGv7MqLVHV4q3b6dm+QwAAFpK6dyxbeJmn/6/728dXKUTQjd5y5F2Vf3zn/80kyxqsbK2xmgNkj7G46WXXhJX0XP4/e9/b2bHdoeJKgEAQBuZIVtrdjQE3XjjjZKUlCTf//73zQgy7drSYmidhNFV9HwAAABaNBzpDNVa66O0aUpfK63jefDBB6Ut2JuZUGezHAAA8DyN6lbTYPTRRx+Zv/fv39/UHtlblAICApr2DAEAANw9HGnXlc6GrXTG6T/84Q/mKfc655DWIwEAALSp0WrVHTp0SHbu3Gnqjq655hppzRpS7Q4AADzv+7tRNUdWOs+RFmLrAgAA4OkaFY50HqPf/va3ZnLFY8eOmcdxaB3Sr371K/MIkenTp0trNzAjn3mOAACtQluZ66hZa45+85vfyLJly8ys0/r8MruBAweaOY8AAADaVDjSOY5eeOEFM59Ru3btHOsHDRok+/fvb8rzAwAAcP9wdOTIEVN8XZ3OSv311183xXkBAAB4Tji66qqrZNu2bRetf/nllyUmJqYpzgsAAMBzwlF6ero89NBDMm/ePNNatHr1arn33ntNLZJua4iysjJJTk42z2XT+iUd9Zaamur0QFs9/qhRoyQwMFC8vLxk9+7dFx3n/vvvl/DwcPHz85OgoCAZN25crV18CQkJpjuwsLCwEVcPAABaswaFo5KSEtFpkTR46GzYmzZtks6dO5tAVFRUZNbFx8c36HhDhgyR4uJiWb58uRw8eNCMgNu8ebPExcU5Hkty5swZ82gSDWO1GTx4sCxdutScR35+vjlPDVQ6ss7q8OHDsn37dhPulixZ0pDLBwAAbUCDJoHU1pajR49Kz549zeuJEyfK73//e7n88ssb9eFjxoyRvXv3mqkAtMXHrry83LQC3X333bJw4ULH+tLSUunbt6/s2rVLrr322ksee8+ePaZAXAOXHssuMzPTtChlZGTI0KFDzfVYP7u+k0iFPrqSofwAgFahLQzlP92ASSAb1HJUPUe9/vrrplWnMbRVSFt4ZsyYcVE4CQ4ONiPh8vLyLvrM+tBz0lYkDVKhoaFO56/r77rrLvNMOC0q1zqpS6mqqjI31LoAAIDWq1E1R3bf5skj2pWm74+Ojq5xu66vrKyU48eP1/uYOTk54u/vbxYNbhs3bnSah0m7Ab/88ktTc6Q0JC1evPiSx8zKyjJJ075YwxYAAGjj4UiLoXWpvq45A5Y13NRFW5u0y23Lli0SFRUliYmJ5vEmdlpjpF2B7dv/d2LwyZMnS0FBgXz44Ye1HjMtLc00wdkXLSAHAACtV/uGBplp06aJr6+vea3B44EHHjBF2VY6uqwu2qWlwUoLqMePH3/Rdl2vo84CAgLqfX721p3IyEhTT3TZZZfJmjVrTAjSbjz9u87DZK1j0oJtDU060q4meq326wUAAK1fg8LRPffc4/Rau6UaS4fl68g27QqbOXPmRQXZubm5kpKS0ujja5DTRWuGlB7viiuukLVr1zrtt2HDBnnmmWfkySefdJrtGwAAtE0NCkdazNyUsrOzZdiwYaYGaM6cOaaAet++fTJr1izTLWafM0lbfXQI/ieffGJeHzhwwFG4rYtOCaDF2zp0X1ubPv74Y5k7d64JXLfccovZV2uL7rzzTvP8NyutIdKus/Xr18vYsa2/Wh8AADRjQfa3pd1fOhFjv379TH2QTgCpw/s1GGktkBZWq3Xr1pmZt+3hZdKkSea1zomkOnbsaGbs1iCk3XVaV9SlSxczn5FOO7Bz50559913ZcKECRedg3bD3XzzzXUWZgMAgLahQfMctQSdf2j+/PlmpJnWDbkb5jkCALQ2zHP0LbrVWoJO0tinTx/ZsWOHxMbGire3Sxu3AABAG+N24UglJSW5+hQAAEAb5ZbhyBPszUyoc/pxAADgeeizAgAAsCAcAQAAWBCOAAAALKg5aqSBGfni7dupsW8HAMCttIXh/PVFyxEAAIAF4QgAAMCCcAQAAGBBOAIAALAgHAEAAHhaOCorK5Pk5GQJCQkRHx8f6d27t6SmpkpFRYVjn9WrV8uoUaMkMDBQvLy8ZPfu3bUeLysrS9q1aydPPfVUC10BAADwFG4fjkpKSmTIkCFSXFwsy5cvl4MHD8qiRYtk8+bNEhcXJydOnDD7nTlzRoYPHy7z5s2r85hLliyRn/70p+ZPAAAAj5rnKCUlxbQWbdiwQfz8/My6sLAwiYmJkfDwcJk9e7YsXLhQpk6daraVlpZe8nhbtmyRs2fPypNPPikvvfSSbN++XYYNG1br/lVVVWaxO336dJNdGwAAcD9u3XKkrUL5+fkyY8YMRzCyCw4OlilTpkheXp7YbLZ6H3Px4sUyefJk6dChg/lTX1+KdsF169bNsYSGhjb6egAAgPtz63CkXWkafKKjo2vcrusrKyvl+PHj9Tqetvq8/PLLctddd5nX+ufKlSvliy++qPU9aWlpcurUKcei9U8AAKD1cutwZFdXy5B2u9WH1ixpV9ygQYPM62uvvdYUd2vrU218fX2la9euTgsAAGi93DocRUREmJFnRUVFNW7X9UFBQRIQEFCv42kX2r59+6R9+/aO5f3336cwGwAAeEZBtg7Lj4+Pl5ycHJk5c6ZT3VF5ebnk5uaagu36eO+99+Q///mPvPnmm9K9e3enuqYbb7xR9u/fL/3792+W6wAAAJ7DrVuOVHZ2thktlpCQIFu3bjU1P+vXrzehKSoqStLT0x0hR+c20pYgdeDAAfNaQ5S91Sg2NlZGjBghAwcOdCz6+rrrrquzMBsAALQNbh+OIiMjpbCwUPr16yeJiYmmRmjMmDEmGBUUFIi/v7/Zb926dWZ4/9ixY83rSZMmmdc6J9K5c+fkr3/9q0yYMKHGz9D1Oqz/66+/btFrAwAA7sfL1pBx8G4iIyND5s+fLxs3bpShQ4e26GfriDczpP/RleLt26lFPxsAgOZSOve/jQutlf37W0ee1zW4yq1rjmqTmZkpffr0kR07dpiuMm9vt28AAwAAHsIjW448JXkCAADP+/6myQUAAMCCcAQAAGBBOAIAALAgHAEAAHj6aDV3MDAjn6H8AIBWr7SVD/GvCS1HAAAAFoQjAAAAC8IRAACABeEIAADAE8NRWVmZJCcnS0hIiPj4+JgH0KampkpFRYVjnyeeeEL69+8vnTt3lssuu0xGjhwp//73v52O4+XlVeOyYsUKF1wVAABwNx4RjkpKSmTIkCFSXFwsy5cvl4MHD8qiRYtk8+bNEhcXJydOnDD7RUVFSXZ2trz33nvyr3/9yzx/bdSoUXL8+HGn4y1dulSOHj3qtNx+++0uujoAAOBOPGIof0pKimkt2rBhg/j5+Zl1YWFhEhMTI+Hh4TJ79mxZuHCh/PjHP3Z63/z582Xx4sWyZ88eufnmmx3rAwICJDg4uMWvAwAAuD+3bznSVqH8/HyZMWOGIxjZacCZMmWK5OXlSfXn5547d05eeOEF85C5QYMGNfrzq6qqzMPqrAsAAGi93D4caVeaBp/o6Ogat+v6yspKR9fZ//7v/4q/v7907NhRnn32Wdm4caP06NHD6T2TJ082+1iXw4cP13j8rKwsE7DsS2hoaDNcJQAAcBduH47sqrcMVafdbuqmm26S3bt3y/bt22X06NGSmJgon376qdO+Gpp0H+uihd41SUtLk1OnTjkWLQwHAACtl9uHo4iICDOarKioqMbtuj4oKMjUESkdqabvGTp0qKk3at++vfmzenec7mNddL+a+Pr6SteuXZ0WAADQerl9OAoMDJT4+HjJycmRs2fPOm0rLy+X3NxcmTZtWq3vv3DhgqkbAgAAaBXhSOnwfA04CQkJsnXrVtO1tX79ehOadPh+enq6nDlzRn7xi1/Ijh075NChQ7Jz504zL9KRI0fkRz/6kdPxTp48aYKVddH3AwAAeEQ4ioyMlMLCQunXr5+pIdIJIMeMGWOCUUFBgSmobteunezfv18mTJhg1v/whz80E0Ru27ZNBgwY4HS8pKQk6dWrl9OyYMECl10fAABwHx4xz5HSCR2XLVvmeJ2RkWHmMdI5jLS+SEenrV69+lsXdgMAgLbNY8JRdZmZmSYwaTdabGyseHt7RCMYAABwcx4bjuzdYwAAAE3Jo8ORK+3NTGBYPwAArRB9UQAAABaEIwAAAAvCEQAAgAXhCAAAwIKC7EYamJEv3r6dGvt2AAA8WuncsdJa0XIEAABgQTgCAACwIBwBAABYEI4AAADcLRyVlZVJcnKyhISEiI+Pj/Tu3VtSU1OloqLCsY8+VHbUqFESGBgoXl5esnv37ouO89VXX0lKSorZx9/fXyZMmCDHjh1zbC8tLTXvrWnRZ7QBAAC4PByVlJTIkCFDpLi4WJYvXy4HDx6URYsWyebNmyUuLk5OnDhh9jtz5owMHz5c5s2bV+uxZs6cKa+++qqsWrVKtmzZIp988onccccdF+23adMmOXr0qNMyePDgZr1OAADgGVw+lF9berS1aMOGDeLn52fWhYWFSUxMjISHh8vs2bNl4cKFMnXqVEfrT01OnTolixcvlr/97W/ygx/8wKxbunSpREdHm1ahoUOHOvbVlqXg4OAWuT4AAOBZXNpypK1C+fn5MmPGDEcwstPwMmXKFMnLyxObzVbnsXbu3Clff/21jBw50rGuf//+Jmi99dZbjT7HqqoqOX36tNMCAABaL5eGI+1K0+CjrTs10fWVlZVy/PjxOo9VXl5uWqACAgKc1l9++eVmm9WwYcNMTZJ1qU1WVpZ069bNsYSGhtb7+gAAgOdxebeaqqtlSENPU9LWqNoCWXVpaWny2GOPOV5ryxEBCQCA1sul4SgiIsKMFCsqKpLx48dftF3XBwUFXdQaVBPthjt37pycPHnSaX8drVa9vkjDjX52ffj6+poFAAC0DS7tVtPC6Pj4eMnJyZGzZ886bdOusNzcXJk2bVq9jqWjzTp06GBGudkdOHBADh8+bEa9AQAAeES3WnZ2tqkBSkhIkDlz5kjfvn1l3759MmvWLImKipL09HRH8bYGHR2ebw8+SluFdNF6oOnTp5susO7du0vXrl3l4YcfNsHIOlJN6fxJ1euQtLWpY8eOLXbdAADAPbl8nqPIyEgpLCyUfv36SWJiopkAcsyYMSYYFRQUOIql161bZ4b3jx3736cAT5o0ybzWOZHsnn32Wbn11lvN5I8jRowwoUknj6xOR7T16tXLaVm7dm0LXjUAAHBXXrb6jJNvYRkZGTJ//nzZuHHjRa0+rqYF2WbU2qMrxdu3k6tPBwAAlyid+9/GCk9h//7WeRG1d8mtu9VqkpmZKX369DGTN8bGxoq3t8sbuAAAQBvhluFIJSUlufoUAABAG+S24cjd7c1MqLNZDgAAeB76qwAAACwIRwAAABaEIwAAAAtqjhppYEY+Q/kBAG1aqYcN568vWo4AAAAIRwAAADWj5QgAAMCCcAQAAGBBOAIAAPDEcFRWVibJyckSEhIiPj4+0rt3b0lNTZWKigrHPl5eXjUuTz31VJ37rFixwkVXBgAA3IlHDOUvKSmRuLg4iYqKkuXLl0vfvn1l3759MmvWLHn99dfNA2q7d+8uR48edXqfbps+fbpMmDDBaf3SpUtl9OjRTusCAgJa5FoAAIB784hwlJKSYlqLNmzYIH5+fmZdWFiYxMTESHh4uMyePVsWLlwowcHBTu975ZVX5KabbpJ+/fpdFISq71ubqqoqs9idPn26Sa4JAAC4J7fvVjtx4oTk5+fLjBkzHMHITgPOlClTJC8vT2w2m9O2Y8eOyWuvvWZajr6NrKws6datm2MJDQ39VscDAADuze3DUXFxsQk+0dHRNW7X9ZWVlXL8+HGn9S+++KJ06dJF7rjjjoveM3nyZPH393daDh8+XOPx09LS5NSpU45Fa58AAEDr5RHdaqp6y1B12u1mtWTJEtOq1LFjx4v2ffbZZ2XkyJFO67TQuya+vr5mAQAAbYPbh6OIiAgzmqyoqEjGjx9/0XZdHxQU5FRQvW3bNjlw4IDpbquJdsfpcQEAADyuWy0wMFDi4+MlJydHzp4967StvLxccnNzZdq0aU7rFy9eLIMHD5ZBgwa18NkCAABP5/bhSGVnZ5sRYwkJCbJ161ZT97N+/XoTmnR4f3p6utNoslWrVslPfvKTWo938uRJE6ysy5kzZ1roagAAgDvziHAUGRkphYWFZkh+YmKimQByzJgxJhgVFBSYgmo7ncxR65O06Lo2SUlJ0qtXL6dlwYIFLXQ1AADAnXnZ6qp0dlMZGRkyf/582bhxowwdOrTFPldbpsyQ/kdXirdvpxb7XAAA3E3p3LHiKezf3zryvGvXrp5dkF2bzMxM6dOnj5kdOzY2Vry9PaIRDAAAuDmPDUf27jEAAICm5NHhyJX2ZibU2SwHAAA8D31RAAAAFoQjAAAAC8IRAACABTVHjTQwI5+h/AAAtMKpAGg5AgAAsCAcAQAAWBCOAAAALAhHAAAA7hSOysrKJDk5WUJCQsTHx8c8VDY1NVUqKioc+6xevVpGjRolgYGB4uXlJbt373Y6xokTJ+Thhx+WK6+8Uvz8/CQsLEweeeQR8/yUmiQkJEi7du3Mw2wBAADcJhyVlJTIkCFDpLi4WJYvXy4HDx6URYsWyebNmyUuLs6EHnXmzBkZPny4zJs3r8bjfPLJJ2Z5+umnZe/evbJs2TJZv369TJ8+/aJ9Dx8+LNu3b5eHHnpIlixZ0uzXCAAAPIuXzWazuerDx4wZY8LMBx98YFp87MrLyyU8PFzuvvtuWbhwoWN9aWmp9O3bV3bt2iXXXnvtJY+9atUqueuuu0ywat++vdMDa/fv3y8ZGRkydOhQOXr0qNNn1/epvqGPrmQoPwAAHjKU3/79rb1KdT3+y2UtR9oqlJ+fLzNmzLgonAQHB8uUKVMkLy9PGpvd7BdvDUZ6rKVLl5rQ1L9/f4mIiJCXX375ksepqqoyN9S6AACA1stl4Ui70jSsREdH17hd11dWVsrx48cbfOzPPvtMfv3rX8t9993ntH7Tpk3y5ZdfmpojpSFp8eLFlzxWVlaWSZr2JTQ0tMHnAwAAPIfLC7LrahnSIu2G0JadsWPHylVXXSVPPPGE0zatMZo4caKjNWny5MlSUFAgH374Ya3HS0tLM61Q9kULyAEAQOvlsnCkXVo68qyoqKjG7bo+KChIAgIC6n3Mzz//XEaPHi1dunSRNWvWSIcOHZy68XRdTk6OCUe6fOc735FvvvnmkoXZvr6+pnvOugAAgNbLZeFIh+XHx8ebsHL27FmnbVqQnZubK9OmTWtQi5EO99eWpnXr1knHjh2dtuvxrrjiCnn33XfNVAD25ZlnnjGj286fP99k1wYAADyXS7vVsrOzTcGz1gBt3brVdFnpEHwNTVFRUZKenu5o9dEg8/7775vXBw4cMK81RFmDkY5M0xoifa3bdLGHHl1/5513ysCBA50WHe6vNUr6uQAAAC4NR5GRkWYixn79+kliYqKZAFKH92sw0logf39/s5+2BMXExJhaIjVp0iTzWudEUu+88478+9//lvfee8901/Xq1cuxaODauXOnaTGaMGHCReegRdY333xznYXZAACgbXDpPEc10fmH5s+fLxs3bjTzELkb5jkCAKB1z3P0/ycBchM6SWOfPn1kx44dEhsbK97eLh9QBwAA2hC3C0cqKSnJ1acAAADaKLcMR55gb2YCw/oBAGiF6LMCAACwIBwBAABYEI4AAAAsCEcAAAAWFGQ30sCMfPH27dTYtwMAABfPfVQbWo4AAAAsCEcAAAAWhCMAAAALwhEAAIAnhKOysjJJTk6WkJAQ8fHxkd69e0tqaqpUVFQ49lm9erWMGjVKAgMDxcvLS3bv3n3Rce6//34JDw8XPz8/CQoKknHjxsn+/fsd20tLS2t9LwAAaHvcMhyVlJTIkCFDpLi4WJYvXy4HDx6URYsWyebNmyUuLk5OnDhh9jtz5owMHz5c5s2bV+uxBg8eLEuXLpWioiLJz88Xm81mAtX58+db8IoAAICncMuh/CkpKaa1aMOGDabFR4WFhUlMTIxpBZo9e7YsXLhQpk6d6mj9qc19993n+HufPn1kzpw5MmjQIPMePRYAAIBbtxxpq5C28MyYMcMRjOyCg4NlypQpkpeXZ1qAGkpbmrQVqW/fvhIaGlqv91RVVcnp06edFgAA0Hq5XTjSrjQNPtHR0TVu1/WVlZVy/Pjxeh8zJydH/P39zfL666/Lxo0bTctUfWRlZUm3bt0cS31DFQAA8ExuF47s6moZqm+4UdratGvXLtmyZYtERUVJYmKifPXVV/V6b1pampw6dcqxaKE4AABovdwuHEVERJjRY1pAXRNdr6POAgIC6n1MbfGJjIyUESNGyMsvv2xGq61Zs6Ze7/X19ZWuXbs6LQAAoPVyu3Ckw/Lj4+NNV9jZs2edtpWXl0tubq5MmzbtW7VI6aK1RAAAAG4fjlR2drYJLwkJCbJ161bTlbV+/XoTmrRbLD093VG8rfMTvf/+++b1gQMHzGsNUfYpAbRmaOfOnXL48GHZvn27/OhHPzKF3rfccotLrxEAALgntwxH2gVWWFgo/fr1M/VBOgHkmDFjTDAqKCgwhdVq3bp1Znj/2LH/fYLvpEmTzGudE0l17NhRtm3bZoKQdtdNnDhRunTpYkJSz549XXqNAADAPXnZGjMm3gUyMjJk/vz5ZqTZ0KFDXXYeOpTfjFp7dKV4+3Zy2XkAANAalc79b4NHc31/6+CquuqH3XISyJpkZmaaSRx37NghsbGx4u3tlo1eAADAw3lMOFJJSUmuPgUAANDKeVQ4cid7MxMY1g8AQCtE3xQAAIAF4QgAAMCCcAQAAGBBOAIAALAgHAEAAFgQjgAAACwIRwAAABaEIwAAAAvCEQAAgAXhCAAAwIJwBAAAYEE4AgAAsCAcAQAAWBCOAAAALAhHAAAAFu2tL1A3m81m/jx9+jS3CwAAD2H/3rZ/j18K4aiBKioqzJ+hoaGN+dkAAAAX+vzzz6Vbt26X3Idw1EDdu3c3fx4+fLjOm4umSfoaRMvKyqRr167c0mbEvW5Z3G/udWt12k3/3dYWIw1GISEhde5LOGogb+//lmlpMHKnH3prp/ea+829bo343eZet1Zd3fDf7fo2alCQDQAAYEE4AgAAsCAcNZCvr69kZGSYP9H8uN8th3vdsrjf3OvWyrcVfE962eozpg0AAKCNoOUIAADAgnAEAABgQTgCAACwIBwBAABYEI5E5A9/+IP06dNHOnbsKNdff728/fbbcimrVq2S/v37m/2vvvpq+cc//uG0XWvc09PTpVevXuLn5ycjR46U4uLiSx6zrWjKe/3111/Lz372M7O+c+fOZtbTu+++Wz755JMWuJK2+btt9cADD4iXl5c899xzzXDmnqc57nVRUZHcdtttZuI6/R2/7rrrzOz8aPr7/cUXX8hDDz0kV1xxhfl3+6qrrpJFixZxq6Vh93rfvn0yYcIEs/+l/n1o6M+vxdnauBUrVth8fHxsS5Ysse3bt89277332gICAmzHjh2rcf+CggJbu3btbL/73e9s77//vu2Xv/ylrUOHDrb33nvPsc/cuXNt3bp1s61du9b27rvv2m677TZb3759bWfPnrW1ZU19r0+ePGkbOXKkLS8vz7Z//37bW2+9ZYuNjbUNHjy4ha+s7fxu261evdo2aNAgW0hIiO3ZZ5+1tXXNca8PHjxo6969u23WrFm2d955x7x+5ZVXaj1mW9Ic91uPER4ebnvjjTdsH330ke2Pf/yjeY/e87ZsRQPv9dtvv237n//5H9vy5cttwcHBNf770NBjukKbD0f6ZZqSkuK4IefPnzf/4GdlZdV4wxITE21jx451Wnf99dfb7r//fvP3CxcumF+Ip556yrFdv8R9fX3NL0tb1tT3urb/Y2rmP3TokK2ta677/fHHH9u+853v2Pbu3Wvr3bs34aiZ7vXEiRNtd911V8N+6G1Ec9zvAQMG2J588kmnfb773e/aZs+ebWvLYht4r61q+/fh2xyzpbTpbrVz587Jzp07TbeX9dlp+vqtt96q8T263rq/SkhIcOz/0UcfSXl5udM+2iSuzYa1HbMtaI57XZNTp06ZptyAgABpy5rrfl+4cEGmTp0qs2bNkgEDBjTjFbTte633+bXXXpOoqCizvmfPnubfkLVr10pb11y/28OGDZN169bJkSNHTGnEG2+8IR988IGMGjVK2qpzjbjXrjhmc2jT4eizzz6T8+fPy+WXX+60Xl9rwKmJrr/U/vY/G3LMtqA57nV1X331lalBmjx5sts97LC13O958+ZJ+/bt5ZFHHmmmM/c8zXGvP/30U1MDM3fuXBk9erRs2LBBxo8fL3fccYds2bJF2rLm+t1esGCBqTPSmiMfHx9z37UuZsSIEdJWfdaIe+2KYzaH9q4+AaApaHF2YmKi+S++hQsXclObgf7X3vPPPy/vvPOOaZ1D89GWIzVu3DiZOXOm+fu1114r27dvN0XCN9xwA7e/iWk42rFjh2k96t27t2zdulVSUlLMQI/qrU5o/dp0y1GPHj2kXbt2cuzYMaf1+jo4OLjG9+j6S+1v/7Mhx2wLmuNeVw9Ghw4dko0bN7b5VqPmut/btm0zLRphYWGm9UgXveePP/64GXXSVjXHvdZj6v3Vlgyr6OjoNj9arTnu99mzZ+UXv/iFzJ8/X374wx/KNddcY0auTZw4UZ5++mlpq3o04l674pjNoU2HI206HTx4sGzevNnpv9j0dVxcXI3v0fXW/ZV+Idv379u3r/kBW/c5ffq0/Pvf/671mG1Bc9xrazDSqRI2bdokgYGBzXgVbft+a63Rnj17ZPfu3Y5F/6ta64/y8/OlrWqOe63H1GH7Bw4ccNpHa2C0VaMta477rf+O6KK1L1b6JW5vxWuLfBpxr11xzGZha+N0SKGOJFu2bJkZ4nnfffeZIYXl5eVm+9SpU20///nPnYaEtm/f3vb000/bioqKbBkZGTUO5ddj6BDQPXv22MaNG8dQ/ma41+fOnTPTJFxxxRW23bt3244ePepYqqqqbG1dc/xuV8dotea71zpdgq574YUXbMXFxbYFCxaYoeXbtm2ztXXNcb9vuOEGM2JNh/KXlJTYli5dauvYsaMtJyfH1pataOC91n97d+3aZZZevXqZYf36d/0dru8x3UGbD0dK/9EJCwsz8y7oEMMdO3Y4/R/mnnvucbppK1eutEVFRZn99f9Mr732mtN2Hc7/q1/9ynb55ZebX4Cbb77ZduDAgRb6kbade61zkWi+r2nRf+DQ9L/b1RGOmud3227x4sW2iIgI8yWt80rp3Glonvut/1E1bdo0M6Rc7/eVV15pe+aZZ8y/523dggbc69r+Xdb96ntMd+Cl/+Pq1isAAAB30aZrjgAAAKojHAEAAFgQjgAAACwIRwAAABaEIwAAAAvCEQAAgAXhCAAAwIJwBAAAYEE4AuAS06ZNk9tvv90t735paal4eXmZ58cBaHsIRwBgce7cOe4H0MYRjgC43I033igPP/ywPProo3LZZZfJ5ZdfLn/605/kzJkzkpSUJF26dJGIiAh5/fXXHe958803TevOa6+9Jtdcc4107NhRhg4dKnv37nU69t///ncZMGCA+Pr6Sp8+feSZZ55x2q7rfv3rX8vdd98tXbt2lfvuu0/69u1rtsXExJjP0PNThYWFEh8fLz169JBu3brJDTfcIO+8847T8XT/P//5zzJ+/Hjp1KmTREZGyrp165z22bdvn9x6663m8/Tavv/978uHH37o2K7vj46ONtfUv39/ycnJacK7DaAuhCMAbuHFF180oePtt982QenBBx+UH/3oRzJs2DATQEaNGiVTp06VL7/80ul9s2bNMoFHg0tQUJD88Ic/lK+//tps27lzpyQmJsqkSZPkvffekyeeeEJ+9atfybJly5yO8fTTT8ugQYNk165dZrueg9q0aZMcPXpUVq9ebV5//vnncs8998i//vUv2bFjhwk+t9xyi1lvlZmZaT53z549ZvuUKVPkxIkTZtuRI0dkxIgRJqz985//NOeYnJws33zzjdmem5sr6enp8pvf/EaKiorkt7/9rTknvT8AWoirn3wLoG3SJ3mPGzfO/F2f2D18+HDHtm+++cbWuXNn29SpU52emq7/ZL311lvm9RtvvGFer1ixwrFPRUWFzc/Pz5aXl2de//jHP7bFx8c7fe6sWbNsV111leN17969bbfffrvTPvYni+/ateuS13D+/Hlbly5dbK+++qpjnb7vl7/8peP1F198Yda9/vrr5nVaWpqtb9++tnPnztV4zPDwcNvf/vY3p3W//vWvbXFxcZc8FwBNh5YjAG5Bu8bs2rVrJ4GBgXL11Vc71mlXm/r000+d3hcXF+f4e/fu3eXKK680LS5K//ze977ntL++Li4ulvPnzzvWDRkypF7neOzYMbn33ntNi5F2q2m32BdffCGHDx+u9Vo6d+5s9rOftxZ5azdahw4dLjq+diNq99r06dPF39/fscyZM8ep2w1A82rfzMcHgHqpHha0dse6Tl+rCxcuNPkd1QBTH9qlVlFRIc8//7z07t3bdI1pOKtexF3TtdjP28/Pr9bja9BSWm91/fXXO23TwAigZRCOAHg0rf0JCwszf6+srJQPPvjAFDMr/bOgoMBpf30dFRV1ybDh4+Nj/rS2Ltnfq8XRWkekysrK5LPPPmvQ+WqrktYPaV1U9RClrWMhISFSUlJi6pQAuAbhCIBHe/LJJ00XnAaL2bNnm6Ju+/xJjz/+uFx33XVmNNrEiRPlrbfekuzs7DpHf/Xs2dO08Kxfv16uuOIKM2pMu9G0O+0vf/mL6YY7ffq0KQa/VEtQTR566CFZsGCBKRJPS0szx9WAFxsba7oEtZj7kUceMetHjx4tVVVV8p///McEv8cee+xb3SsA9UPNEQCPNnfuXElNTZXBgwdLeXm5vPrqq46Wn+9+97uycuVKWbFihQwcONCMAtMwpRNQXkr79u3l97//vfzxj380LTnjxo0z6xcvXmxCih5XR85piNEg1RAa5HSUmnah6VQAet7ajWZvRfrJT35ihvIvXbrU1FzpPjq6zj69AIDm56VV2S3wOQDQpHSeo5tuusmElYCAAO4ugCZDyxEAAIAF4QgAAMCCbjUAAAALWo4AAAAsCEcAAAAWhCMAAAALwhEAAIAF4QgAAMCCcAQAAGBBOAIAALAgHAEAAFgQjgAAAOT/+39gA5lpoMHAbgAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "top_features = feature_importance.head(15)\n",
+ "\n",
+ "plt.figure()\n",
+ "plt.barh(top_features[\"Feature\"], top_features[\"Importance\"])\n",
+ "plt.xlabel(\"Importance\")\n",
+ "plt.ylabel(\"Feature\")\n",
+ "plt.title(\"Top 15 Important Features\")\n",
+ "\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4d3ae23d-cc19-4f5a-8668-08dfc369bf8f",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7085d36f-2872-4ef6-b2b3-a18005a1f1a9",
+ "metadata": {},
+ "source": [
+ "### Conclusion\n",
+ "\n",
+ "In this project, a deep neural network model was developed to predict Depression, Anxiety, and Stress scores using questionnaire responses.\n",
+ "\n",
+ "The dataset contained 39,775 samples with 42 features representing psychological questionnaire items. The data was normalized and split into training and testing sets.\n",
+ "\n",
+ "The neural network achieved high prediction accuracy with very low Mean Absolute Error:\n",
+ "\n",
+ "* Depression MAE = 0.49\n",
+ "* Anxiety MAE = 0.40\n",
+ "* Stress MAE = 0.44\n",
+ "\n",
+ "Feature importance analysis showed that multiple questionnaire items contributed to the predictions, indicating that the model learned meaningful psychological patterns rather than relying on a single feature.\n",
+ "\n",
+ "Overall, the model demonstrated strong performance and good generalization ability, making it suitable for predicting mental health scores from questionnaire data.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "id": "c8e6b156-934f-4fd7-ae5d-aef3718ee59d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Requirement already satisfied: ipywidgets in e:\\conda\\envs\\tf\\lib\\site-packages (8.1.8)\n",
+ "Requirement already satisfied: comm>=0.1.3 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipywidgets) (0.2.3)\n",
+ "Requirement already satisfied: ipython>=6.1.0 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipywidgets) (8.38.0)\n",
+ "Requirement already satisfied: traitlets>=4.3.1 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipywidgets) (5.14.3)\n",
+ "Requirement already satisfied: widgetsnbextension~=4.0.14 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipywidgets) (4.0.15)\n",
+ "Requirement already satisfied: jupyterlab_widgets~=3.0.15 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipywidgets) (3.0.16)\n",
+ "Requirement already satisfied: colorama in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (0.4.6)\n",
+ "Requirement already satisfied: decorator in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (5.2.1)\n",
+ "Requirement already satisfied: exceptiongroup in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (1.3.1)\n",
+ "Requirement already satisfied: jedi>=0.16 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (0.19.2)\n",
+ "Requirement already satisfied: matplotlib-inline in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (0.2.1)\n",
+ "Requirement already satisfied: prompt_toolkit<3.1.0,>=3.0.41 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (3.0.52)\n",
+ "Requirement already satisfied: pygments>=2.4.0 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (2.19.2)\n",
+ "Requirement already satisfied: stack_data in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (0.6.3)\n",
+ "Requirement already satisfied: typing_extensions>=4.6 in e:\\conda\\envs\\tf\\lib\\site-packages (from ipython>=6.1.0->ipywidgets) (4.15.0)\n",
+ "Requirement already satisfied: wcwidth in e:\\conda\\envs\\tf\\lib\\site-packages (from prompt_toolkit<3.1.0,>=3.0.41->ipython>=6.1.0->ipywidgets) (0.6.0)\n",
+ "Requirement already satisfied: parso<0.9.0,>=0.8.4 in e:\\conda\\envs\\tf\\lib\\site-packages (from jedi>=0.16->ipython>=6.1.0->ipywidgets) (0.8.6)\n",
+ "Requirement already satisfied: executing>=1.2.0 in e:\\conda\\envs\\tf\\lib\\site-packages (from stack_data->ipython>=6.1.0->ipywidgets) (2.2.1)\n",
+ "Requirement already satisfied: asttokens>=2.1.0 in e:\\conda\\envs\\tf\\lib\\site-packages (from stack_data->ipython>=6.1.0->ipywidgets) (3.0.1)\n",
+ "Requirement already satisfied: pure-eval in e:\\conda\\envs\\tf\\lib\\site-packages (from stack_data->ipython>=6.1.0->ipywidgets) (0.2.3)\n"
+ ]
+ }
+ ],
+ "source": [
+ "!pip install ipywidgets"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "id": "7f53e39a-85fc-431c-9b8d-938e2dfe87b6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b1c9d4000d3646f1bc00a730d716bc6a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "HTML(value=\"\\nMental Health Predictor \\nDepression - Anxiety - Stress \\…"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "Answer the Questions (0 → 4) "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "88703f1d357c40fe9c16563fba644bcd",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q1', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "a8d0dc3bb82c48e9995c97b05fbc2219",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q2', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e0e6f84ab6474bfb963ee5fd6ce1f1c6",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q3', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1b03eb5dd4de4804b52539d1c7c61f20",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q4', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "0c8d9f09a7b0483c82fe4ab6b873b040",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q5', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "6f5227ccf9744c84aa30f81272a686c8",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q6', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3495accc1da64bdd9076b24a48277508",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q7', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "7c741986099e497eb7884ff87ba3d501",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q8', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "66f669486edc4e3d87dc6fd7d5473530",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q9', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b8117740578e42c09265e3033106e548",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q10', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "bb45aa705cb44467afccad42a19bcafb",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q11', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3956942329f34bb3a0b471ebc51518b0",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q12', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f842dfee88904afba965096555425315",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q13', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "950fae1f7fb446c1b397a38cbbcef9ed",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q14', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f62d22cf2d604996981d9bb97bb85642",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q15', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "891520443f194c82b43d7b336b88f309",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q16', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "d9e7d8da811d4967b9d340c03eb1e1f9",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q17', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "916e48b5645743aead4e15cdbb03b2ac",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q18', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f0188f47d7b54a8bb5033619dd8246c5",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q19', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "bf7fb7d3bad5466e997275808fab2e21",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q20', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "877b855b022b412e8b0a190f784260e5",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q21', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "8fb15b3e945342879823d88f1db6e9bd",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q22', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f9af225dcaed4d24877590220734b226",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q23', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e68a479aa8864f418c65f0e48984fab6",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q24', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1c28d566f77b46958bc3fc52bd7b6bfd",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q25', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "eb90cf2439044f22ab8e131f8feae22e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q26', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "6b76c12843e94e8698cc04f6ea94074a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q27', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3ef195f6bf5a47799c8286935daef4da",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q28', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "0cf022bd43d741d981faf92bfdc70e36",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q29', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "fbcb1e6ee44a46daaa48f9fe791bea0d",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q30', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "5daf9f2953424048a78ecce3ce4c7348",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q31', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "03c70298c6a54fc9ba1e76db395e96f0",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q32', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "7dcbc1fb4e8b4931bdd052bba8556061",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q33', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b22de470a7214244a887da47563a3e09",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q34', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "9a0b054440d242ecbdfe96f32a1c6944",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q35', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3b008068dba4452987c50334b9d1401a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q36', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "fee141378f3646fcb5a402e696cde2e5",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q37', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e60652a4fd754cc0bcedbbd9e7420699",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q38', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "6df2db40d1e14099bc8da13d91fe1505",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q39', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e4c6477489744a059241fcd3c800b8a7",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q40', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "6e3f6c6df1774f83877cd54f2cca1344",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q41', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "15f12d36ee4e444e8b4a61bbd5133708",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=2, description='Q42', layout=Layout(width='500px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "7742fd4c9e5b4f3ba572a5b75bf9d3c3",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Button(button_style='success', description='Predict Mental Health', style=ButtonStyle())"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "Prediction Results "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "5c8aff36624a4af18cbfa6bcbef3ca1d",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "FloatProgress(value=0.0, description='Depression', layout=Layout(width='500px'))"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "84c6da44dd1f4d4d8109e6d58ca2eae3",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "FloatProgress(value=0.0, description='Anxiety', layout=Layout(width='500px'))"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "11e488f76be24dfa93286899f8678700",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "FloatProgress(value=0.0, description='Stress', layout=Layout(width='500px'))"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "39d53a71c02b46ddad54b29d9ebd3ca8",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "HTML(value='')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import ipywidgets as widgets\n",
+ "from IPython.display import display, HTML\n",
+ "import numpy as np\n",
+ "\n",
+ "title = widgets.HTML(\"\"\"\n",
+ "Mental Health Predictor \n",
+ "Depression - Anxiety - Stress \n",
+ "\"\"\")\n",
+ "\n",
+ "questions = []\n",
+ "\n",
+ "for i in range(42):\n",
+ " \n",
+ " slider = widgets.IntSlider(\n",
+ " value=2,\n",
+ " min=0,\n",
+ " max=4,\n",
+ " step=1,\n",
+ " description=f\"Q{i+1}\",\n",
+ " layout=widgets.Layout(width='500px')\n",
+ " )\n",
+ " \n",
+ " questions.append(slider)\n",
+ "\n",
+ "\n",
+ "dep_bar = widgets.FloatProgress(\n",
+ " min=0,\n",
+ " max=100,\n",
+ " description='Depression',\n",
+ " layout=widgets.Layout(width='500px')\n",
+ ")\n",
+ "\n",
+ "anx_bar = widgets.FloatProgress(\n",
+ " min=0,\n",
+ " max=100,\n",
+ " description='Anxiety',\n",
+ " layout=widgets.Layout(width='500px')\n",
+ ")\n",
+ "\n",
+ "stress_bar = widgets.FloatProgress(\n",
+ " min=0,\n",
+ " max=100,\n",
+ " description='Stress',\n",
+ " layout=widgets.Layout(width='500px')\n",
+ ")\n",
+ "\n",
+ "\n",
+ "risk_label = widgets.HTML(\"\")\n",
+ "\n",
+ "\n",
+ "button = widgets.Button(\n",
+ " description=\"Predict Mental Health\",\n",
+ " button_style='success'\n",
+ ")\n",
+ "\n",
+ "\n",
+ "def risk_level(value):\n",
+ "\n",
+ " if value < 33:\n",
+ " return \"Low\"\n",
+ " \n",
+ " elif value < 66:\n",
+ " return \"Medium\"\n",
+ " \n",
+ " else:\n",
+ " return \"High\"\n",
+ "\n",
+ "\n",
+ "\n",
+ "def predict_model(b):\n",
+ "\n",
+ " answers = [q.value for q in questions]\n",
+ " answers = np.array(answers).reshape(1,-1)\n",
+ "\n",
+ " answers_scaled = scaler.transform(answers)\n",
+ "\n",
+ " pred = model_r.predict(answers_scaled)[0]\n",
+ "\n",
+ " pred = pred * 56\n",
+ "\n",
+ " dep = pred[0]\n",
+ " anx = pred[1]\n",
+ " stress = pred[2]\n",
+ "\n",
+ " dep_percent = dep/56*100\n",
+ " anx_percent = anx/56*100\n",
+ " stress_percent = stress/56*100\n",
+ "\n",
+ "\n",
+ " dep_bar.value = dep_percent\n",
+ " anx_bar.value = anx_percent\n",
+ " stress_bar.value = stress_percent\n",
+ "\n",
+ "\n",
+ " risk_label.value = f\"\"\"\n",
+ " Risk Levels \n",
+ "\n",
+ " Depression: {risk_level(dep_percent)} \n",
+ "\n",
+ " Anxiety: {risk_level(anx_percent)} \n",
+ "\n",
+ " Stress: {risk_level(stress_percent)} \n",
+ " \"\"\"\n",
+ "\n",
+ "\n",
+ "button.on_click(predict_model)\n",
+ "\n",
+ "\n",
+ "display(title)\n",
+ "\n",
+ "display(HTML(\"Answer the Questions (0 → 4) \"))\n",
+ "\n",
+ "for q in questions:\n",
+ " display(q)\n",
+ "\n",
+ "display(button)\n",
+ "\n",
+ "display(HTML(\"Prediction Results \"))\n",
+ "\n",
+ "display(dep_bar)\n",
+ "display(anx_bar)\n",
+ "display(stress_bar)\n",
+ "\n",
+ "display(risk_label)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "id": "adb590ca-a47e-4252-84c7-6fa43a91b5cf",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "questions = [\n",
+ "\n",
+ "\"I found it hard to wind down\",\n",
+ "\"I was aware of dryness of my mouth\",\n",
+ "\"I couldn't seem to experience any positive feeling at all\",\n",
+ "\"I experienced breathing difficulty\",\n",
+ "\"I found it difficult to work up the initiative to do things\",\n",
+ "\"I tended to over-react to situations\",\n",
+ "\"I experienced trembling\",\n",
+ "\"I felt that I was using a lot of nervous energy\",\n",
+ "\"I was worried about situations in which I might panic\",\n",
+ "\"I felt that I had nothing to look forward to\",\n",
+ "\"I found myself getting agitated\",\n",
+ "\"I found it difficult to relax\",\n",
+ "\"I felt down-hearted and blue\",\n",
+ "\"I was intolerant of anything that kept me from getting on\",\n",
+ "\"I felt I was close to panic\",\n",
+ "\"I was unable to become enthusiastic\",\n",
+ "\"I felt I wasn't worth much as a person\",\n",
+ "\"I felt that I was rather touchy\",\n",
+ "\"I was aware of the action of my heart\",\n",
+ "\"I felt scared without any good reason\",\n",
+ "\"I felt that life was meaningless\",\n",
+ "\n",
+ "\"I found it hard to calm down\",\n",
+ "\"I felt nervous\",\n",
+ "\"I felt sad and depressed\",\n",
+ "\"I found myself getting impatient\",\n",
+ "\"I felt that I was rather emotional\",\n",
+ "\"I felt restless\",\n",
+ "\"I had difficulty concentrating\",\n",
+ "\"I felt lonely\",\n",
+ "\"I found it difficult to relax\",\n",
+ "\"I felt hopeless\",\n",
+ "\"I felt worried about many things\",\n",
+ "\"I felt that I had no energy\",\n",
+ "\"I felt tense\",\n",
+ "\"I felt tired for no reason\",\n",
+ "\"I felt uneasy\",\n",
+ "\"I felt worthless\",\n",
+ "\"I felt anxious\",\n",
+ "\"I felt discouraged\",\n",
+ "\"I felt stressed\",\n",
+ "\"I felt overwhelmed\",\n",
+ "\"I felt emotionally exhausted\"\n",
+ "\n",
+ "]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "id": "090bcb96-0cb1-43b6-ab8e-fb9ab5df887d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "052172b7a5244a3091551f087b8a52a1",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I found it hard to wind down')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b535366bb82f4493b2475e9e327c63b4",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q1', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "d52ea52ec7294d8dad39b30fd049ff6b",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I was aware of dryness of my mouth')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "8eb2acfd300041f88921efd9fb7ed864",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q2', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b5c6ba8136954004b9bf010adb8c1a45",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value=\"I couldn't seem to experience any positive feeling at all\")"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e045aaba64d94c0b8cbbaa27f6cdee34",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q3', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "64488066245a406cb762f26bb77f7acb",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I experienced breathing difficulty')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "9f82dc6bdbde4059970c30e000ae1b07",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q4', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4bf99176779a4505ad222c68f823171a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I found it difficult to work up the initiative to do things')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "52c0da6a9247478aba318a615db82a75",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q5', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b2475cdb64384827b4059d6a5d337026",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I tended to over-react to situations')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "54e367bf57b34c0d86a1cdfe627fa85a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q6', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "2bcb93c9de15473d99b7db57b7fdb075",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I experienced trembling')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "37d066ff1eca491f81eeb1a94030a2f7",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q7', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b90216b86c144624aa24d32b681fb422",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt that I was using a lot of nervous energy')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "5e383f256a054c68813c8cbddd81ee8b",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q8', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "59e534bcf1dc4e3f8580e11ac8d30bb1",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I was worried about situations in which I might panic')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "92e809f0c57749b393bfc85b327143ad",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q9', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c8300b5c676740409d41361cd3850cd9",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt that I had nothing to look forward to')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "82e04e9045bb4804b2aa55b859da66e3",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q10', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "76647727636449b49df6cffd99b64c12",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I found myself getting agitated')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1aa94050e9f649d8a3948681a1af05d9",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q11', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "82a3c79c9be84473ac5cfabed31c7880",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I found it difficult to relax')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "2b9244fe1f5d42d8b27ccccc6b65b0fe",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q12', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f05f7fe894424423bbd5682c21af11a7",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt down-hearted and blue')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "48d0b3cffb0d42dda317d003d203a42c",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q13', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "04042fee5b464283ae035b1115b0cda8",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I was intolerant of anything that kept me from getting on')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c4af2cf25d904a01aafce6b6bc2099d1",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q14', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c20d63deaa994dc2bce4edbc2d631e83",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt I was close to panic')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "9e320e480b5c4dd488da35f38a702464",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q15', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "2ca958b3e440494a939856e7f355119e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I was unable to become enthusiastic')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1d739c420f6a47679f5b13986469a292",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q16', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "28ff17795d7f4353a8be82a8f8bdb074",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value=\"I felt I wasn't worth much as a person\")"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "2a7a6df4cb3d4ba0bae1d2b7a79de0db",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q17', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "afeaed9db29e4e088860fc6f028ca02e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt that I was rather touchy')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "6b7174cf6ec64c6390f89aac4c457073",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q18', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f840d326691b4cc4a6f1853f7cb6c250",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I was aware of the action of my heart')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "2e058d8d42ca45f0988b8327db92bab4",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q19', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4385f3a72477405f9ac9908e426c9153",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt scared without any good reason')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "a7dab9fbc9fd44409cb98cd1b47d6384",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q20', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "64de07f56ae84b7196e2038f607c7010",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt that life was meaningless')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "ecd80a3e5173454d8892b6bb4e443c08",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q21', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c7201a945d9b4218a5fef8e51921660a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I found it hard to calm down')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "cbab20e5098347ecafeb428e8764aeea",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q22', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "42c20ccbef2841fcbfcf3bab01ed851a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt nervous')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f9422c86b0ec41d8955558daa7340a99",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q23', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "88492bc6d35a4b35b3c04ff4068bd6c8",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt sad and depressed')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "9bb64bf723e4401e99b0b6c599ffe77f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q24', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4cb4012b69674f469f0d5fe0918cd630",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I found myself getting impatient')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "0063cf93eb0740edbc56a42f26ea3759",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q25', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "980a05f2899b40008f5034644df1dc15",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt that I was rather emotional')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f59d82c3d1b44b0e83757c5757160ef5",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q26', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "843d0e4b2ebe4be1a8f2457a4c34156f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt restless')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4a198316985d455283f82d889ca7f009",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q27', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1fa7c970bb874da899424b3208794bc2",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I had difficulty concentrating')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "8b52c21e44ad470aa73c3ba38eeed908",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q28', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b5a3d0202488415e8eb235f91b6839ca",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt lonely')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "aabaa63c0a984554bc7cdae06149a419",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q29', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "268834dd7e194fe79e0355bed096c22b",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I found it difficult to relax')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4eb024c93de7414f9b14d9a9609427a0",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q30', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e9ab20874a5f41bc99b4a6566c8e0f98",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt hopeless')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3d8bf124f5ec42f69671dbfcd39a8f62",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q31', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "8d6b7fbab1a9401faa1e36ee783ca522",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt worried about many things')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "b7569209c9cb445182decaa099dfe825",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q32', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "834dcaee3fbf4bbca654cb0b82d55869",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt that I had no energy')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "ebb813a05b614b9bb82cad41d2e59b80",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q33', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1374f96091f34044a2bb557a99f1e915",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt tense')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "bb7897aa5ac644a59f4ffc2f3fbdacb1",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q34', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4dcbf0236e724833b471afa3c6f93847",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt tired for no reason')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3c56531cc206415fa4985c6234b9bc5e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q35', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c5b9083f94174297a79be4210dd3757f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt uneasy')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "560c7a2daac443e398cb7eeb013a8bb4",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q36', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "15ee2bc073de44219ddd186886a92349",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt worthless')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f2be08e5319b4b60b7307501fe3d60a3",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q37', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "152d141fedab48dfbddb7ce369c28bfe",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt anxious')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "402f0f37e06842a7bd38f8c1105f2306",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q38', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "7bab4f4307004a63bc450797a902ee5f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt discouraged')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1f61a972e72543bab32698e8de4d672f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q39', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3f2c8fef40094a3086e6c189cc4fef8a",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt stressed')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "ba6d38ec322f4332ae51607a7d3a5cb7",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q40', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "bae83ef7a660495692d6b4a3f113eae7",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt overwhelmed')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "f280276df53f40c79b65b8db91ecb726",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q41', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "e1499e948ea9438288297174cf5a66a3",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Label(value='I felt emotionally exhausted')"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "2dd3e4491e234c6cacf796383fdbe154",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "IntSlider(value=0, description='Q42', layout=Layout(width='600px'), max=4)"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "4225e3637e904144af33ce9be19c8ad6",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Button(description='Predict', style=ButtonStyle())"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "888933e277114a05b53e87278d09139d",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Output()"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "id": "8b502715-c79b-4cb8-9f6f-eb60883be969",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n"
+ ]
+ }
+ ],
+ "source": [
+ "model_r.save(\"mental_model.h5\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "id": "9de7a25b-3ab2-4885-ac5a-8d1b3b7b1c8a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pickle\n",
+ "\n",
+ "pickle.dump(scaler, open(\"scaler.pkl\",\"wb\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "id": "764d3dca-0da5-4c5b-ae8f-31a4108992d7",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "===== MODEL EVALUATION =====\n",
+ "\n",
+ "\u001b[1m249/249\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step\n",
+ "Regression Metrics:\n",
+ "\n",
+ "MAE = 0.007952718074524872\n",
+ "RMSE = 0.010862623189120308\n",
+ "R2 = 0.9969703167532534\n",
+ "\n",
+ "Accuracy:\n",
+ "\n",
+ "Depression Accuracy = 0.9796354494028913\n",
+ "Anxiety Accuracy = 0.97561282212445\n",
+ "Stress Accuracy = 0.97561282212445\n",
+ "\n",
+ "Confusion Matrices:\n",
+ "\n",
+ "Depression:\n",
+ " [[ 843 24 0]\n",
+ " [ 13 3418 6]\n",
+ " [ 0 119 3532]]\n",
+ "\n",
+ "Anxiety:\n",
+ " [[1064 50 0]\n",
+ " [ 3 4614 1]\n",
+ " [ 0 140 2083]]\n",
+ "\n",
+ "Stress:\n",
+ " [[ 409 41 0]\n",
+ " [ 0 3828 4]\n",
+ " [ 0 149 3524]]\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhwAAAHHCAYAAAD074ENAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAATTlJREFUeJzt3Qd4FOX2+PGT0FvonVAUpfcmoBSlKMgFwc4FlCZcUJqg+ONSVZSOiqAXARtXQKUICNK59K6AyhVEg0pVINJDMv/nvN7Z/27ILgk7m+xuvh+eecLOzs7O7G4yZ8973veNsCzLEgAAgACKDOTOAQAACDgAAECqIMMBAAACjoADAAAEHAEHAAAIOAIOAAAQcAQcAAAg4Ag4AABAwBFwAACAgCPgAG7RyJEjJSIiIl2+ftevX5chQ4ZIdHS0REZGSrt27Rx/jiZNmpgFf5kzZ475vP3000+8JAhJBBxI8R88e8maNasUK1ZMWrZsKW+88Yb8+eefvJqp6MqVKzJ58mSpV6+e5M6d27wfd955p/Tt21f++9//BvS5Z82aJePHj5eHH35Y3n//fRkwYICEi/Xr17s+4x999FGS2zRs2NDcX7ly5Vt6jrffftv8PgHpSQRzqSC59A/k008/LaNHj5YyZcpIXFycnDhxwvyBXrVqlZQsWVKWLFkiVatWTTff8nXRC31qO3PmjNx///2ye/duefDBB6VZs2aSM2dOOXTokHzyySfmfbl27VrAnv/xxx+XTZs2yS+//BKw57CPP3PmzJKa9PPctGlT877qz+XLl3vcrxkG/fzr/bfffrscOHAgxc+hgUqBAgXMcyVXfHy8+Z3LkiVLus2sIbRlTOsDQOh54IEHpHbt2q7bQ4cOlbVr15oL39/+9jf57rvvJFu2bKl2PDr/oH7bT83nVBkzZjRLWnjqqadk79698umnn0qHDh087hszZoz83//9X0Cf/9SpU5InT56APkdqBxqJtWrVygTQGtxpcGCbO3euFC5cWO644w45e/ZswI/j4sWLkiNHDsmQIYNZgFBFkwocce+998o///lP+fnnn29IQ3///fcm9Z4vXz7zrVCDFf1DnlRzzcaNG+WZZ56R/PnzS1RUlHTu3PmGP+qlS5c2wc3KlSvNvjTQeOedd8x9586dk/79+5vaAv0mWLZsWXn99dclISHBYx+aBahVq5bkypXLPE+VKlVk6tSprvv1m+SoUaPMRUWPWY/n7rvvNpkcXzUcmvHQC75+89Xn12N96aWX5OrVq0meg2YJ6tata57jtttukw8++OCmr/X27dtl2bJl0q1btxuCDaXPO2HCBI91GhDec8895sKlgULbtm1NYOjOPp/Dhw+bgEa306YazWpdunTJ9e1et1m3bp0cPHjQ1fSg39TtpojE39rtx7g3IWgGRvdbokQJc7xFixY1x+Ren5BUDYcGOnreesHX16xatWqmSSep59PX4N1333W9F3Xq1JGdO3dKcunx6OMWLFjgsV4DjkcffTTJi//s2bPN70KhQoXMYytWrCjTp0+/4b3X127Dhg2u188+T/v3QO/7xz/+Yfajr5H7ffZrpO+p1s8MHz78huPT7RI/L5DWyHDAMZ06dTIX16+++kp69Ohh1ukfVm3vLl68uLz44ovmgjd//nxTZPjZZ5/JQw895LEPrT/QC51e/LR5QP9oahBjX8xset8TTzxhghN9rnLlypmLYuPGjeXXX38167WJZ8uWLSYDc/z4cZkyZYp5rAYN+tj77rvPBCNKL76bN2+Wfv36mdv6/GPHjpXu3bubgCA2NlZ27dole/bskebNm3t9DXR7vQBqgDVo0CATHOh+dP8LFy702FYv7LqdXkC7dOli6iL0Qq+BUKVKlbw+hx2s6eudHKtXrzZZKQ1o9LwuX74sb775pnlf9Hz0AuhOL6baZKDHrffPnDnTXPj0tSpYsKB8+OGH8sorr8iFCxfMNqpChQo3BDC+aKCkn41nn33WPL8GEvq+xMTE3HA8Nj1uvTDr66afEz1GDQb0NdNA037v3C+8WleknwX97IwbN07at28vP/74o2TKlOmmx5g9e3YTdPz73/+W3r17m3Vff/21OW59Tb755psbHqOfV33vNNOn2a8vvvjCBA4a8Pbp08dso59DPW9tArMzURpAudPH6GutwYRmOJKigY1up++B/j7VrFnTfM5139rE1qtXr5ueI5CqtIYDSI7Zs2db+pHZuXOn121y585t1ahRw3X7vvvus6pUqWJduXLFtS4hIcFq0KCBdccdd9yw71q1alnXrl1zrR83bpxZv3jxYte6UqVKmXUrVqzweO4xY8ZYOXLksP773/96rH/xxRetDBkyWDExMeZ2v379rKioKOv69etez6NatWpW69atfb4e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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhwAAAHHCAYAAAD074ENAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAREZJREFUeJzt3Ql4FFX28OGTsIQdBGSTVXFYBAOyCY4siiAwDIz7MoCyODCgLMrmMCC4oMiqIsggoI4MiwooIIhgQARkHxGFvyAaVBYZEWRNSNf3nDtT/XWHdJPQVUl35ff61BO6qrq6qrtjnZx77r1xlmVZAgAA4KJ4Nw8OAABAwAEAALIFGQ4AAOA6Ag4AAOA6Ag4AAOA6Ag4AAOA6Ag4AAOA6Ag4AAOA6Ag4AAOA6Ag7kCg899JBUrVo1p08jqpw6dUp69uwp5cqVk7i4OBkwYIDjr6Hvub73+K+nnnrKvNdAbkTAgWz36quvmv/pNmnSJGbOd86cOa4c++TJkzJ69GhJTEyUIkWKSMGCBaVOnToydOhQ+emnn8RNzz33nLmuPn36yFtvvSVdunQRr9Dr0u+YLuvXr79ou87oUKlSJbP9D3/4w2W/f4sXL3bgbIHcIY65VJDdbrrpJnMz/e677+Sbb76R6tWru/6aqamp4vP5JCEhIcvP1QCgdOnSkpSU5Og5ffvtt9K6dWtJTk6Wu+++W37/+99L/vz55YsvvpB//etfUrJkSfm///s/ccuNN94oefPmzfCG7JTz589LfHy85MuXT7I74Hj44YelQIEC5qcGjYH0s2zVqpX5PuhnsHTp0iy/hgaId911V5aC0QsXLphFzwvIbchwIFsdOHBANmzYIBMnTpQrr7xS3n777Wx5Xb3hXU6w4Ra96dxxxx1y5MgRc/PTAKNv377Sq1cvefnll00wokGIm44ePSolSpRw9TX0Pc/uYCNQ+/btZeHCheb9DjR37lxp0KCBaU7KDqdPnzY/NcAj2EBuRcCBbKUBxhVXXCEdOnQwfx1mFHBo5kNT3ePHj5cZM2bINddcY25cjRo1ki1btgTdMDVoadmypUmR2/bt2yeFCxeWe++9N2wNh2Y8Jk+eLNddd525CZQtW1b+8pe/yPHjx/376HN2794ta9eu9afo9fU0INB/T5o06aLz14BKt2kQEcq7774r//73v+Vvf/ubyWykV6xYMXn22WeD1umNU2+S2uyiGZc///nP8uOPPwbto9epf3nr+s6dO5t/63v0xBNPSFpamtlHAxw9Pw3+li1b5r8ufd/tpgj9dyD7OYFZHs1O3Xnnneamre9fxYoV5b777pMTJ06EreGwgynN4BQqVMhkWvQ8Mnq9BQsWmPdBj62vceutt5rPN7Puv/9++c9//iOrVq3yr0tJSZF33nlHHnjggQyfo9+7Zs2aSalSpcx7re+57h9Iz02DiDfeeMP//tnXaddpfPXVV+Y19Ptuf8bpazhmz55tHs+aNeui5hpdv3z58kxfKxD1tEkFyC41a9a0evToYf69bt06jRKszZs3B+1z4MABs75+/fpW9erVrRdeeMEaN26cVbp0aatixYpWSkqKf9+FCxeafadMmWIep6WlWTfddJNVtmxZ69ixY/79unXrZlWpUiXodXr27GnlzZvX6tWrlzV9+nRr6NChVuHCha1GjRr5X2PRokXmNfW833rrLbN89NFHZpu+ToMGDS66xr/+9a9W0aJFrdOnT4d8Hx544AFz3snJyZl632bPnm3213ObNGmSNWzYMKtgwYJW1apVrePHjwddZ4ECBazrrrvO6t69uzVt2jTrzjvvNM999dVXzT6HDx8216HvZ7169fzXderUKf/r6GcQ6JNPPjHr9ac6f/68Va1aNatChQrWM888Y82cOdMaPXq0Ob/vvvvO/zx9z/WcbPra+tno+/O3v/3NmjhxopWYmGjFx8db77333kWvp98BfY/1mp966imrUKFCVuPGjTP9fm3ZssVq1qyZ1aVLF/+2xYsXm9f78ccfzfl16NAh6Ln6eetn+Morr5jz09fTYy1dutS/j75fCQkJ1s033+x//zZs2GC2jRo1yuxfu3Ztq1OnTuZ9nzp1atC2QH/4wx+s4sWL+78LX3zxhZU/f37/7wngFQQcyDZbt241/7NdtWqVeezz+cz/3Pv3759hwFGqVCnrl19+8a9fsmSJWf/BBx8E7X///febG9H//d//WS+++KLZR28qgdIHHJ9++qnZ7+233w7ab8WKFRet15t3ixYtLrqe1157zez79ddf+9dpoKI38sCbbEb0Rqo3mczQY5YpU8aqU6eOdfbsWf96vQHq648cOTLoOnXdmDFjLnq99MFRRjfbzAYcO3bsMI814AsnfcAxYMAA8zx9/22//fabCV40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DqCGIzwCDgAAHOCTOEmTuIiP4VU0qQAAANeR4QAAwAE+679LpMfwKgIOAAAckOZAk0oaTSoAAACXjwwHAAAOIMMRHgEHAAAO8FlxZon0GF5FLxUAAOA6MhwAADiAJpXwCDgAAHBAmsSbJbJjeBcBBwAADrAcqOGwqOEAAAC4fGQ4AABwADUc4RFwAADggDQr3iyRHUM8i26xAADAdWQ4AABwgE4t74vw73ifeDfFQcABAIADqOEIjyYVAADgOjIcAABETdGo5dnPgoADAADHajginLxNmLwNAADgspHhAADAAT4H5lLx0UsFAACEQw1HeGQ4AABwKMPBOByh0S0WAAC4joADAAAHpFlxjiyX6/nnn5e4uDgZMGCAf925c+ekb9++UqpUKSlSpIjceeedcuTIkaDnJScnS4cOHaRQoUJSpkwZGTx4sFy4cCFon6SkJLnhhhskISFBqlevLnPmzMny+RFwAADgAC0YdWK5HFu2bJHXXntNrr/++qD1AwcOlA8++EAWLlwoa9eulZ9++knuuOMO//a0tDQTbKSkpMiGDRvkjTfeMMHEyJEj/fscOHDA7NOqVSvZuXOnCWh69uwpK1euzNI5EnAAABDDTp06JQ8++KD84x//kCuuuMK//sSJE/L666/LxIkT5ZZbbpEGDRrI7NmzTWCxadMms89HH30kX331lfzzn/+UevXqSbt27eTpp5+WqVOnmiBETZ8+XapVqyYTJkyQWrVqSb9+/eSuu+6SSZMmZek8CTgAAHCAz4p3ZFEnT54MWs6fPy+haJOJZiBat24dtH7btm2SmpoatL5mzZpSuXJl2bhxo3msP+vWrStly5b179O2bVvzmrt37/bvk/7Yuo99jMwi4AAAIMqaVCpVqiTFixf3L2PHjs3wNefNmyfbt2/PcPvhw4clf/78UqJEiaD1GlzoNnufwGDD3m5vC7ePBiVnz57N9PtDt1gAAKLMwYMHpVixYv7HWqyZ0T79+/eXVatWSYECBSTakeEAAMABPgd6qvj+dywNNgKXjAIObTI5evSo6T2SN29es2hh6EsvvWT+rVkIrcP49ddfg56nvVTKlStn/q0/0/dasR9fah89r4IFC2b6/SHgAADAwYG/Il0y69Zbb5Vdu3aZniP20rBhQ1NAav87X758snr1av9z9u7da7rBNm3a1DzWn3oMDVxsmjHR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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhwAAAHHCAYAAAD074ENAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAS/JJREFUeJzt3QuczPX++PH3WvfLkuSWdYlyt0K5VC4l63IcTjoVhUqKQyVC+juIE0WSSuQoqkMuFRVyj3LPrVDtiZRVWApryWLn+3+8P53v/GbW7tgx39mdmX09e3wfa2Y+853vd2a373ven/fn84myLMsSAACAIMoTzJ0DAAAQcAAAgGxBhgMAAAQdAQcAAAg6Ag4AABB0BBwAACDoCDgAAEDQEXAAAICgI+AAAABBR8AB5AITJkyQ6667TqKjo6V+/fqO7//BBx+UypUrO77fcLV27VqJiooyPwH8iYADOW737t1y9913S6VKlaRgwYJy7bXXyp133imvvfaaV7uxY8fKokWLJBylpaXJzJkzpWXLllKyZEkpUKCAuUA/9NBDsm3btqC+9ooVK2TIkCFyyy23mGPQ9zFS/PTTT+bCrtu//vWvDNvcf//95vGiRYte0WvMmTNHXnnllQCPFEAUa6kgJ23cuFFatWolFStWlJ49e0rZsmUlMTFRNm/eLPv375d9+/a52+oFQwOTWbNmSTj5448/5K677pJly5ZJ8+bNpWPHjibo0Ivl/Pnz5b///a8cPHhQKlSoEJTXf+aZZ0yGQ48jf/78QXmNCxcuiMvlMoFUdtL3sEqVKiZQ1QzO3r17vR4/c+aMlClTxgR8mt1JSUnx+zX+8pe/yJ49e8xrZZW+F+fPnzfvd548fK8DVF7eBuSk559/XooXLy5fffWVlChRwuuxpKSkK96vXmiKFCkioWDw4MEm2Jg0aZIMGDDA67GRI0ea+4NJ38dChQoFLdhQ+fLlk5zUvn17+eijj+Trr7+WuLg49/0ff/yxufC3bdtW1qxZE/TjOHfunDvI0CAIwP8h9EaO0ixG7dq1Lwk2VOnSpd3/1pS4BhHvvPOOO4WudQNq1KhR5va3334r3bp1k6uuukpuvfVW93P/85//SMOGDc1FVzML9913n8miePrhhx+kS5cuJsOiFwrNNmi7U6dOudusXLnS7FePVbMt1atXl2effdbn+R06dEjefPNN00WUPthQ+q376aef9spu7Ny5U9q1aycxMTHmde644w6T8fGkWR495w0bNsjAgQPlmmuuMQHW3/72Nzl27JjX+6bdKPre2e+bPtfuisgoW6T363tqO336tDl27QLSDIZ+Lno+O3bs8FnDoa85aNAgiY2NNc/T9+ull16S9AtU6+v179/fdJfVqVPHtNXfCQ3Ssqpp06Ym06HdH55mz55tgg393NPTYKRDhw5Svnx585pVq1aVMWPGmGyITbvAlixZIj///LP7/bPP067TmDt3rgwfPtx0BRYuXFiSk5MvqeH47rvvzO9fjx49vI5h/fr15ndg6NChWT5XIFyR4UCO0rqNTZs2mZS1Xmwy895778kjjzwiN998szz66KPmPr1AePr73/8u119/valRsC9qmkH55z//Kffcc495vl6MtTZEuzb0wq7Bg34Djo+Pl9TUVHn88cdN0PHLL7/I4sWL5eTJkyYDo6l6Ta3Xq1dPRo8ebS5Q2t2jF3xfPvvsM7l48aJ07949S++Hvs5tt91mgg2tu9DMgQYseuFbt26dNG7c2Ku9Hq8GWJop0SBCaw304j1v3jz3+zZ9+nTZunWrzJgxw9zXrFkz8UefPn3kgw8+MPutVauW/Pbbb+ZCqRfRBg0aZPgcff//+te/yueffy69evUyharLly832R59b9NndXR/mqH4xz/+IcWKFZNXX33VBIDa1XT11Vdn6Ti7du1qgssXXnjBXOyPHz9u6lf0PcgoeNFgSwM6Ddj0p2ZARowYYQIG7YJS/+///T8TdGrgaB9z+loQDVI0q6GBo/4OZZRJqlmzpmmn56/dgvreaECmgVqNGjXM7xQQ8bSGA8gpK1assKKjo83WtGlTa8iQIdby5cut8+fPX9K2SJEiVs+ePS+5f+TIkRpdWF27dvW6/6effjL7ff75573u3717t5U3b173/Tt37jTPX7BgQabHOWnSJNPm2LFjfp3fU089ZZ6nr5EVnTt3tvLnz2/t37/ffd+vv/5qFStWzGrevLn7vpkzZ5r9tm7d2nK5XF6vp+d88uRJ9336nul75+nAgQPm+bqf9PR+fU9txYsXt/r16+fzuPU1KlWq5L69aNEis59//etfXu3uvvtuKyoqytq3b5/X6+k5e9739ddfm/tfe+01n69rn8eECROsPXv2mH9/+eWX5rEpU6ZYRYsW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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "from sklearn.metrics import mean_absolute_error\n",
+ "from sklearn.metrics import mean_squared_error\n",
+ "from sklearn.metrics import r2_score\n",
+ "from sklearn.metrics import accuracy_score\n",
+ "from sklearn.metrics import confusion_matrix\n",
+ "\n",
+ "print(\"===== MODEL EVALUATION =====\\n\")\n",
+ "\n",
+ "# Predictions\n",
+ "y_pred = model_r.predict(X_test_r)\n",
+ "\n",
+ "####################################\n",
+ "# 1️⃣ Regression Metrics\n",
+ "####################################\n",
+ "\n",
+ "mae = mean_absolute_error(y_test_r, y_pred)\n",
+ "rmse = np.sqrt(mean_squared_error(y_test_r, y_pred))\n",
+ "r2 = r2_score(y_test_r, y_pred)\n",
+ "\n",
+ "print(\"Regression Metrics:\\n\")\n",
+ "\n",
+ "print(\"MAE =\", mae)\n",
+ "print(\"RMSE =\", rmse)\n",
+ "print(\"R2 =\", r2)\n",
+ "\n",
+ "####################################\n",
+ "# 2️⃣ Convert to Levels\n",
+ "####################################\n",
+ "\n",
+ "def level(x):\n",
+ " if x < 0.33:\n",
+ " return 0\n",
+ " elif x < 0.66:\n",
+ " return 1\n",
+ " else:\n",
+ " return 2\n",
+ "\n",
+ "\n",
+ "y_true_levels = np.array([[level(v) for v in row] for row in y_test_r])\n",
+ "y_pred_levels = np.array([[level(v) for v in row] for row in y_pred])\n",
+ "\n",
+ "####################################\n",
+ "# 3️⃣ Accuracy\n",
+ "####################################\n",
+ "\n",
+ "acc_dep = accuracy_score(y_true_levels[:,0], y_pred_levels[:,0])\n",
+ "acc_anx = accuracy_score(y_true_levels[:,1], y_pred_levels[:,1])\n",
+ "acc_str = accuracy_score(y_true_levels[:,2], y_pred_levels[:,2])\n",
+ "\n",
+ "print(\"\\nAccuracy:\\n\")\n",
+ "\n",
+ "print(\"Depression Accuracy =\", acc_dep)\n",
+ "print(\"Anxiety Accuracy =\", acc_anx)\n",
+ "print(\"Stress Accuracy =\", acc_str)\n",
+ "\n",
+ "####################################\n",
+ "# 4️⃣ Confusion Matrix\n",
+ "####################################\n",
+ "\n",
+ "cm_dep = confusion_matrix(y_true_levels[:,0], y_pred_levels[:,0])\n",
+ "cm_anx = confusion_matrix(y_true_levels[:,1], y_pred_levels[:,1])\n",
+ "cm_str = confusion_matrix(y_true_levels[:,2], y_pred_levels[:,2])\n",
+ "\n",
+ "print(\"\\nConfusion Matrices:\\n\")\n",
+ "\n",
+ "print(\"Depression:\\n\", cm_dep)\n",
+ "print(\"\\nAnxiety:\\n\", cm_anx)\n",
+ "print(\"\\nStress:\\n\", cm_str)\n",
+ "\n",
+ "####################################\n",
+ "# 5️⃣ Plot Confusion Matrix\n",
+ "####################################\n",
+ "\n",
+ "plt.figure()\n",
+ "plt.imshow(cm_dep)\n",
+ "plt.title(\"Depression Confusion Matrix\")\n",
+ "plt.xlabel(\"Predicted\")\n",
+ "plt.ylabel(\"Actual\")\n",
+ "plt.colorbar()\n",
+ "plt.show()\n",
+ "\n",
+ "plt.figure()\n",
+ "plt.imshow(cm_anx)\n",
+ "plt.title(\"Anxiety Confusion Matrix\")\n",
+ "plt.xlabel(\"Predicted\")\n",
+ "plt.ylabel(\"Actual\")\n",
+ "plt.colorbar()\n",
+ "plt.show()\n",
+ "\n",
+ "plt.figure()\n",
+ "plt.imshow(cm_str)\n",
+ "plt.title(\"Stress Confusion Matrix\")\n",
+ "plt.xlabel(\"Predicted\")\n",
+ "plt.ylabel(\"Actual\")\n",
+ "plt.colorbar()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "dd1a94f4-d579-4d26-b413-dbe42bf9b799",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.19"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/History b/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/History
new file mode 100644
index 0000000000000000000000000000000000000000..46bfb67d7a4defe714194092b8549715e375da1b
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/History
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:18bb7fac167630752b1cfa38fdbd37883c97701d67639db61141b814498b3388
+size 163840
diff --git a/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/Web Data b/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/Web Data
new file mode 100644
index 0000000000000000000000000000000000000000..26a6944507a4bfcfaa63e79599510b3a2bc2c2b6
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/Web Data
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3743dd646541935eebc92ec44dc065a71a5beefd8165facae2a5a73eeb6ae656
+size 157696
diff --git a/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log b/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log
new file mode 100644
index 0000000000000000000000000000000000000000..8669d1b19b76c715c1ca9c34a57353bf6af20be8
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/shared_proto_db/000003.log
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:224b7af78f931fbc5e380e4970816885ce968e38da0eb46f510b4a661f7b55db
+size 111699
diff --git a/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb b/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb
new file mode 100644
index 0000000000000000000000000000000000000000..39c9d5d4df9acafb6c0629251c63786a90123761
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/.dart_tool/chrome-device/Default/trusted_vault.pb
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b87bf305aafae1f1ec7dd947176c9529b2a9cbd4a3bf296fce25fc009e725366
+size 84
diff --git a/temp_space/clean_git_repo/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill b/temp_space/clean_git_repo/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
new file mode 100644
index 0000000000000000000000000000000000000000..9dbf20fbb73c80ab708d144f6ce9bc0b96d6dd9f
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/build/8730b13ca0249799964d0a71255a8f3b.cache.dill.track.dill
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae0b1b0e267ea854918ca7afbf3c5be6a073deae0894ad6ad67ffd9f78b46c7a
+size 41863640
diff --git a/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/AssetManifest.bin b/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/AssetManifest.bin
new file mode 100644
index 0000000000000000000000000000000000000000..1811cbdd65eaf822a27ec3cb6c1f26a069e55a89
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/AssetManifest.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:00af55ad3d6f21898fe77e0ff092d1a1cda52c941b6860e9928d45c8af8c095d
+size 117
diff --git a/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf b/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf
new file mode 100644
index 0000000000000000000000000000000000000000..0e72af0d1c2d8662f7be287eb6d27210edbbfa1f
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/fonts/MaterialIcons-Regular.otf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d9865b671a09d683d13a863089d8825e0f61a37696ce5d7d448bc8023aa62453
+size 1645184
diff --git a/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf b/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..e98baa9f284d21d1e6d3837523e5d879e73dca86
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/build/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:67c44fe9183b002e79dde7f6977e2988661c9a3e4a3c5fce968787efdbed823c
+size 257628
diff --git a/temp_space/clean_git_repo/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/temp_space/clean_git_repo/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
new file mode 100644
index 0000000000000000000000000000000000000000..0066c008ba292c746ef170676f5643de1742f589
--- /dev/null
+++ b/temp_space/clean_git_repo/UI/safespace/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6232e5815af17e25e0268b2fec7aea9e068cc92ec709e9605c2b31df4ff2a313
+size 102994
diff --git a/temp_space/clean_git_repo/data.csv b/temp_space/clean_git_repo/data.csv
new file mode 100644
index 0000000000000000000000000000000000000000..0847e02e19d0c56ffac0e1c3a236b920fc543bee
--- /dev/null
+++ b/temp_space/clean_git_repo/data.csv
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d6b39f44704ef71efab7fb6223ffaa68bc84af9c7c42875310c043242dac593d
+size 20819959
diff --git a/temp_space/clean_git_repo/mental_model.h5 b/temp_space/clean_git_repo/mental_model.h5
new file mode 100644
index 0000000000000000000000000000000000000000..693a1c764002481b5135c428003eaf8eb872d8f0
--- /dev/null
+++ b/temp_space/clean_git_repo/mental_model.h5
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d83c61efe6d2ff698925835f970cce7d65026107d6adcbe8eb31b58ed1ac4325
+size 259632
diff --git a/temp_space/clean_git_repo/mental_xlmr_final/label_encoder.pkl b/temp_space/clean_git_repo/mental_xlmr_final/label_encoder.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..16a91edce0554ab569252f4a5ab2b709edf178b9
--- /dev/null
+++ b/temp_space/clean_git_repo/mental_xlmr_final/label_encoder.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7459c4d557907ee7efd7151ef3618a1a47b74750e839c56c50d450f6a2553c20
+size 275
diff --git a/temp_space/clean_git_repo/mental_xlmr_final/tokenizer.json b/temp_space/clean_git_repo/mental_xlmr_final/tokenizer.json
new file mode 100644
index 0000000000000000000000000000000000000000..b4f6f590cde1393c600866cd86431644f2acbae0
--- /dev/null
+++ b/temp_space/clean_git_repo/mental_xlmr_final/tokenizer.json
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:542cda5f12d1c653dd46ac4d8c992d71e0047e65e7bf2cdda17c2d43b1d94b37
+size 17781767
diff --git a/temp_space/clean_git_repo/mental_xlmr_final/training_args.bin b/temp_space/clean_git_repo/mental_xlmr_final/training_args.bin
new file mode 100644
index 0000000000000000000000000000000000000000..6c71739c0891e0e9a564ade3b6560d7e6ed26905
--- /dev/null
+++ b/temp_space/clean_git_repo/mental_xlmr_final/training_args.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d487b97c54aa8b5c1582f059ef3c809014c6d48eabd7a6c0be396fc96cf835f2
+size 5201
diff --git a/temp_space/clean_git_repo/model_weights.pkl b/temp_space/clean_git_repo/model_weights.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..13e811fccdc58b055dd08dc019eb889377c128a3
--- /dev/null
+++ b/temp_space/clean_git_repo/model_weights.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c7f5e42ca4cda8a43af36c8b72b4ac1dfe500fbab6c7359d26c1eaa9048b37f7
+size 68153
diff --git a/temp_space/clean_git_repo/scaler.pkl b/temp_space/clean_git_repo/scaler.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..448673ece4b713d1a799c2afb888346fc35d1e59
--- /dev/null
+++ b/temp_space/clean_git_repo/scaler.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fe630eaf06688d9090bba2e118657f64d1fbdf3506175f640cf4990effbfdb22
+size 1467
diff --git a/temp_space/data.csv b/temp_space/data.csv
new file mode 100644
index 0000000000000000000000000000000000000000..0847e02e19d0c56ffac0e1c3a236b920fc543bee
--- /dev/null
+++ b/temp_space/data.csv
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d6b39f44704ef71efab7fb6223ffaa68bc84af9c7c42875310c043242dac593d
+size 20819959
diff --git a/temp_space/mental_model.h5 b/temp_space/mental_model.h5
new file mode 100644
index 0000000000000000000000000000000000000000..693a1c764002481b5135c428003eaf8eb872d8f0
--- /dev/null
+++ b/temp_space/mental_model.h5
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d83c61efe6d2ff698925835f970cce7d65026107d6adcbe8eb31b58ed1ac4325
+size 259632
diff --git a/temp_space/mental_xlmr_final/label_encoder.pkl b/temp_space/mental_xlmr_final/label_encoder.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..16a91edce0554ab569252f4a5ab2b709edf178b9
--- /dev/null
+++ b/temp_space/mental_xlmr_final/label_encoder.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7459c4d557907ee7efd7151ef3618a1a47b74750e839c56c50d450f6a2553c20
+size 275
diff --git a/temp_space/mental_xlmr_final/tokenizer.json b/temp_space/mental_xlmr_final/tokenizer.json
new file mode 100644
index 0000000000000000000000000000000000000000..b4f6f590cde1393c600866cd86431644f2acbae0
--- /dev/null
+++ b/temp_space/mental_xlmr_final/tokenizer.json
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:542cda5f12d1c653dd46ac4d8c992d71e0047e65e7bf2cdda17c2d43b1d94b37
+size 17781767
diff --git a/temp_space/mental_xlmr_final/training_args.bin b/temp_space/mental_xlmr_final/training_args.bin
new file mode 100644
index 0000000000000000000000000000000000000000..6c71739c0891e0e9a564ade3b6560d7e6ed26905
--- /dev/null
+++ b/temp_space/mental_xlmr_final/training_args.bin
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d487b97c54aa8b5c1582f059ef3c809014c6d48eabd7a6c0be396fc96cf835f2
+size 5201
diff --git a/temp_space/model_weights.pkl b/temp_space/model_weights.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..13e811fccdc58b055dd08dc019eb889377c128a3
--- /dev/null
+++ b/temp_space/model_weights.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c7f5e42ca4cda8a43af36c8b72b4ac1dfe500fbab6c7359d26c1eaa9048b37f7
+size 68153
diff --git a/temp_space/recommendations.py b/temp_space/recommendations.py
new file mode 100644
index 0000000000000000000000000000000000000000..c1658d58ecabf8bade53aede7d93cf57f55269d0
--- /dev/null
+++ b/temp_space/recommendations.py
@@ -0,0 +1,564 @@
+"""
+recommendations.py
+==================
+Bilingual (EN + AR) recommendation system.
+Uses:
+ - primary disease (anxiety / depression / stress)
+ - severity (mild / moderate / severe) from DASS-42 scores
+ - cause (extracted from user text)
+ - suicidal flag (extracted from user text)
+"""
+
+import re
+
+# ══════════════════════════════════════════════════════════════════════════════
+# 1. SEVERITY FROM DASS-42 SCORES
+# ══════════════════════════════════════════════════════════════════════════════
+# DASS-42 official cutoffs (raw sum, not percentage)
+DASS_CUTOFFS = {
+ "depression": [(0, 9, "normal"), (10, 13, "mild"), (14, 20, "moderate"),
+ (21, 27, "severe"), (28, 999, "extremely_severe")],
+ "anxiety": [(0, 7, "normal"), (8, 9, "mild"), (10, 14, "moderate"),
+ (15, 19, "severe"), (20, 999, "extremely_severe")],
+ "stress": [(0, 14, "normal"),(15, 18, "mild"),(19, 25, "moderate"),
+ (26, 33, "severe"), (34, 999, "extremely_severe")],
+}
+
+def get_severity(disease: str, raw_score: float, max_score: float = 1.0) -> str:
+ """
+ raw_score: إما نسبة (0-1) من الموديل، وإما raw DASS score
+ بنحوّل النسبة لـ raw score تقريبي عشان نقدر نستخدم الـ cutoffs
+ """
+ # لو جاي من الموديل كنسبة (0-1)، نحوّله لـ raw score تقريبي
+ if max_score == 1.0:
+ # DASS-42 depression max=84, anxiety max=72, stress max=84
+ max_raw = {"depression": 84, "anxiety": 72, "stress": 84}
+ score = int(raw_score * max_raw.get(disease, 84))
+ else:
+ score = int(raw_score)
+
+ for low, high, label in DASS_CUTOFFS.get(disease, []):
+ if low <= score <= high:
+ return label
+ return "severe"
+
+
+# ══════════════════════════════════════════════════════════════════════════════
+# 2. CAUSE EXTRACTION FROM TEXT
+# ══════════════════════════════════════════════════════════════════════════════
+CAUSE_KEYWORDS = {
+ "work": [
+ "شغل", "عمل", "وظيفة", "مدير", "boss", "deadline", "مشروع", "project",
+ "office", "مكتب", "راتب", "salary", "overtime", "job", "work", "career",
+ "كثير شغل", "ضغط شغل", "مش قادر أكمل شغل", "tired from work",
+ ],
+ "relationships": [
+ "حبيب", "حبيبة", "زوج", "زوجة", "جوز", "مراتي", "علاقة", "relationship",
+ "أهل", "عيلة", "family", "صاحب", "صحاب", "friend", "خيانة", "betrayal",
+ "فراق", "breakup", "طلاق", "divorce", "وحيد", "lonely", "خلاف", "conflict",
+ ],
+ "financial": [
+ "فلوس", "مال", "money", "دين", "debt", "فقر", "مصاريف", "broke",
+ "إيجار", "rent", "مديون", "financial", "بطالة", "unemployment",
+ ],
+ "academic": [
+ "دراسة", "امتحان", "exam", "جامعة", "university", "مدرسة", "school",
+ "درجات", "grades", "رسوب", "fail", "مذاكرة", "study", "تخرج",
+ ],
+ "health": [
+ "مرض", "وجع", "pain", "صحة", "health", "doctor", "دكتور", "مستشفى",
+ "hospital", "علاج", "treatment", "دواء", "medication", "نوم", "sleep",
+ ],
+ "social": [
+ "ناس", "people", "مجتمع", "حكم", "judgment", "خجل", "shy", "منعزل",
+ "isolated", "خايف", "scared", "مش قادر أتكلم", "can't talk",
+ ],
+ "self_worth": [
+ "فاشل", "failure", "مش كافي", "not enough", "ضعيف", "weak", "worthless",
+ "لا قيمة", "ما ينفعش", "مش عارف أنجح", "can't succeed", "loser",
+ ],
+ "trauma": [
+ "صدمة", "trauma", "حادثة", "accident", "خسارة", "loss", "وفاة", "death",
+ "مات", "died", "إساءة", "abuse", "كوابيس", "nightmares", "ذكريات",
+ ],
+}
+
+def extract_cause(text: str) -> str:
+ text_lower = text.lower()
+ text_lower = re.sub(r'[^\w\s\u0600-\u06FF]', ' ', text_lower)
+ scores = {}
+ for cause, keywords in CAUSE_KEYWORDS.items():
+ count = sum(1 for kw in keywords if kw.lower() in text_lower)
+ if count > 0:
+ scores[cause] = count
+ if not scores:
+ return "general"
+ return max(scores, key=scores.get)
+
+
+# ══════════════════════════════════════════════════════════════════════════════
+# 3. SUICIDAL IDEATION DETECTION
+# ══════════════════════════════════════════════════════════════════════════════
+SUICIDAL_KEYWORDS = [
+ "انتحار", "suicide", "أقتل نفسي", "kill myself", "أموت", "want to die",
+ "عايز أموت", "مش عايز أعيش", "don't want to live", "نهاية حياتي",
+ "end my life", "أريح نفسي", "rest forever", "مفيش فايدة من الحياة",
+ "life is not worth", "أذي نفسي", "hurt myself", "إيذاء النفس",
+ "self harm", "مش قادر أكمل", "can't go on", "عايز أختفي",
+ "want to disappear", "لو مت", "if i die", "لو اختفيت",
+]
+
+def detect_suicidal(text: str) -> bool:
+ text_lower = text.lower()
+ return any(kw.lower() in text_lower for kw in SUICIDAL_KEYWORDS)
+
+
+# ══════════════════════════════════════════════════════════════════════════════
+# 4. RECOMMENDATIONS DATABASE (Bilingual)
+# ══════════════════════════════════════════════════════════════════════════════
+
+# Structure: disease → cause → severity_group → {tips, resources, referral}
+# severity_group: "mild_moderate" | "severe"
+
+REC_DB = {
+
+ # ── ANXIETY ───────────────────────────────────────────────────────────────
+ "anxiety": {
+ "work": {
+ "mild_moderate": {
+ "tips_en": [
+ "Break your tasks into small steps and focus on one at a time",
+ "Take a 5-minute breathing break every hour",
+ "Communicate your workload clearly with your manager",
+ "Set clear boundaries between work time and rest time",
+ ],
+ "tips_ar": [
+ "قسّم مهامك لخطوات صغيرة وركز على خطوة واحدة في كل مرة",
+ "خذ استراحة تنفس 5 دقائق كل ساعة",
+ "تحدث بوضوح مع مديرك عن حجم عملك",
+ "حدد حدوداً واضحة بين وقت العمل والراحة",
+ ],
+ "resources_en": ["App: Calm or Headspace for quick work breaks",
+ "Technique: 4-7-8 breathing (inhale 4s, hold 7s, exhale 8s)"],
+ "resources_ar": ["تطبيق: Calm أو Headspace لفترات الراحة السريعة",
+ "تقنية: التنفس 4-7-8 (استنشق 4 ثواني، احبس 7، اطرد 8)"],
+ "referral_en": "If work anxiety persists for more than 2 weeks, consider speaking with a mental health professional.",
+ "referral_ar": "لو قلق العمل مستمر أكثر من أسبوعين، فكّر في التحدث مع متخصص نفسي.",
+ },
+ "severe": {
+ "tips_en": [
+ "Consider taking a short leave if possible — your mental health comes first",
+ "Talk to HR or a trusted colleague about your situation",
+ "Avoid making major work decisions when anxiety is high",
+ ],
+ "tips_ar": [
+ "فكّر في أخذ إجازة قصيرة لو ممكن — صحتك النفسية أولاً",
+ "تحدث مع قسم الموارد البشرية أو زميل موثوق عن وضعك",
+ "تجنب اتخاذ قرارات عمل كبيرة في وقت القلق الشديد",
+ ],
+ "resources_en": ["Cognitive Behavioral Therapy (CBT) is highly effective for work anxiety",
+ "Book: 'Anxiety at Work' by Adrian Gostick"],
+ "resources_ar": ["العلاج المعرفي السلوكي (CBT) فعّال جداً لقلق العمل",
+ "كتاب: 'Anxiety at Work' لـ Adrian Gostick"],
+ "referral_en": "Severe work-related anxiety requires professional support. Please consult a therapist or psychiatrist.",
+ "referral_ar": "قلق العمل الشديد يحتاج دعماً متخصصاً. من فضلك استشر معالجاً نفسياً أو طبيباً نفسياً.",
+ },
+ },
+ "relationships": {
+ "mild_moderate": {
+ "tips_en": [
+ "Express your feelings calmly using 'I feel...' statements",
+ "Set healthy boundaries in your relationships",
+ "Don't try to solve everything at once",
+ ],
+ "tips_ar": [
+ "عبّر عن مشاعرك بهدوء باستخدام عبارات 'أنا أشعر...'",
+ "حدد حدوداً صحية في علاقاتك",
+ "لا تحاول حل كل شيء دفعة واحدة",
+ ],
+ "resources_en": ["Book: 'Attached' by Amir Levine — understanding relationship patterns",
+ "Couples or individual counseling can help significantly"],
+ "resources_ar": ["كتاب: 'Attached' لـ Amir Levine — لفهم أنماط العلاقات",
+ "الإرشاد الفردي أو للأزواج بيساعد كتير"],
+ "referral_en": "If relationship anxiety is affecting your sleep or daily function, a therapist can help.",
+ "referral_ar": "لو قلق العلاقات بيأثر على نومك أو حياتك اليومية، معالج نفسي يقدر يساعد.",
+ },
+ "severe": {
+ "tips_en": [
+ "Create some distance if the relationship is causing constant distress",
+ "Reach out to a trusted family member or friend for support",
+ "Journaling your feelings daily can help process the anxiety",
+ ],
+ "tips_ar": [
+ "خلق مسافة مؤقتة لو العلاقة بتسبب ضيقاً مستمراً",
+ "تواصل مع فرد من العائلة أو صديق موثوق للدعم",
+ "كتابة مشاعرك يومياً في دفتر بيساعد على معالجة القلق",
+ ],
+ "resources_en": ["CBT or DBT therapy is recommended for severe relationship anxiety"],
+ "resources_ar": ["العلاج المعرفي السلوكي أو DBT موصى به لقلق العلاقات الشديد"],
+ "referral_en": "Please consult a mental health professional. Severe relationship anxiety is treatable.",
+ "referral_ar": "من فضلك استشر متخصصاً نفسياً. قلق العلاقات الشديد قابل للعلاج.",
+ },
+ },
+ "general": {
+ "mild_moderate": {
+ "tips_en": [
+ "Practice 4-7-8 breathing daily",
+ "Reduce caffeine intake — it worsens anxiety",
+ "Exercise for at least 20 minutes a day",
+ "Limit news and social media consumption",
+ ],
+ "tips_ar": [
+ "مارس تنفس 4-7-8 يومياً",
+ "قلل الكافيين — بيزيد القلق",
+ "مارس الرياضة 20 دقيقة على الأقل يومياً",
+ "قلل استهلاك الأخبار ووسائل التواصل الاجتماعي",
+ ],
+ "resources_en": ["App: Calm or Insight Timer",
+ "Book: 'Dare' by Barry McDonagh",
+ "YouTube: Progressive Muscle Relaxation guided sessions"],
+ "resources_ar": ["تطبيق: Calm أو Insight Timer",
+ "كتاب: 'Dare' لـ Barry McDonagh",
+ "YouTube: جلسات Progressive Muscle Relaxation موجّهة"],
+ "referral_en": "If anxiety persists for more than 2 weeks, consider speaking with a professional.",
+ "referral_ar": "لو القلق مستمر أكثر من أسبوعين، فكّر في التحدث مع متخصص.",
+ },
+ "severe": {
+ "tips_en": [
+ "Do not isolate yourself — stay connected with safe people",
+ "Try grounding: name 5 things you see, 4 you hear, 3 you touch",
+ "Avoid making big decisions when anxiety peaks",
+ ],
+ "tips_ar": [
+ "لا تعزل نفسك — ابقَ على تواصل مع الناس الآمنين",
+ "جرب تقنية التأريض: اذكر 5 أشياء تراها، 4 تسمعها، 3 تلمسها",
+ "تجنب اتخاذ قرارات كبيرة في وقت ذروة القلق",
+ ],
+ "resources_en": ["CBT is the gold standard for severe anxiety",
+ "Medication may help — consult a psychiatrist"],
+ "resources_ar": ["CBT هو المعيار الذهبي لعلاج القلق الشديد",
+ "الدواء قد يساعد — استشر طبيباً نفسياً"],
+ "referral_en": "Severe anxiety requires professional treatment. Please reach out to a therapist or psychiatrist soon.",
+ "referral_ar": "القلق الشديد يحتاج علاجاً متخصصاً. من فضلك تواصل مع معالج نفسي أو طبيب نفسي في أقرب وقت.",
+ },
+ },
+ },
+
+ # ── DEPRESSION ────────────────────────────────────────────────────────────
+ "depression": {
+ "work": {
+ "mild_moderate": {
+ "tips_en": [
+ "Try to find one small meaningful task at work each day",
+ "Take short walks outside during your lunch break",
+ "Talk to a trusted colleague — connection helps",
+ ],
+ "tips_ar": [
+ "حاول تلاقي مهمة صغيرة ذات معنى في العمل كل يوم",
+ "اخرج في نزهة قصيرة أثناء استراحة الغداء",
+ "تحدث مع زميل موثوق — التواصل بيساعد",
+ ],
+ "resources_en": ["Book: 'Lost Connections' by Johann Hari",
+ "Technique: Behavioral Activation — schedule small enjoyable activities"],
+ "resources_ar": ["كتاب: 'Lost Connections' لـ Johann Hari",
+ "تقنية: التنشيط السلوكي — جدوّل أنشطة صغيرة ممتعة"],
+ "referral_en": "Work-related depression responds well to therapy. Consider reaching out to a professional.",
+ "referral_ar": "الاكتئاب المرتبط بالعمل يستجيب جيداً للعلاج. فكّر في التواصل مع متخصص.",
+ },
+ "severe": {
+ "tips_en": [
+ "Take medical leave if possible — you need recovery time",
+ "Maintain a basic daily routine even if it feels hard",
+ "Tell one trusted person how you truly feel",
+ ],
+ "tips_ar": [
+ "خذ إجازة طبية لو ممكن — تحتاج وقتاً للتعافي",
+ "حافظ على روتين يومي أساسي حتى لو صعب",
+ "أخبر شخصاً موثوقاً واحداً بمشاعرك الحقيقية",
+ ],
+ "resources_en": ["Antidepressants combined with therapy show strong results",
+ "Contact a psychiatrist as soon as possible"],
+ "resources_ar": ["مضادات الاكتئاب مع العلاج النفسي بتعطي نتائج قوية",
+ "تواصل مع طبيب نفسي في أقرب وقت ممكن"],
+ "referral_en": "Severe depression is a medical condition. Please see a psychiatrist urgently.",
+ "referral_ar": "الاكتئاب الشديد حالة طبية. من فضلك راجع طبيباً نفسياً بشكل عاجل.",
+ },
+ },
+ "self_worth": {
+ "mild_moderate": {
+ "tips_en": [
+ "Write 3 things you did well today — no matter how small",
+ "The critical voice in your head is not the truth",
+ "Treat yourself with the same kindness you'd give a friend",
+ ],
+ "tips_ar": [
+ "اكتب 3 أشياء قمت بها بشكل جيد اليوم — مهما كانت صغيرة",
+ "الصوت الناقد في رأسك ليس الحقيقة",
+ "تعامل مع نفسك بنفس اللطف الذي تعطيه لصديق",
+ ],
+ "resources_en": ["Book: 'Feeling Good' by David Burns",
+ "Book: 'Self-Compassion' by Kristin Neff"],
+ "resources_ar": ["كتاب: 'Feeling Good' لـ David Burns",
+ "كتاب: 'Self-Compassion' لـ Kristin Neff"],
+ "referral_en": "Low self-worth with depression responds very well to CBT therapy.",
+ "referral_ar": "ضعف الثقة مع الاكتئاب يستجيب جيداً جداً للعلاج المعرفي السلوكي.",
+ },
+ "severe": {
+ "tips_en": [
+ "You are not your worst thoughts — please reach out for help",
+ "Start with one tiny act of self-care today",
+ "Connect with someone safe right now",
+ ],
+ "tips_ar": [
+ "أنت لست أفكارك السيئة — من فضلك اطلب المساعدة",
+ "ابدأ بفعل صغير جداً من الرعاية الذاتية اليوم",
+ "تواصل مع شخص آمن الآن",
+ ],
+ "resources_en": ["Urgent: Please contact a mental health professional",
+ "CBT and medication together are very effective"],
+ "resources_ar": ["عاجل: من فضلك تواصل مع متخصص نفسي",
+ "العلاج المعرفي السلوكي والدواء معاً فعّالان جداً"],
+ "referral_en": "Please seek professional help immediately. You deserve support and recovery.",
+ "referral_ar": "من فضلك اطلب مساعدة متخصصة فوراً. أنت تستحق الدعم والتعافي.",
+ },
+ },
+ "general": {
+ "mild_moderate": {
+ "tips_en": [
+ "Maintain a consistent daily routine",
+ "Get 15 minutes of sunlight every day — it genuinely helps",
+ "Light exercise (a 30-minute walk) is clinically proven to reduce mild depression",
+ "Connect with at least one person daily",
+ ],
+ "tips_ar": [
+ "حافظ على روتين يومي ثابت",
+ "احصل على 15 دقيقة من أشعة الشمس كل يوم — بيساعد فعلاً",
+ "الرياضة الخفيفة (مشي 30 دقيقة) ثبت علمياً إنها بتقلل الاكتئاب الخفيف",
+ "تواصل مع شخص واحد على الأقل يومياً",
+ ],
+ "resources_en": ["App: Woebot for daily mental health support",
+ "Book: 'The Depression Cure' by Stephen Ilardi",
+ "Book: 'Feeling Good' by David Burns"],
+ "resources_ar": ["تطبيق: Woebot للدعم النفسي اليومي",
+ "كتاب: 'The Depression Cure' لـ Stephen Ilardi",
+ "كتاب: 'Feeling Good' لـ David Burns"],
+ "referral_en": "If symptoms persist more than 2 weeks, please speak with a doctor or therapist.",
+ "referral_ar": "لو الأعراض مستمرة أكثر من أسبوعين، من فضلك تحدث مع طبيب أو معالج.",
+ },
+ "severe": {
+ "tips_en": [
+ "Do not be alone — stay with safe people",
+ "Focus only on the next hour, not the whole day",
+ "Even getting out of bed is an achievement today",
+ ],
+ "tips_ar": [
+ "لا تكن وحدك — ابقَ مع أشخاص آمنين",
+ "ركز على الساعة القادمة فقط، ليس اليوم كله",
+ "حتى النهوض من السرير إنجاز اليوم",
+ ],
+ "resources_en": ["Combination of therapy and medication is most effective for severe depression",
+ "Please contact a psychiatrist as soon as possible"],
+ "resources_ar": ["مزيج العلاج النفسي والدواء هو الأكثر فعالية للاكتئاب الشديد",
+ "من فضلك تواصل مع طبيب نفسي في أقرب وقت ممكن"],
+ "referral_en": "Severe depression is a serious medical condition. Please seek help urgently.",
+ "referral_ar": "الاكتئاب الشديد حالة طبية خطيرة. من فضلك اطلب المساعدة بشكل عاجل.",
+ },
+ },
+ },
+
+ # ── STRESS ────────────────────────────────────────────────────────────────
+ "stress": {
+ "work": {
+ "mild_moderate": {
+ "tips_en": [
+ "Use the Pomodoro technique: 25 min work + 5 min break",
+ "Write your top 3 priorities each morning and stick to them",
+ "Learn to say no to extra tasks when overloaded",
+ "Disconnect from work emails after working hours",
+ ],
+ "tips_ar": [
+ "استخدم تقنية Pomodoro: 25 دقيقة عمل + 5 دقائق راحة",
+ "اكتب أهم 3 أولويات كل صباح والتزم بها",
+ "تعلّم قول 'لا' للمهام الإضافية عند الضغط الزائد",
+ "افصل نفسك عن إيميلات العمل بعد ساعات العمل",
+ ],
+ "resources_en": ["App: Todoist or Notion for task management",
+ "Book: 'Deep Work' by Cal Newport"],
+ "resources_ar": ["تطبيق: Todoist أو Notion لإدارة المهام",
+ "كتاب: 'Deep Work' لـ Cal Newport"],
+ "referral_en": "If work stress is causing physical symptoms, consult a doctor.",
+ "referral_ar": "لو ضغط العمل بيسبب أعراضاً جسمانية، استشر طبيباً.",
+ },
+ "severe": {
+ "tips_en": [
+ "You may be experiencing burnout — this is a real medical condition",
+ "Take urgent time off if possible",
+ "Talk to your manager or HR about workload redistribution",
+ ],
+ "tips_ar": [
+ "قد تكون تعاني من الإرهاق الوظيفي (Burnout) — وهذه حالة طبية حقيقية",
+ "خذ إجازة عاجلة لو ممكن",
+ "تحدث مع مديرك أو الموارد البشرية عن إعادة توزيع عبء العمل",
+ ],
+ "resources_en": ["Book: 'Burnout' by Emily Nagoski",
+ "Urgent: Consult an occupational health specialist"],
+ "resources_ar": ["كتاب: 'Burnout' لـ Emily Nagoski",
+ "عاجل: استشر أخصائي الصحة المهنية"],
+ "referral_en": "Severe burnout requires professional support. Please consult a doctor or therapist.",
+ "referral_ar": "الإرهاق الوظيفي الشديد يحتاج دعماً متخصصاً. من فضلك استشر طبيباً أو معالجاً.",
+ },
+ },
+ "academic": {
+ "mild_moderate": {
+ "tips_en": [
+ "Plan your study schedule in advance — avoid last-minute cramming",
+ "Use Active Recall and Spaced Repetition for effective studying",
+ "Sleep is more valuable than all-nighters before exams",
+ ],
+ "tips_ar": [
+ "خطط جدول مذاكرتك مسبقاً — تجنب الدراسة في اللحظة الأخيرة",
+ "استخدم Active Recall وSpaced Repetition للمذاكرة الفعّالة",
+ "النوم أهم من السهر قبل الامتحانات",
+ ],
+ "resources_en": ["App: Anki for Spaced Repetition",
+ "App: Forest to block distractions while studying"],
+ "resources_ar": ["تطبيق: Anki لـ Spaced Repetition",
+ "تطبيق: Forest لمنع التشتيت أثناء المذاكرة"],
+ "referral_en": "If academic stress is severely impacting you, talk to your university counselor.",
+ "referral_ar": "لو ضغط الدراسة بيأثر عليك بشكل كبير، تحدث مع المرشد الأكاديمي في جامعتك.",
+ },
+ "severe": {
+ "tips_en": [
+ "Your worth is not defined by your grades",
+ "Talk to your academic advisor — they can offer real solutions",
+ "Seek your university's mental health support services",
+ ],
+ "tips_ar": [
+ "قيمتك لا تُحدّد بدرجاتك",
+ "تحدث مع مرشدك الأكاديمي — بيقدر يقدم حلولاً حقيقية",
+ "اطلب خدمات الدعم النفسي في جامعتك",
+ ],
+ "resources_en": ["Most universities offer free mental health counseling"],
+ "resources_ar": ["معظم الجامعات تقدم إرشاداً نفسياً مجانياً"],
+ "referral_en": "Please reach out to a counselor or therapist. Academic stress at this level needs support.",
+ "referral_ar": "من فضلك تواصل مع مرشد أو معالج. ضغط الدراسة بهذا المستوى يحتاج دعماً.",
+ },
+ },
+ "general": {
+ "mild_moderate": {
+ "tips_en": [
+ "Exercise for 20 minutes daily — it reduces cortisol significantly",
+ "Write your thoughts in a daily journal",
+ "Focus on what you can control, let go of what you can't",
+ "Schedule genuine rest time — it's not wasted time",
+ ],
+ "tips_ar": [
+ "مارس الرياضة 20 دقيقة يومياً — بيقلل الكورتيزول بشكل ملحوظ",
+ "اكتب أفكارك في دفتر يومي",
+ "ركز على ما تقدر تتحكم فيه، واترك ما لا تقدر",
+ "جدوّل وقت راحة حقيقي — هو مش وقت ضائع",
+ ],
+ "resources_en": ["App: Insight Timer for short meditation sessions",
+ "Book: 'The Stress Solution' by Rangan Chatterjee",
+ "Technique: Progressive Muscle Relaxation before sleep"],
+ "resources_ar": ["تطبيق: Insight Timer لجلسات تأمل قصيرة",
+ "كتاب: 'The Stress Solution' لـ Rangan Chatterjee",
+ "تقنية: Progressive Muscle Relaxation قبل النوم"],
+ "referral_en": "Chronic stress (over 1 month) is worth discussing with a professional.",
+ "referral_ar": "الضغط المزمن (أكثر من شهر) يستحق التحدث عنه مع متخصص.",
+ },
+ "severe": {
+ "tips_en": [
+ "Your body is sending serious signals — please listen to them",
+ "Eliminate one major stressor if possible",
+ "Ask for help — carrying everything alone is not sustainable",
+ ],
+ "tips_ar": [
+ "جسمك يرسل إشارات خطيرة — من فضلك استمع إليها",
+ "أزل مصدر ضغط رئيسي واحد لو ممكن",
+ "اطلب المساعدة — حمل كل شيء وحدك ليس مستداماً",
+ ],
+ "resources_en": ["Severe chronic stress can cause physical illness — see a doctor",
+ "Therapy (CBT or mindfulness-based) is highly effective"],
+ "resources_ar": ["الضغط المزمن الشديد قد يسبب أمراضاً جسدية — راجع طبيباً",
+ "العلاج النفسي (CBT أو القائم على اليقظة الذهنية) فعّال جداً"],
+ "referral_en": "Please consult a doctor or therapist. Severe stress at this level needs professional attention.",
+ "referral_ar": "من فضلك استشر طبيباً أو معالجاً. الضغط الشديد بهذا المستوى يحتاج اهتماماً متخصصاً.",
+ },
+ },
+ },
+}
+
+# Suicidal crisis — overrides everything
+SUICIDAL_REC = {
+ "tips_en": [
+ "You are not alone — help is available right now",
+ "Please reach out to someone you trust immediately",
+ "Remove access to any means of self-harm if possible",
+ "Stay with another person — do not be alone right now",
+ ],
+ "tips_ar": [
+ "أنت لست وحدك — المساعدة متاحة الآن",
+ "من فضلك تواصل مع شخص تثق به فوراً",
+ "ابتعد عن أي وسيلة قد تؤذي بها نفسك",
+ "ابقَ مع شخص آخر — لا تكن وحدك الآن",
+ ],
+ "resources_en": [
+ "🆘 International Association for Suicide Prevention: https://www.iasp.info/resources/Crisis_Centres/",
+ "🆘 Crisis Text Line (US): Text HOME to 741741",
+ "🆘 Befrienders Worldwide: https://www.befrienders.org",
+ ],
+ "resources_ar": [
+ "🆘 الرابطة الدولية للوقاية من الانتحار: https://www.iasp.info/resources/Crisis_Centres/",
+ "🆘 خط أزمات إيميج (مصر): 08008880700",
+ "🆘 خط مساندة (السعودية): 920033360",
+ "🆘 موقع Befrienders العالمي: https://www.befrienders.org",
+ ],
+ "referral_en": "🚨 URGENT: Please contact a mental health crisis line or go to the nearest emergency room immediately. Your life has value and help is available.",
+ "referral_ar": "🚨 عاجل جداً: من فضلك تواصل مع خط أزمات الصحة النفسية أو اذهب لأقرب طوارئ فوراً. حياتك لها قيمة والمساعدة متاحة.",
+}
+
+
+# ══════════════════════════════════════════════════════════════════════════════
+# 5. MAIN FUNCTION
+# ══════════════════════════════════════════════════════════════════════════════
+
+def get_recommendations(
+ disease: str,
+ disease_score: float,
+ user_text: str,
+) -> dict:
+ """
+ disease : 'anxiety' | 'depression' | 'stress'
+ disease_score: float 0-1 من الموديل
+ user_text : النص الذي كتبه المستخدم
+ returns : dict بالتوصيات الكاملة
+ """
+ is_suicidal = detect_suicidal(user_text)
+ if is_suicidal:
+ return {
+ "suicidal_flag": True,
+ "severity": "crisis",
+ "cause": "crisis",
+ **SUICIDAL_REC,
+ }
+
+ severity = get_severity(disease, disease_score)
+ severity_group = "severe" if severity in ("severe", "extremely_severe") else "mild_moderate"
+ cause = extract_cause(user_text)
+
+ disease_db = REC_DB.get(disease, REC_DB["stress"])
+ cause_db = disease_db.get(cause, disease_db.get("general", {}))
+ rec = cause_db.get(severity_group, cause_db.get("mild_moderate", {}))
+
+ return {
+ "suicidal_flag": False,
+ "severity": severity,
+ "cause": cause,
+ "tips_en": rec.get("tips_en", []),
+ "tips_ar": rec.get("tips_ar", []),
+ "resources_en": rec.get("resources_en", []),
+ "resources_ar": rec.get("resources_ar", []),
+ "referral_en": rec.get("referral_en", ""),
+ "referral_ar": rec.get("referral_ar", ""),
+ }
\ No newline at end of file
diff --git a/temp_space/runtime.txt b/temp_space/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..37504c53c604004f29d17be13adb2838b49c3bd3
--- /dev/null
+++ b/temp_space/runtime.txt
@@ -0,0 +1 @@
+3.11
diff --git a/temp_space/scaler.pkl b/temp_space/scaler.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..448673ece4b713d1a799c2afb888346fc35d1e59
--- /dev/null
+++ b/temp_space/scaler.pkl
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fe630eaf06688d9090bba2e118657f64d1fbdf3506175f640cf4990effbfdb22
+size 1467
diff --git a/temp_space/seed_db.py b/temp_space/seed_db.py
new file mode 100644
index 0000000000000000000000000000000000000000..c71571d23a5720024e386b34ae9283d1072cca7c
--- /dev/null
+++ b/temp_space/seed_db.py
@@ -0,0 +1,102 @@
+import os
+import random
+from datetime import datetime, timedelta
+from sqlalchemy import create_engine, Column, Integer, String, DateTime, JSON
+from sqlalchemy.orm import declarative_base, sessionmaker
+
+print("="*50)
+print("SafeSpace MVP Database Seeder (45 Days)")
+print("="*50)
+
+DATABASE_URL = "REMOVED_SECRET"
+
+try:
+ engine = create_engine(DATABASE_URL, connect_args={'connect_timeout': 10})
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
+ Base = declarative_base()
+
+ class DBUser(Base):
+ __tablename__ = "users"
+ id = Column(Integer, primary_key=True, index=True)
+ email = Column(String, unique=True, index=True)
+ password = Column(String)
+ created_at = Column(DateTime, default=datetime.utcnow)
+
+ class DBAnalysis(Base):
+ __tablename__ = "analyses"
+ id = Column(Integer, primary_key=True, index=True)
+ user_id = Column(Integer, index=True, nullable=True)
+ primary_condition = Column(String)
+ clinical_scoring = Column(JSON)
+ created_at = Column(DateTime, default=datetime.utcnow)
+
+ print("\nConnecting to database and ensuring tables exist...")
+ Base.metadata.create_all(bind=engine)
+ db = SessionLocal()
+
+ print("Creating dummy user (test@example.com)...")
+ user = db.query(DBUser).filter_by(email="test@example.com").first()
+ if not user:
+ user = DBUser(email="test@example.com", password="hashed_password_123")
+ db.add(user)
+ db.commit()
+ db.refresh(user)
+
+ print("\nGenerating 45 days of realistic DASS-42 mood history...")
+
+ # Clear old dummy data for this user to avoid duplicates if run multiple times
+ db.query(DBAnalysis).filter(DBAnalysis.user_id == user.id).delete()
+ db.commit()
+
+ # Generate 45 days of data
+ # We will simulate a healing journey over 45 days, with occasional bad days.
+ scores_history = []
+
+ dep, anx, str_score = 30, 26, 34 # Start high (Severe)
+
+ for day in range(45):
+ # Gradual improvement (scores drop over time)
+ dep = max(2, dep - random.uniform(0, 1.2))
+ anx = max(2, anx - random.uniform(0, 1.0))
+ str_score = max(4, str_score - random.uniform(0, 1.4))
+
+ # Add random "bad days" spikes (e.g. panic attacks or stressful events)
+ if day in [12, 25, 38]:
+ dep += random.randint(4, 10)
+ anx += random.randint(8, 14)
+ str_score += random.randint(6, 12)
+
+ # Ensure scores don't exceed DASS-42 maximums (42)
+ dep = min(42, int(dep))
+ anx = min(42, int(anx))
+ str_score = min(42, int(str_score))
+
+ scores_history.append((dep, anx, str_score))
+
+ for i, (d, a, s) in enumerate(scores_history):
+ record_date = datetime.utcnow() - timedelta(days=44 - i)
+
+ max_score = max(d, a, s)
+ primary = "depression" if max_score == d else ("anxiety" if max_score == a else "stress")
+
+ clinical_data = {
+ "depression": {"score": d, "severity": "Moderate"},
+ "anxiety": {"score": a, "severity": "Mild"},
+ "stress": {"score": s, "severity": "Moderate"}
+ }
+
+ analysis = DBAnalysis(
+ user_id=user.id,
+ primary_condition=primary,
+ clinical_scoring=clinical_data,
+ created_at=record_date
+ )
+ db.add(analysis)
+
+ db.commit()
+ print("\nSuccessfully seeded the database! 45 days of data added.")
+ print("Refresh your Flutter app to see the beautiful new Mood Graph!")
+ db.close()
+
+except Exception as e:
+ print(f"\nError connecting or seeding database: {e}")
diff --git a/temp_space/test_db.py b/temp_space/test_db.py
new file mode 100644
index 0000000000000000000000000000000000000000..53eb2dbf4adfccb2aa2f3b9998dca9cb0b30fd47
--- /dev/null
+++ b/temp_space/test_db.py
@@ -0,0 +1,58 @@
+from sqlalchemy import create_engine, text
+from datetime import datetime
+
+DATABASE_URL = "REMOVED_SECRET"
+
+print("="*50)
+print("Database Connection Test (No AI)")
+print("="*50)
+
+try:
+ print("\n[1] Creating engine with 10s timeout...")
+ engine = create_engine(DATABASE_URL, connect_args={'connect_timeout': 10})
+
+ print("[2] Attempting connection...")
+ with engine.connect() as conn:
+ # Test basic connectivity
+ result = conn.execute(text("SELECT 1"))
+ print("[3] SELECT 1 = OK")
+
+ # Check what tables exist
+ tables = conn.execute(text(
+ "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"
+ )).fetchall()
+ print(f"\n--- Tables in database ---")
+ for t in tables:
+ print(f" - {t[0]}")
+
+ # Count rows in each table
+ for t in tables:
+ count = conn.execute(text(f"SELECT COUNT(*) FROM {t[0]}")).scalar()
+ print(f" {t[0]}: {count} rows")
+
+ # Show last 5 analyses
+ try:
+ rows = conn.execute(text(
+ "SELECT id, primary_condition, created_at FROM analyses ORDER BY created_at DESC LIMIT 5"
+ )).fetchall()
+ print(f"\n--- Last 5 Analyses ---")
+ for r in rows:
+ print(f" ID={r[0]} condition={r[1]} date={r[2]}")
+ except Exception:
+ print(" (analyses table not found or empty)")
+
+ # Show users
+ try:
+ users = conn.execute(text("SELECT id, email, created_at FROM users")).fetchall()
+ print(f"\n--- Users ---")
+ for u in users:
+ print(f" ID={u[0]} email={u[1]} created={u[2]}")
+ except Exception:
+ print(" (users table not found or empty)")
+
+ print("\n" + "="*50)
+ print("CONNECTION SUCCESSFUL")
+ print("="*50)
+
+except Exception as e:
+ print(f"\nCONNECTION FAILED: {e}")
diff --git a/updated_backend/Requirements.txt b/updated_backend/Requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4220da1335844290da4c3144d05acdb90a04e454
--- /dev/null
+++ b/updated_backend/Requirements.txt
@@ -0,0 +1,15 @@
+streamlit>=1.32.0
+transformers>=4.41.0
+torch>=2.0.0
+tensorflow>=2.12.0
+scikit-learn>=1.3.0
+deep-translator>=1.11.4
+numpy>=1.24.0
+fastapi>=0.100.0
+uvicorn>=0.23.0
+pydantic>=2.4.0
+python-multipart>=0.0.6
+sentencepiece>=0.1.99
+sqlalchemy>=2.0.0
+psycopg2-binary>=2.9.0
+httpx>=0.25.0
\ No newline at end of file
diff --git a/updated_backend/api.py b/updated_backend/api.py
new file mode 100644
index 0000000000000000000000000000000000000000..cabadbd84db3fb4892bc1169f2911fbbaafc4852
--- /dev/null
+++ b/updated_backend/api.py
@@ -0,0 +1,360 @@
+import os
+from datetime import datetime
+import hashlib
+
+import httpx
+from fastapi import FastAPI, HTTPException, Depends
+from fastapi.responses import HTMLResponse
+from fastapi.middleware.cors import CORSMiddleware
+from pydantic import BaseModel, Field
+from typing import Optional
+
+from core_ai import predict_text, predict_survey, fuse_scores
+from recommendations import get_recommendations
+
+# --- DATABASE SETUP ---
+from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime, JSON
+from sqlalchemy.orm import declarative_base, sessionmaker, Session
+
+DATABASE_URL = os.environ.get("DATABASE_URL")
+if DATABASE_URL and DATABASE_URL.startswith("postgres://"):
+ DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://", 1)
+
+engine = create_engine(DATABASE_URL, connect_args={'connect_timeout': 5}) if DATABASE_URL else None
+SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) if engine else None
+Base = declarative_base()
+
+
+class DBUser(Base):
+ __tablename__ = "users"
+ id = Column(Integer, primary_key=True, index=True)
+ name = Column(String, nullable=True)
+ email = Column(String, unique=True, index=True)
+ password = Column(String)
+ created_at = Column(DateTime, default=datetime.utcnow)
+
+
+class DBAnalysis(Base):
+ __tablename__ = "analyses"
+ id = Column(Integer, primary_key=True, index=True)
+ user_id = Column(Integer, index=True, nullable=True)
+ primary_condition = Column(String)
+ clinical_scoring = Column(JSON)
+ created_at = Column(DateTime, default=datetime.utcnow)
+
+# --- APP SETUP ---
+app = FastAPI(title="SafeSpace API", version="1.0.0")
+
+
+@app.on_event("startup")
+async def startup_event():
+ import asyncio
+ if engine:
+ try:
+ await asyncio.wait_for(
+ asyncio.to_thread(Base.metadata.create_all, bind=engine),
+ timeout=8.0
+ )
+ print("Database connected and tables verified.")
+ except asyncio.TimeoutError:
+ print("Database connection timed out during startup - server will start without DB verification.")
+ except Exception as e:
+ print(f"Database connection failed during startup: {e}")
+ print("Application startup complete.")
+
+
+def get_db():
+ if not SessionLocal:
+ yield None
+ else:
+ db = SessionLocal()
+ try:
+ yield db
+ finally:
+ db.close()
+
+# Add CORS so Flutter app can communicate with it
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"],
+ allow_credentials=True,
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+
+# --- Password Hashing ---
+def hash_password(password: str) -> str:
+ return hashlib.sha256(password.encode()).hexdigest()
+
+# --- DASS-42 Clinical Scoring ---
+def calculate_dass_clinical_score(answers: list) -> dict:
+ dep_idx = [2, 4, 9, 12, 15, 16, 20, 23, 25, 30, 33, 36, 37, 41]
+ anx_idx = [1, 3, 6, 8, 14, 18, 19, 22, 24, 27, 29, 35, 39, 40]
+ str_idx = [0, 5, 7, 10, 11, 13, 17, 21, 26, 28, 31, 32, 34, 38]
+
+ dep_score = sum(answers[i] for i in dep_idx)
+ anx_score = sum(answers[i] for i in anx_idx)
+ str_score = sum(answers[i] for i in str_idx)
+
+ def get_severity(score, bounds):
+ if score <= bounds[0]: return "Normal"
+ if score <= bounds[1]: return "Mild"
+ if score <= bounds[2]: return "Moderate"
+ if score <= bounds[3]: return "Severe"
+ return "Extremely Severe"
+
+ return {
+ "depression": {"score": dep_score, "severity": get_severity(dep_score, [9, 13, 20, 27])},
+ "anxiety": {"score": anx_score, "severity": get_severity(anx_score, [7, 9, 14, 19])},
+ "stress": {"score": str_score, "severity": get_severity(str_score, [14, 18, 25, 33])}
+ }
+
+# --- API MODELS ---
+class AnalysisRequest(BaseModel):
+ user_id: str | int = Field(default=None, description="User identifier")
+ text: str = Field(..., min_length=1)
+ survey_answers: list[int] = Field(..., min_items=42, max_items=42)
+ locale: str = Field(default="en")
+ client_ts: str | None = None
+
+
+class AnalyzeRequest(BaseModel):
+ text: str = Field(..., description="The user's response in text (Arabic/English)")
+ survey_answers: list[int] = Field(..., min_items=42, max_items=42, description="List of 42 integers (0-4) representing DASS-42 survey answers")
+ user_id: int | None = Field(default=None, description="Optional user ID to link analysis to a user")
+
+
+class ChatRequest(BaseModel):
+ message: str
+ session_id: Optional[str] = "default"
+
+
+class ChatResponse(BaseModel):
+ reply: str
+
+
+class SignupRequest(BaseModel):
+ name: str = Field(..., min_length=1)
+ email: str = Field(..., min_length=5)
+ password: str = Field(..., min_length=4)
+
+
+class LoginRequest(BaseModel):
+ email: str = Field(..., min_length=5)
+ password: str = Field(..., min_length=1)
+
+
+# --- ENDPOINTS ---
+@app.get("/")
+def root():
+ return {"status": "ok", "message": "SafeSpace API"}
+
+
+@app.get("/test", response_class=HTMLResponse)
+def test_page():
+ html_path = os.path.join(os.path.dirname(__file__), "index.html")
+ if not os.path.exists(html_path):
+ raise HTTPException(status_code=404, detail="index.html not found")
+ with open(html_path, "r", encoding="utf-8") as f:
+ return f.read()
+
+
+# --- AUTH ENDPOINTS ---
+@app.post("/api/v1/auth/signup")
+async def signup(request: SignupRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ # Check if email already exists
+ existing = db.query(DBUser).filter(DBUser.email == request.email).first()
+ if existing:
+ raise HTTPException(status_code=400, detail="Email already registered")
+
+ # Create new user
+ try:
+ new_user = DBUser(
+ name=request.name,
+ email=request.email,
+ password=hash_password(request.password),
+ )
+ db.add(new_user)
+ db.commit()
+ db.refresh(new_user)
+
+ return {
+ "user_id": new_user.id,
+ "email": new_user.email,
+ "name": new_user.name,
+ "message": "Account created successfully"
+ }
+ except Exception as e:
+ db.rollback()
+ raise HTTPException(status_code=500, detail=f"Failed to create account: {str(e)}")
+
+
+@app.post("/api/v1/auth/login")
+async def login(request: LoginRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ user = db.query(DBUser).filter(DBUser.email == request.email).first()
+ if not user:
+ raise HTTPException(status_code=401, detail="Email not found")
+
+ if user.password != hash_password(request.password):
+ # Also try plain-text match for legacy users who signed up before hashing
+ if user.password != request.password:
+ raise HTTPException(status_code=401, detail="Incorrect password")
+
+ return {
+ "user_id": user.id,
+ "email": user.email,
+ "name": user.name or "",
+ "message": "Login successful"
+ }
+
+
+# New-style endpoint (used by index.html test page)
+@app.post("/v1/analysis")
+def analyze(payload: AnalysisRequest, db: Session = Depends(get_db)):
+ text_scores = predict_text(payload.text)
+ survey_scores = predict_survey(payload.survey_answers)
+ final_scores = fuse_scores(text_scores, survey_scores)
+ primary = max(final_scores, key=final_scores.get)
+ clinical = calculate_dass_clinical_score(payload.survey_answers)
+ rec = get_recommendations(primary, final_scores[primary], payload.text)
+ created_at = datetime.utcnow().isoformat() + "Z"
+
+ # Save to PostgreSQL if DB is connected
+ if db:
+ try:
+ new_analysis = DBAnalysis(
+ primary_condition=primary,
+ clinical_scoring=clinical
+ )
+ db.add(new_analysis)
+ db.commit()
+ except Exception as e:
+ print(f"DB save error: {e}")
+
+ return {
+ "analysis_id": None,
+ "primary_condition": primary,
+ "fused_scores": final_scores,
+ "text_scores": text_scores,
+ "survey_scores": survey_scores,
+ "clinical_scoring": clinical,
+ "severity": rec.get("severity"),
+ "cause": rec.get("cause"),
+ "recommendations": {
+ "tips_en": rec.get("tips_en", []),
+ "tips_ar": rec.get("tips_ar", []),
+ "resources_en": rec.get("resources_en", []),
+ "resources_ar": rec.get("resources_ar", []),
+ "referral_en": rec.get("referral_en", ""),
+ "referral_ar": rec.get("referral_ar", ""),
+ },
+ "suicidal_flag": rec.get("suicidal_flag", False),
+ "created_at": created_at,
+ }
+
+# Flutter-compatible endpoint (used by api_service.dart)
+@app.post("/api/v1/analyze")
+async def analyze_mental_health(request: AnalyzeRequest, db: Session = Depends(get_db)):
+ try:
+ text_scores = predict_text(request.text)
+ survey_scores = predict_survey(request.survey_answers)
+ final_scores = fuse_scores(text_scores, survey_scores)
+ primary = max(final_scores, key=final_scores.get)
+ clinical = calculate_dass_clinical_score(request.survey_answers)
+ rec = get_recommendations(primary, final_scores[primary], request.text)
+ created_at = datetime.utcnow().isoformat() + "Z"
+
+ # Save to PostgreSQL if DB is connected
+ if db:
+ try:
+ new_analysis = DBAnalysis(
+ user_id=request.user_id,
+ primary_condition=primary,
+ clinical_scoring=clinical
+ )
+ db.add(new_analysis)
+ db.commit()
+ except Exception as e:
+ print(f"DB save error: {e}")
+
+ return {
+ "analysis_id": None,
+ "primary_condition": primary,
+ "fused_scores": final_scores,
+ "text_scores": text_scores,
+ "survey_scores": survey_scores,
+ "clinical_scoring": clinical,
+ "severity": rec.get("severity"),
+ "cause": rec.get("cause"),
+ "recommendations": {
+ "tips_en": rec.get("tips_en", []),
+ "tips_ar": rec.get("tips_ar", []),
+ "resources_en": rec.get("resources_en", []),
+ "resources_ar": rec.get("resources_ar", []),
+ "referral_en": rec.get("referral_en", ""),
+ "referral_ar": rec.get("referral_ar", ""),
+ },
+ "suicidal_flag": rec.get("suicidal_flag", False),
+ "created_at": created_at,
+ }
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=str(e))
+
+# Flutter-compatible history endpoint
+@app.get("/api/v1/analyses/history")
+async def get_analyses_history(user_id: int = None, db: Session = Depends(get_db)):
+ try:
+ if not db:
+ return []
+
+ query = db.query(DBAnalysis)
+
+ # Filter by user_id if provided
+ if user_id is not None:
+ query = query.filter(DBAnalysis.user_id == user_id)
+
+ # Get the 10 most recent analyses, sorted by created_at ascending (oldest first for graphing)
+ records = query.order_by(DBAnalysis.created_at.desc()).limit(10).all()
+
+ history = []
+ for r in reversed(records): # Reverse so oldest is first
+ if r.clinical_scoring:
+ history.append({
+ "id": r.id,
+ "date": r.created_at.strftime("%b %d"),
+ "depression": r.clinical_scoring.get("depression", {}).get("score", 0),
+ "anxiety": r.clinical_scoring.get("anxiety", {}).get("score", 0),
+ "stress": r.clinical_scoring.get("stress", {}).get("score", 0),
+ "primary": r.primary_condition
+ })
+ return history
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=str(e))
+
+@app.post("/api/v1/chat", response_model=ChatResponse)
+async def chat_with_ai(request: ChatRequest):
+ api_url = os.environ.get("AI_API_URL")
+ api_key = os.environ.get("AI_API_KEY")
+ chatflow_id = os.environ.get("AI_CHATFLOW_ID")
+
+ if not api_url or not api_key or not chatflow_id:
+ raise HTTPException(status_code=500, detail="AI API credentials are not configured in Secrets.")
+
+ endpoint = f"{api_url}/api/v1/prediction/{chatflow_id}"
+ headers = {"Authorization": f"Bearer {api_key}"}
+ payload = {"question": request.message, "overrideConfig": {"sessionId": request.session_id}}
+
+ async with httpx.AsyncClient() as client:
+ try:
+ response = await client.post(endpoint, json=payload, headers=headers, timeout=30.0)
+ response.raise_for_status()
+ data = response.json()
+ return ChatResponse(reply=data.get("text") or data.get("answer") or str(data))
+ except Exception as e:
+ raise HTTPException(status_code=502, detail=f"Failed to communicate with AI API: {str(e)}")
diff --git a/updated_backend/main.py b/updated_backend/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..4b1c19e413391f6f56b0a6fb7aad9bb3d0053771
--- /dev/null
+++ b/updated_backend/main.py
@@ -0,0 +1,343 @@
+import os
+from datetime import datetime
+import hashlib
+
+import httpx
+from fastapi import FastAPI, HTTPException, Depends
+from fastapi.responses import HTMLResponse
+from fastapi.middleware.cors import CORSMiddleware
+from pydantic import BaseModel, Field
+from typing import Optional
+
+from core_ai import predict_text, predict_survey, fuse_scores
+from recommendations import get_recommendations
+
+# --- DATABASE SETUP ---
+from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime, JSON
+from sqlalchemy.orm import declarative_base, sessionmaker, Session
+
+DATABASE_URL = os.environ.get("DATABASE_URL")
+if DATABASE_URL and DATABASE_URL.startswith("postgres://"):
+ DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://", 1)
+
+engine = create_engine(DATABASE_URL, connect_args={'connect_timeout': 5}) if DATABASE_URL else None
+SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) if engine else None
+Base = declarative_base()
+
+
+class DBUser(Base):
+ __tablename__ = "users"
+ id = Column(Integer, primary_key=True, index=True)
+ name = Column(String, nullable=True)
+ email = Column(String, unique=True, index=True)
+ password = Column(String)
+ created_at = Column(DateTime, default=datetime.utcnow)
+
+
+class DBAnalysis(Base):
+ __tablename__ = "analyses"
+ id = Column(Integer, primary_key=True, index=True)
+ user_id = Column(Integer, index=True, nullable=True)
+ primary_condition = Column(String)
+ clinical_scoring = Column(JSON)
+ created_at = Column(DateTime, default=datetime.utcnow)
+
+# --- APP SETUP ---
+app = FastAPI(title="SafeSpace API", version="1.0.0")
+
+
+@app.on_event("startup")
+async def startup_event():
+ import asyncio
+ if engine:
+ try:
+ await asyncio.wait_for(
+ asyncio.to_thread(Base.metadata.create_all, bind=engine),
+ timeout=8.0
+ )
+ print("Database connected and tables verified.")
+ except asyncio.TimeoutError:
+ print("Database connection timed out during startup - server will start without DB verification.")
+ except Exception as e:
+ print(f"Database connection failed during startup: {e}")
+ print("Application startup complete.")
+
+
+def get_db():
+ if not SessionLocal:
+ yield None
+ else:
+ db = SessionLocal()
+ try:
+ yield db
+ finally:
+ db.close()
+
+# Add CORS so Flutter app can communicate with it
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"],
+ allow_credentials=True,
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+
+# --- Password Hashing ---
+def hash_password(password: str) -> str:
+ return hashlib.sha256(password.encode()).hexdigest()
+
+# --- DASS-42 Clinical Scoring ---
+def calculate_dass_clinical_score(answers: list) -> dict:
+ dep_idx = [2, 4, 9, 12, 15, 16, 20, 23, 25, 30, 33, 36, 37, 41]
+ anx_idx = [1, 3, 6, 8, 14, 18, 19, 22, 24, 27, 29, 35, 39, 40]
+ str_idx = [0, 5, 7, 10, 11, 13, 17, 21, 26, 28, 31, 32, 34, 38]
+
+ dep_score = sum(answers[i] for i in dep_idx)
+ anx_score = sum(answers[i] for i in anx_idx)
+ str_score = sum(answers[i] for i in str_idx)
+
+ def get_severity(score, bounds):
+ if score <= bounds[0]: return "Normal"
+ if score <= bounds[1]: return "Mild"
+ if score <= bounds[2]: return "Moderate"
+ if score <= bounds[3]: return "Severe"
+ return "Extremely Severe"
+
+ return {
+ "depression": {"score": dep_score, "severity": get_severity(dep_score, [9, 13, 20, 27])},
+ "anxiety": {"score": anx_score, "severity": get_severity(anx_score, [7, 9, 14, 19])},
+ "stress": {"score": str_score, "severity": get_severity(str_score, [14, 18, 25, 33])}
+ }
+
+# --- API MODELS ---
+class AnalysisRequest(BaseModel):
+ user_id: str | int = Field(default=None, description="User identifier")
+ text: str = Field(..., min_length=1)
+ survey_answers: list[int] = Field(..., min_items=42, max_items=42)
+ locale: str = Field(default="en")
+ client_ts: str | None = None
+
+
+class AnalyzeRequest(BaseModel):
+ text: str = Field(..., description="The user's response in text (Arabic/English)")
+ survey_answers: list[int] = Field(..., min_items=42, max_items=42, description="List of 42 integers (0-4) representing DASS-42 survey answers")
+ user_id: int | None = Field(default=None, description="Optional user ID to link analysis to a user")
+
+
+class ChatRequest(BaseModel):
+ message: str
+ session_id: Optional[str] = "default"
+
+
+class ChatResponse(BaseModel):
+ reply: str
+
+
+class SignupRequest(BaseModel):
+ name: str = Field(..., min_length=1)
+ email: str = Field(..., min_length=5)
+ password: str = Field(..., min_length=4)
+
+
+class LoginRequest(BaseModel):
+ email: str = Field(..., min_length=5)
+ password: str = Field(..., min_length=1)
+
+
+# --- ENDPOINTS ---
+@app.get("/")
+def root():
+ return {"status": "ok", "message": "SafeSpace API"}
+
+
+@app.get("/test", response_class=HTMLResponse)
+def test_page():
+ html_path = os.path.join(os.path.dirname(__file__), "index.html")
+ if not os.path.exists(html_path):
+ raise HTTPException(status_code=404, detail="index.html not found")
+ with open(html_path, "r", encoding="utf-8") as f:
+ return f.read()
+
+
+# --- AUTH ENDPOINTS ---
+@app.post("/api/v1/auth/signup")
+async def signup(request: SignupRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ # Check if email already exists
+ existing = db.query(DBUser).filter(DBUser.email == request.email).first()
+ if existing:
+ raise HTTPException(status_code=400, detail="Email already registered")
+
+ # Create new user
+ try:
+ new_user = DBUser(
+ name=request.name,
+ email=request.email,
+ password=hash_password(request.password),
+ )
+ db.add(new_user)
+ db.commit()
+ db.refresh(new_user)
+
+ return {
+ "user_id": new_user.id,
+ "email": new_user.email,
+ "name": new_user.name,
+ "message": "Account created successfully"
+ }
+ except Exception as e:
+ db.rollback()
+ raise HTTPException(status_code=500, detail=f"Failed to create account: {str(e)}")
+
+
+@app.post("/api/v1/auth/login")
+async def login(request: LoginRequest, db: Session = Depends(get_db)):
+ if not db:
+ raise HTTPException(status_code=500, detail="Database not available")
+
+ user = db.query(DBUser).filter(DBUser.email == request.email).first()
+ if not user:
+ raise HTTPException(status_code=401, detail="Email not found")
+
+ if user.password != hash_password(request.password):
+ # Also try plain-text match for legacy users who signed up before hashing
+ if user.password != request.password:
+ raise HTTPException(status_code=401, detail="Incorrect password")
+
+ return {
+ "user_id": user.id,
+ "email": user.email,
+ "name": user.name or "",
+ "message": "Login successful"
+ }
+
+
+# New-style endpoint (used by index.html test page)
+@app.post("/v1/analysis")
+def analyze(payload: AnalysisRequest, db: Session = Depends(get_db)):
+ text_scores = predict_text(payload.text)
+ survey_scores = predict_survey(payload.survey_answers)
+ final_scores = fuse_scores(text_scores, survey_scores)
+ primary = max(final_scores, key=final_scores.get)
+ clinical = calculate_dass_clinical_score(payload.survey_answers)
+ rec = get_recommendations(primary, final_scores[primary], payload.text)
+
+ # Save to PostgreSQL if DB is connected
+ if db:
+ try:
+ new_analysis = DBAnalysis(
+ primary_condition=primary,
+ clinical_scoring=clinical
+ )
+ db.add(new_analysis)
+ db.commit()
+ except Exception as e:
+ print(f"DB save error: {e}")
+
+ return {
+ "analysis_id": None,
+ "primary": primary,
+ "scores": final_scores,
+ "severity": rec.get("severity"),
+ "cause": rec.get("cause"),
+ "recommendations": {
+ "tips_en": rec.get("tips_en", []),
+ "tips_ar": rec.get("tips_ar", []),
+ "resources_en": rec.get("resources_en", []),
+ "resources_ar": rec.get("resources_ar", []),
+ "referral_en": rec.get("referral_en", ""),
+ "referral_ar": rec.get("referral_ar", ""),
+ },
+ "suicidal_flag": rec.get("suicidal_flag", False),
+ "created_at": datetime.utcnow().isoformat() + "Z",
+ }
+
+# Flutter-compatible endpoint (used by api_service.dart)
+@app.post("/api/v1/analyze")
+async def analyze_mental_health(request: AnalyzeRequest, db: Session = Depends(get_db)):
+ try:
+ text_scores = predict_text(request.text)
+ survey_scores = predict_survey(request.survey_answers)
+ final_scores = fuse_scores(text_scores, survey_scores)
+ primary = max(final_scores, key=final_scores.get)
+ clinical = calculate_dass_clinical_score(request.survey_answers)
+ rec = get_recommendations(primary, final_scores[primary], request.text)
+
+ # Save to PostgreSQL if DB is connected
+ if db:
+ try:
+ new_analysis = DBAnalysis(
+ user_id=request.user_id,
+ primary_condition=primary,
+ clinical_scoring=clinical
+ )
+ db.add(new_analysis)
+ db.commit()
+ except Exception as e:
+ print(f"DB save error: {e}")
+
+ return {
+ "primary_condition": primary,
+ "fused_scores": final_scores,
+ "text_scores": text_scores,
+ "survey_scores": survey_scores,
+ "clinical_scoring": clinical,
+ "recommendations": rec
+ }
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=str(e))
+
+# Flutter-compatible history endpoint
+@app.get("/api/v1/analyses/history")
+async def get_analyses_history(user_id: int = None, db: Session = Depends(get_db)):
+ try:
+ if not db:
+ return []
+
+ query = db.query(DBAnalysis)
+
+ # Filter by user_id if provided
+ if user_id is not None:
+ query = query.filter(DBAnalysis.user_id == user_id)
+
+ # Get the 10 most recent analyses, sorted by created_at ascending (oldest first for graphing)
+ records = query.order_by(DBAnalysis.created_at.desc()).limit(10).all()
+
+ history = []
+ for r in reversed(records): # Reverse so oldest is first
+ if r.clinical_scoring:
+ history.append({
+ "id": r.id,
+ "date": r.created_at.strftime("%b %d"),
+ "depression": r.clinical_scoring.get("depression", {}).get("score", 0),
+ "anxiety": r.clinical_scoring.get("anxiety", {}).get("score", 0),
+ "stress": r.clinical_scoring.get("stress", {}).get("score", 0),
+ "primary": r.primary_condition
+ })
+ return history
+ except Exception as e:
+ raise HTTPException(status_code=500, detail=str(e))
+
+@app.post("/api/v1/chat", response_model=ChatResponse)
+async def chat_with_ai(request: ChatRequest):
+ api_url = os.environ.get("AI_API_URL")
+ api_key = os.environ.get("AI_API_KEY")
+ chatflow_id = os.environ.get("AI_CHATFLOW_ID")
+
+ if not api_url or not api_key or not chatflow_id:
+ raise HTTPException(status_code=500, detail="AI API credentials are not configured in Secrets.")
+
+ endpoint = f"{api_url}/api/v1/prediction/{chatflow_id}"
+ headers = {"Authorization": f"Bearer {api_key}"}
+ payload = {"question": request.message, "overrideConfig": {"sessionId": request.session_id}}
+
+ async with httpx.AsyncClient() as client:
+ try:
+ response = await client.post(endpoint, json=payload, headers=headers, timeout=30.0)
+ response.raise_for_status()
+ data = response.json()
+ return ChatResponse(reply=data.get("text") or data.get("answer") or str(data))
+ except Exception as e:
+ raise HTTPException(status_code=502, detail=f"Failed to communicate with AI API: {str(e)}")