{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":102335,"databundleVersionId":12518947,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":12080011,"sourceType":"datasetVersion","datasetId":7604462}],"dockerImageVersionId":31040,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-06T14:29:53.394821Z","iopub.execute_input":"2025-06-06T14:29:53.395188Z","iopub.status.idle":"2025-06-06T14:29:53.419848Z","shell.execute_reply.started":"2025-06-06T14:29:53.395160Z","shell.execute_reply":"2025-06-06T14:29:53.418859Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n\nimport pandas as pd\nimport numpy as np\nimport joblib\n\n# モデルの読み込み\nprint(\"Loading model...\")\nmodel_data = joblib.load('/kaggle/input/cmi-optimized-model/optimized_full_model.pkl')\nmodels = model_data['models']\nle = model_data['label_encoder']\nfeature_names = model_data['feature_names']\nprint(\"Model loaded successfully\")\n\ndef create_features(seq_data):\n  \"\"\"特徴量作成\"\"\"\n  features = {}\n\n  # 加速度特徴量\n  for axis in ['x', 'y', 'z']:\n      col = f'acc_{axis}'\n      data = seq_data[col].values\n\n      features[f'{col}_mean'] = np.mean(data)\n      features[f'{col}_std'] = np.std(data)\n      features[f'{col}_max'] = np.max(data)\n      features[f'{col}_min'] = np.min(data)\n      features[f'{col}_range'] = features[f'{col}_max'] - features[f'{col}_min']\n      features[f'{col}_p25'] = np.percentile(data, 25)\n      features[f'{col}_p75'] = np.percentile(data, 75)\n      features[f'{col}_iqr'] = features[f'{col}_p75'] - features[f'{col}_p25']\n\n      diff1 = np.diff(data)\n      if len(diff1) > 0:\n          features[f'{col}_diff_mean'] = np.mean(diff1)\n          features[f'{col}_diff_std'] = np.std(diff1)\n\n  # 加速度の大きさ\n  acc_mag = np.sqrt(seq_data['acc_x']**2 + seq_data['acc_y']**2 + seq_data['acc_z']**2)\n  features['acc_mag_mean'] = np.mean(acc_mag)\n  features['acc_mag_std'] = np.std(acc_mag)\n  features['acc_mag_max'] = np.max(acc_mag)\n  features['acc_mag_min'] = np.min(acc_mag)\n\n  # 角度特徴\n  features['acc_xy_angle_mean'] = np.mean(np.arctan2(seq_data['acc_y'], seq_data['acc_x']))\n  features['acc_xy_angle_std'] = np.std(np.arctan2(seq_data['acc_y'], seq_data['acc_x']))\n\n  # エネルギー\n  features['acc_energy'] = np.sum(acc_mag**2) / len(acc_mag)\n  features['acc_log_energy'] = np.log1p(features['acc_energy'])\n\n  # ジャイロ特徴\n  for axis in ['w', 'x', 'y', 'z']:\n      col = f'rot_{axis}'\n      features[f'{col}_mean'] = seq_data[col].mean()\n      features[f'{col}_std'] = seq_data[col].std()\n      features[f'{col}_max'] = seq_data[col].max()\n      features[f'{col}_min'] = seq_data[col].min()\n\n  # 回転の大きさ\n  rot_mag = np.sqrt(seq_data['rot_x']**2 + seq_data['rot_y']**2 + seq_data['rot_z']**2)\n  features['rot_mag_mean'] = np.mean(rot_mag)\n  features['rot_mag_std'] = np.std(rot_mag)\n  features['rot_energy'] = np.sum(rot_mag**2) / len(rot_mag)\n\n  # サーモパイル\n  for i in range(1, 6):\n      col = f'thm_{i}'\n      if col in seq_data.columns:\n          valid_data = seq_data[seq_data[col] != -1][col]\n          if len(valid_data) > 0:\n              features[f'{col}_mean'] = valid_data.mean()\n              features[f'{col}_std'] = valid_data.std()\n          else:\n              features[f'{col}_mean'] = 0\n              features[f'{col}_std'] = 0\n      else:\n          features[f'{col}_mean'] = 0\n          features[f'{col}_std'] = 0\n\n  # ToF\n  for sensor_id in range(1, 6):\n      features[f'tof_{sensor_id}_mean'] = 0\n      features[f'tof_{sensor_id}_std'] = 0\n      features[f'tof_{sensor_id}_has_data'] = 0\n\n  features['sequence_length'] = len(seq_data)\n\n  mid = len(seq_data) // 2\n  if mid > 0:\n      features['acc_mag_trend'] = np.mean(acc_mag[mid:]) - np.mean(acc_mag[:mid])\n  else:\n      features['acc_mag_trend'] = 0\n\n  return features\n\ndef predict(test_batch):\n  \"\"\"Kaggleから呼ばれる予測関数\"\"\"\n  sequence, demographics = test_batch\n\n  # polarsの場合はpandasに変換\n  if hasattr(sequence, 'to_pandas'):\n      sequence = sequence.to_pandas()\n\n  # Gestureフェーズのデータを取得\n  if 'phase' in sequence.columns:\n      gesture_data = sequence[sequence['phase'] == 'Gesture']\n  else:\n      gesture_data = sequence\n\n  if len(gesture_data) > 0:\n      try:\n          # 特徴量作成\n          features = create_features(gesture_data)\n\n          # 特徴量の存在を確認\n          X_test = pd.DataFrame([features])\n          missing_cols = set(feature_names) - set(X_test.columns)\n          for col in missing_cols:\n              X_test[col] = 0\n          X_test = X_test[feature_names]\n\n          # 予測\n          all_probs = []\n          for model_info in models:\n              lgb_model = model_info['lgb']\n              xgb_model = model_info['xgb']\n\n              lgb_proba = lgb_model.predict_proba(X_test)[0]\n              xgb_proba = xgb_model.predict_proba(X_test)[0]\n\n              ensemble_proba = 0.7 * lgb_proba + 0.3 * xgb_proba\n              all_probs.append(ensemble_proba)\n\n          final_proba = np.mean(all_probs, axis=0)\n          pred_class = np.argmax(final_proba)\n          gesture = le.inverse_transform([pred_class])[0]\n\n          return gesture\n\n      except Exception as e:\n          print(f\"Error in prediction: {e}\")\n          import traceback\n          traceback.print_exc()\n          return 'Text on phone'\n  else:\n      return 'Text on phone'\n\nprint(\"Prediction function ready\")\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T14:29:53.421184Z","iopub.execute_input":"2025-06-06T14:29:53.421546Z","iopub.status.idle":"2025-06-06T14:30:05.277275Z","shell.execute_reply.started":"2025-06-06T14:29:53.421526Z","shell.execute_reply":"2025-06-06T14:30:05.276385Z"}},"outputs":[],"execution_count":null}]}