{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"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","execution":{"iopub.status.busy":"2022-07-18T17:26:08.858276Z","iopub.execute_input":"2022-07-18T17:26:08.859260Z","iopub.status.idle":"2022-07-18T17:26:08.899342Z","shell.execute_reply.started":"2022-07-18T17:26:08.859121Z","shell.execute_reply":"2022-07-18T17:26:08.898122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 1.读取数据并且观察数据","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(\"/kaggle/input/titanic/train.csv\")\ntest_df = pd.read_csv(\"/kaggle/input/titanic/test.csv\")\ncombine = [train_df,test_df]\ntrain_df.sample(3)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:08.901824Z","iopub.execute_input":"2022-07-18T17:26:08.902958Z","iopub.status.idle":"2022-07-18T17:26:08.964365Z","shell.execute_reply.started":"2022-07-18T17:26:08.902908Z","shell.execute_reply":"2022-07-18T17:26:08.962961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.describe()","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:08.966185Z","iopub.execute_input":"2022-07-18T17:26:08.966672Z","iopub.status.idle":"2022-07-18T17:26:09.022961Z","shell.execute_reply.started":"2022-07-18T17:26:08.966627Z","shell.execute_reply":"2022-07-18T17:26:09.021652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.describe(include=\"O\")","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:09.025684Z","iopub.execute_input":"2022-07-18T17:26:09.026339Z","iopub.status.idle":"2022-07-18T17:26:09.050716Z","shell.execute_reply.started":"2022-07-18T17:26:09.026289Z","shell.execute_reply":"2022-07-18T17:26:09.049899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:09.051758Z","iopub.execute_input":"2022-07-18T17:26:09.052364Z","iopub.status.idle":"2022-07-18T17:26:09.072777Z","shell.execute_reply.started":"2022-07-18T17:26:09.052312Z","shell.execute_reply":"2022-07-18T17:26:09.071431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2.猜测可能对标签有影响的特征\n- Age(年龄)\n- Pclass（类似经济舱，商务舱的分类）\n- Fare（票价）\n- sex\n- name的分类，但是不太好提取\n\n对标签没影响的几个特征:\n- Ticket(显然船票编号没影响),Cabin（小屋的位置可能有影响，但是数据不太好舍弃）","metadata":{}},{"cell_type":"markdown","source":"## 3.处理特征\n\n先处理年龄，把空值全部补位中位数","metadata":{}},{"cell_type":"code","source":"for dataset in combine:\n    guess_df = dataset['Age'].dropna() # 把空值全部删除\n    age_median = guess_df.median() # 获取年龄的中位数，中位数可能有两个\n    dataset.loc[dataset.Age.isnull(),'Age'] = int( age_median/0.5 + 0.5 ) * 0.5","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:09.074243Z","iopub.execute_input":"2022-07-18T17:26:09.074983Z","iopub.status.idle":"2022-07-18T17:26:09.086341Z","shell.execute_reply.started":"2022-07-18T17:26:09.074937Z","shell.execute_reply":"2022-07-18T17:26:09.085416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"而后处理Embarked，用众数去补全","metadata":{}},{"cell_type":"code","source":"freq_Embarked = train_df.Embarked.dropna().mode()[0]\nfor dataset in combine:\n    guess_df = dataset['Embarked'].dropna() # 把空值全部删除\n    dataset.loc[dataset.Embarked.isnull(),'Embarked'] = freq_Embarked","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:09.089214Z","iopub.execute_input":"2022-07-18T17:26:09.089594Z","iopub.status.idle":"2022-07-18T17:26:09.104364Z","shell.execute_reply.started":"2022-07-18T17:26:09.089560Z","shell.execute_reply":"2022-07-18T17:26:09.102178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:09.106816Z","iopub.execute_input":"2022-07-18T17:26:09.110437Z","iopub.status.idle":"2022-07-18T17:26:09.126879Z","shell.execute_reply.started":"2022-07-18T17:26:09.110391Z","shell.execute_reply":"2022-07-18T17:26:09.126021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3.开始着手训练","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport sys\nimport torch.optim as optim\nimport torch.nn.functional as F \n\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.model_selection import train_test_split\nfrom torch.utils import data\nfrom tqdm import tqdm\n","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:09.128478Z","iopub.execute_input":"2022-07-18T17:26:09.129161Z","iopub.status.idle":"2022-07-18T17:26:12.617910Z","shell.execute_reply.started":"2022-07-18T17:26:09.129120Z","shell.execute_reply":"2022-07-18T17:26:12.616531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"combine = pd.concat((train_df.iloc[:, 2:-1], test_df.iloc[:, 1:])) \nn_train = train_df.shape[0]\ncombine = pd.get_dummies(combine) # 必须合在一起做，不然预测会出问题\n\nX_train = torch.tensor(combine[:n_train].values,dtype=torch.float32)\ny_train = torch.tensor(train_df.Survived.values,dtype=torch.int64)\nX_train, X_test, y_train, y_test = train_test_split(X_train, y_train, test_size = 0.1)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:12.622533Z","iopub.execute_input":"2022-07-18T17:26:12.623797Z","iopub.status.idle":"2022-07-18T17:26:12.719706Z","shell.execute_reply.started":"2022-07-18T17:26:12.623753Z","shell.execute_reply":"2022-07-18T17:26:12.718783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train.shape,y_train.shape # 分类的y_train不能转为[801,1]，否则会报错。线性回归可以这样","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:12.721552Z","iopub.execute_input":"2022-07-18T17:26:12.722433Z","iopub.status.idle":"2022-07-18T17:26:12.730617Z","shell.execute_reply.started":"2022-07-18T17:26:12.722386Z","shell.execute_reply":"2022-07-18T17:26:12.729716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class LinearRegression(nn.Module):\n    def __init__(self,input_size,output_size):\n        super(LinearRegression,self).__init__()\n        self.f1 = nn.Linear(input_size,2500)\n        self.f2 = nn.Linear(2500,output_size)\n\n\n    def forward(self,x):\n        x = self.f1(x)\n        x = F.leaky_relu(x)\n        x = F.dropout(x, p = 0.3)\n        x = self.f2(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:12.732491Z","iopub.execute_input":"2022-07-18T17:26:12.733542Z","iopub.status.idle":"2022-07-18T17:26:12.743377Z","shell.execute_reply.started":"2022-07-18T17:26:12.733494Z","shell.execute_reply":"2022-07-18T17:26:12.741947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 100\ntrain_dataset = data.TensorDataset(X_train,y_train)\ntrain_loader = data.DataLoader(train_dataset, batch_size, shuffle=True)\nvalid_dataset = data.TensorDataset(X_test,y_test)\nvalid_loader = data.DataLoader(valid_dataset, batch_size, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:12.744933Z","iopub.execute_input":"2022-07-18T17:26:12.745549Z","iopub.status.idle":"2022-07-18T17:26:12.756640Z","shell.execute_reply.started":"2022-07-18T17:26:12.745509Z","shell.execute_reply":"2022-07-18T17:26:12.755165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_dim = 2432\noutput_dim = 2\nmodel = LinearRegression(input_dim, output_dim)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.0002)\nn_epochs = 100\n\ntrain_loss_epoch = []\nvalid_loss_epoch = []\ntrain_accuracy_epoch = []\nvalid_accuracy_epoch = []\n\nfor epoch in range(n_epochs):\n    model.train()\n    train_loss = [] # 记录每个batch训练之后的mean loss\n    train_acc = []\n    train_pbar = tqdm(train_loader, file=sys.stdout)\n\n    for x, y in train_pbar:\n        yhat = model(x)\n        loss = criterion(yhat, y)\n\n        optimizer.zero_grad()\n        # Compute the gradients for parameters.\n        loss.backward()\n        # Update the parameters with computed gradients.\n        optimizer.step()\n\n\n        accuracy = (yhat.argmax(dim=-1) == y).float().mean()\n        train_loss.append(loss.item())  # 记录每个batch训练之后的mean loss\n        train_acc.append(accuracy)\n\n        train_pbar.set_description(f\"Epoch [{epoch + 1}/{n_epochs}]\")\n        train_pbar.set_postfix({\"loss \": loss.item()})  # 训练一个epoch过程中进度条打印训练完一个batch之后的loss\n\n    train_mean_loss = sum(train_loss) / len(train_loss)\n    train_mean_acc = sum(train_acc) / len(train_acc)\n    train_loss_epoch.append(train_mean_loss)\n    train_accuracy_epoch.append(train_mean_acc)\n\n    model.eval()\n    valid_loss = []\n    valid_acc = []\n    \n    for x, y in valid_loader:\n        yhat = model(x)\n        \n        with torch.no_grad():\n            loss = criterion(yhat, y)\n            \n        accuracy = (yhat.argmax(dim=-1) == y).float().mean()\n        valid_loss.append(loss.item())\n        valid_acc.append(accuracy)\n\n    valid_mean_loss = sum(valid_loss) / len(valid_loss)\n    valid_mean_acc = sum(valid_acc) / len(valid_acc) # 计算一个epoch里的平均acc\n    valid_loss_epoch.append(valid_mean_loss)\n    valid_accuracy_epoch.append(valid_mean_acc)\n    print(f\"Epoch [{epoch + 1}/{n_epochs}] Train Loss: {train_mean_loss:.3f} Valid Loss: {valid_mean_loss:.3f}\")","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-18T17:40:20.383612Z","iopub.execute_input":"2022-07-18T17:40:20.384019Z","iopub.status.idle":"2022-07-18T17:40:27.247494Z","shell.execute_reply.started":"2022-07-18T17:40:20.383985Z","shell.execute_reply":"2022-07-18T17:40:27.245990Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nplt.plot(range(n_epochs),train_loss_epoch)\nplt.plot(range(n_epochs),valid_loss_epoch)\nplt.legend(['train_loss','valid_loss'])\nplt.xlabel(\"epoch\")\nplt.ylabel(\"Loss\")\nplt.show()\n\nplt.plot(range(n_epochs),train_accuracy_epoch)\nplt.plot(range(n_epochs),valid_accuracy_epoch)\nplt.legend(['train_acc','valid_acc'])\nplt.xlabel(\"epoch\")\nplt.ylabel(\"acc\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:40:27.254281Z","iopub.execute_input":"2022-07-18T17:40:27.255540Z","iopub.status.idle":"2022-07-18T17:40:27.668257Z","shell.execute_reply.started":"2022-07-18T17:40:27.255482Z","shell.execute_reply":"2022-07-18T17:40:27.667121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4.预测并且提交结果","metadata":{}},{"cell_type":"code","source":"X_test = torch.tensor(combine[n_train:].values,dtype=torch.float32)\n\nwith torch.no_grad():\n    preds = model(X_test)\n    preds = torch.argmax(preds,axis=1)\nsubmission = pd.DataFrame({\n        \"PassengerId\": test_df['PassengerId'],\n        \"Survived\": preds\n    })\nsubmission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-18T17:26:13.993359Z","iopub.status.idle":"2022-07-18T17:26:13.993754Z","shell.execute_reply.started":"2022-07-18T17:26:13.993560Z","shell.execute_reply":"2022-07-18T17:26:13.993586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}