{"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 in \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 \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-08T01:33:39.369460Z","iopub.execute_input":"2022-01-08T01:33:39.370026Z","iopub.status.idle":"2022-01-08T01:33:39.396565Z","shell.execute_reply.started":"2022-01-08T01:33:39.369948Z","shell.execute_reply":"2022-01-08T01:33:39.395245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Tên cuộc thi được chọn: LANL Earthquake Prediction\n# Mô tả bài toán\nBài toán yêu cầu từ một dãy các kết quả dữ liệu âm thanh đầu vào, dự đoán thời gian còn lại trước khi xảy ra động đất\n\n## Input:\nLà một mảng có 150_000 dòng, chỉ gồm một giá trị là acoustic_data - dữ liệu âm thanh. Các giá trị thuộc kiểu int16.\n\n## Output: \nMột giá trị duy nhất là thời gian còn lại trước khi xảy ra động đất. Giá trị thuộc kiểu float64.\n\n# Mô tả dữ liệu cuộc thi\n## train.csv\nLà file chứa 629145481 dòng và 2 cột, là acoustic_data và time_to_failure. Các giá trị được lấy từ các thí nghiệm nghiên cứu động đất.\n\nAcoustic_data là các dữ liệu âm thanh được lấy liên tục, còn time_to_failure là thời gian còn lại trước khi động đất tương ứng thời điểm acoustic_data được lấy.\n\n## test\nLà tệp chứa 2624 tệp để dự đoán. Mỗi tệp sẽ chứa 150_000 dòng và chỉ gồm 1 cột là acoustic_data.\n\n## sample_submission.csv\nLà file nộp mẫu.","metadata":{}},{"cell_type":"code","source":"from tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:33:39.398168Z","iopub.execute_input":"2022-01-08T01:33:39.398437Z","iopub.status.idle":"2022-01-08T01:33:39.419172Z","shell.execute_reply.started":"2022-01-08T01:33:39.398392Z","shell.execute_reply":"2022-01-08T01:33:39.418283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n# Tổng số dòng dữ liệu\ntotal = 629145481 \n# Số dữ liệu được tính mỗi bước.\nchunksize = 150_000\n\n# Tải dữ liệu sử dụng chunk, do nếu tải hết dữ liệu vào trong lúc Editing Noteboong thì sẽ báo lỗi.\nchunks = pd.read_csv('../input/train.csv', dtype={'acoustic_data': np.int16, 'time_to_failure': np.float64}, chunksize = chunksize)\n\nc = 1\n\nsegments = total // chunksize\n    \n# Segment là số lượng đoạn được lấy từ input.\n# Các chunk được load sau đó tiền xử lý luôn luôn.\n\n# Hiển thị đến độ chính xác 15 chữ số sau dấu phẩy.\npd.options.display.precision = 15","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:33:39.420320Z","iopub.execute_input":"2022-01-08T01:33:39.420765Z","iopub.status.idle":"2022-01-08T01:33:39.457316Z","shell.execute_reply.started":"2022-01-08T01:33:39.420716Z","shell.execute_reply":"2022-01-08T01:33:39.456707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Khám phá dữ liệu phân tích - Exploratory Data Analysis","metadata":{}},{"cell_type":"markdown","source":"Import các thư viện trực quan hóa sẽ sử dụng","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt \nimport seaborn as sns \n\nplt.style.use('seaborn')","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:33:39.459823Z","iopub.execute_input":"2022-01-08T01:33:39.460171Z","iopub.status.idle":"2022-01-08T01:33:40.424820Z","shell.execute_reply.started":"2022-01-08T01:33:39.460116Z","shell.execute_reply":"2022-01-08T01:33:40.423770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Do dữ liệu rất nhiều, nên báo cáo thực hiện nhóm mỗi 150000 dữ liệu thành một nhóm, và sử dụng max của mỗi nhóm để trực quan hóa trên biểu đồ.\n\nLý do sử dụng max do thực nhiệm cho thấy khi sử dụng mean, các giá trị thu được không đủ tốt để quan sát xu hướng và tính chất. Sử dụng max sẽ giúp thể hiện rõ các bất thường hơn.","metadata":{}},{"cell_type":"code","source":"%%time\ntrain = []\ntrain_df = None\n\ny = pd.DataFrame(index=range(segments), dtype=np.float64, columns=['time_to_failure'])\n\nrows = 150_000\n\nfor segment in tqdm(range(segments)):\n    chunk = next(chunks)\n    # AD của mỗi chunk.\n    ad = chunk['acoustic_data']\n    # TTF của mỗi chunk. Là đầu ra cần phải dự đoán.\n    y.loc[segment, 'time_to_failure'] = chunk['time_to_failure'].values[-1]\n    \n    # Tính các đặc trung\n    features = dict()\n    # Tính đặc trưng max của dữ liệu.\n    features['max'] = np.max(ad)\n    features['mean'] = np.mean(ad)\n    # Thêm đặc trưng vào mảng train.\n    train.append(features)\n    \n    # Chỉ lấy của 1000 segment đầu.\n    if segment < 1000:\n        if train_df is None:\n            train_df = chunk\n        else:\n            train_df = train_df.append(chunk, ignore_index=True)\n        del chunk\n    \nX = pd.DataFrame(train)","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:33:40.426494Z","iopub.execute_input":"2022-01-08T01:33:40.426818Z","iopub.status.idle":"2022-01-08T01:49:31.954859Z","shell.execute_reply.started":"2022-01-08T01:33:40.426763Z","shell.execute_reply":"2022-01-08T01:49:31.954051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(X.index * rows, X[\"max\"], label=\"acoustic_data\")\nplt.plot(y.index * rows, y[\"time_to_failure\"] * 200, label=\"time_to_failure\", color='orange')\n\nplt.title(\"Biểu đồ quan hệ giữa max AD và thời gian còn lại\")\nplt.legend()\nplt.show()","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-01-08T01:49:31.956484Z","iopub.execute_input":"2022-01-08T01:49:31.956805Z","iopub.status.idle":"2022-01-08T01:49:32.409964Z","shell.execute_reply.started":"2022-01-08T01:49:31.956745Z","shell.execute_reply":"2022-01-08T01:49:32.409136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(X.index * rows, X[\"mean\"], label=\"acoustic_data\")\nplt.plot(y.index * rows, y[\"time_to_failure\"], label=\"time_to_failure\", color='orange')\n\nplt.title(\"Biểu đồ quan hệ giữa trung bình AD và TTF\")\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:49:32.411277Z","iopub.execute_input":"2022-01-08T01:49:32.411551Z","iopub.status.idle":"2022-01-08T01:49:32.812750Z","shell.execute_reply.started":"2022-01-08T01:49:32.411486Z","shell.execute_reply":"2022-01-08T01:49:32.811431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(X.loc[:400].index * rows, X.loc[:400, \"max\"].values, label=\"acoustic_data\")\nplt.plot(y.loc[:400].index * rows, y.loc[:400, \"time_to_failure\"].values * 200, label=\"time_to_failure\", color='orange')\n\nplt.title(\"Biểu đồ quan hệ giữa max AD và thời gian còn lại trong 400 dòng đầu tiên\")\nplt.legend()\nplt.show()","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-01-08T01:49:32.814787Z","iopub.execute_input":"2022-01-08T01:49:32.815175Z","iopub.status.idle":"2022-01-08T01:49:33.133105Z","shell.execute_reply.started":"2022-01-08T01:49:32.815104Z","shell.execute_reply":"2022-01-08T01:49:33.132307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Quy ước khái niệm\nBáo cáo sẽ định nghĩa một số khái niệm để thuận tiện hơn trong quá trình phân tích sau này.\n- Quá trình động đất - Session: là khoảng thời gian bắt đầu khi ttf tăng đột biến, đến khi ttf về gần với 0. Như biểu đồ, các quá trình động đất sẽ luôn nối tiếp nhau.\n- Failure: quá trình cuối của session, khi mà ad đạt đến một giá trị rất lớn rồi giảm mạnh về rất thấp. Như trong khi biểu đồ, có nhiều vị trí mà ad tăng bất thường, nhưng không phải failure (ttf không về 0 ở các trường hợp đó)\n- Loading: quá trình đầu của session, quá trình mà ad có dấu hiệu tăng dần, đến ngay trước khi Failure xảy ra.\n\n## Phân tích biểu đồ\nQuan sát các biểu đồ, báo cáo rút ra được các kết luận:\n\n- Trước mỗi quá trình động đất mới, giá trị của ad sẽ tăng đột biến.\n- Trong quá trình động đất, các giá trị của ad ở giữa cũng có xu hướng tăng dần, thỉnh thoảng sẽ có một vài giá trị cao một cách bất bình thường, tuy nhiên vẫn nhỏ hơn giá trị của acoustic data cao nhất gần vị trí cuối của quá trình động đất đó.\n- Giá trị của ttf có xu hướng giảm ở cùng một tốc độ.\n- Giá trị mean của ad nhỏ (<6) và không thể hiện được nhiều xu hướng.","metadata":{}},{"cell_type":"markdown","source":"## Kiểm tra sự thay đổi giá trị của ttf (time to failure) trong cùng một quá trình động đất","metadata":{}},{"cell_type":"code","source":"plt.plot(train_df.iloc[:50000].index, train_df.iloc[:50000, 1].values)\nplt.title(\"Biểu đồ giá trị của acoustic data trong 50_000 dòng đầu tiên\")\nplt.show()","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-01-08T01:49:33.134265Z","iopub.execute_input":"2022-01-08T01:49:33.134687Z","iopub.status.idle":"2022-01-08T01:49:33.418779Z","shell.execute_reply.started":"2022-01-08T01:49:33.134629Z","shell.execute_reply":"2022-01-08T01:49:33.417757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dt = train_df.iloc[:50000]\ndt['diff'] = dt['time_to_failure'] - dt['time_to_failure'].shift(periods=1).fillna(0)","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-01-08T01:49:33.420420Z","iopub.execute_input":"2022-01-08T01:49:33.421011Z","iopub.status.idle":"2022-01-08T01:49:33.495219Z","shell.execute_reply.started":"2022-01-08T01:49:33.420939Z","shell.execute_reply":"2022-01-08T01:49:33.494469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dt[dt[\"diff\"] < -0.0004]","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-01-08T01:49:33.496802Z","iopub.execute_input":"2022-01-08T01:49:33.497080Z","iopub.status.idle":"2022-01-08T01:49:33.523479Z","shell.execute_reply.started":"2022-01-08T01:49:33.497027Z","shell.execute_reply":"2022-01-08T01:49:33.522646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Báo cáo nhận thấy rằng các dữ liệu thay đổi theo từng block các dòng. Mỗi block dữ liệu sẽ có 4096 dữ liệu. Trong đó sự khác biệt giữa những dữ liệu nằm trong cùng một nhóm là rất nhỏ (-0.0000000011)\n\nGiữa 2 nhóm dữ liệu khác nhau, chênh lệch lớn hơn (-0.0009954955 và -0.0010954955), dù vậy, sự giảm thời gian khi chuyển block cũng không đều (như bảng trên). Sai khác vào khoảng 0.0001.\n\nTheo như trong paper được cung cấp, mỗi khi xảy ra failure, stress tác dụng lên đá sẽ giảm, sao đó tăng trở lại. Khi stress đến một mức nào đó, failure sẽ xảy ra.","metadata":{}},{"cell_type":"code","source":"# Tính chênh lệch giá trị giữa 2 time_to_failure liền kề.\nn_block = 500\ndiff = len(train_df) // n_block\n\ndecay_rate = np.zeros(len(train_df))\n\nfor i in tqdm(range(n_block)):\n    df = train_df.iloc[diff * i: diff * (i + 1)]\n    val = df['time_to_failure'] - df['time_to_failure'].shift(periods=1).fillna(999)\n    \n    decay_rate[diff * i: diff * (i + 1)] = val.values","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:49:33.524660Z","iopub.execute_input":"2022-01-08T01:49:33.524903Z","iopub.status.idle":"2022-01-08T01:49:37.414543Z","shell.execute_reply.started":"2022-01-08T01:49:33.524861Z","shell.execute_reply":"2022-01-08T01:49:37.413758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Khử đi giá trị bị Nan. \ndecay_rate = decay_rate[decay_rate > -100]","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:49:37.415707Z","iopub.execute_input":"2022-01-08T01:49:37.415930Z","iopub.status.idle":"2022-01-08T01:49:40.031414Z","shell.execute_reply.started":"2022-01-08T01:49:37.415890Z","shell.execute_reply":"2022-01-08T01:49:40.030604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Đưa về DataFrame \ndecay_rate = pd.DataFrame(decay_rate, columns=[\"values\"])\ndecay_rate.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:49:40.032488Z","iopub.execute_input":"2022-01-08T01:49:40.032731Z","iopub.status.idle":"2022-01-08T01:49:40.045731Z","shell.execute_reply.started":"2022-01-08T01:49:40.032691Z","shell.execute_reply":"2022-01-08T01:49:40.044862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Sự chênh lệch thường rất nhỏ, nhỏ hơn 1e-8.","metadata":{}},{"cell_type":"code","source":"# Liệt kê tất cả các thời điểm xảy ra failure.\n\nabnomal_drate = decay_rate[decay_rate['values'] > 1]\nabnomal_drate","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:49:40.047001Z","iopub.execute_input":"2022-01-08T01:49:40.047282Z","iopub.status.idle":"2022-01-08T01:49:41.130407Z","shell.execute_reply.started":"2022-01-08T01:49:40.047231Z","shell.execute_reply":"2022-01-08T01:49:41.129777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Khoảng cách giữa 2 lần xảy ra failure liên tiếp\n\nfor i in range(len(abnomal_drate.index) - 1):\n    print(abnomal_drate.index[i + 1] - abnomal_drate.index[i])","metadata":{"execution":{"iopub.status.busy":"2022-01-08T01:49:41.131562Z","iopub.execute_input":"2022-01-08T01:49:41.131968Z","iopub.status.idle":"2022-01-08T01:49:41.137766Z","shell.execute_reply.started":"2022-01-08T01:49:41.131921Z","shell.execute_reply":"2022-01-08T01:49:41.136649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Với mỗi session, chỉ có duy nhất một vị trí mà sự chênh lệch lớn hơn 1.\n\nSố iter giữa 2 failure là rất lớn (tầm chục triệu trở lên), do đó có thể giới hạn bộ nhớ của Kaggle notebook.\n\n### Thắc mắc: \nỞ những chỗ ngay sau failure, là lúc mà giá trị của ad rất nhỏ, nhưng cũng là lúc ttf biến động nhiều nhất, liệu với các giá trị ad có làm ảnh hưởng tới ttf giai đoạn này hay không ?","metadata":{"execution":{"iopub.status.busy":"2021-12-24T13:40:46.606578Z","iopub.execute_input":"2021-12-24T13:40:46.606913Z","iopub.status.idle":"2021-12-24T13:40:46.613239Z","shell.execute_reply.started":"2021-12-24T13:40:46.606867Z","shell.execute_reply":"2021-12-24T13:40:46.611669Z"}}},{"cell_type":"code","source":"plt.subplots(figsize=(30, 10))\n\nfor i in tqdm(range(len(abnomal_drate))):\n    start_index = abnomal_drate.index[i] + 3\n    end_index = abnomal_drate.index[i] + 150003\n    \n    try:\n        x = train_df.iloc[start_index: end_index, 0] / 50\n        y = train_df.iloc[end_index - 1, 1]\n\n        plt.plot(range(150000), x + 4 * i, label=str(y))\n\n        del x\n        del y\n    except Exception as e:\n        print(e)\n\nplt.legend()\nplt.show()\n","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-01-08T01:49:41.139735Z","iopub.execute_input":"2022-01-08T01:49:41.139986Z","iopub.status.idle":"2022-01-08T01:49:42.792359Z","shell.execute_reply.started":"2022-01-08T01:49:41.139932Z","shell.execute_reply":"2022-01-08T01:49:42.791623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Nhận xét biểu đồ:\n\nTrong 150 000 iter ngay sau một Failure, ta thấy rằng những tín hiệu nào càng có nhiều biến động thì thời gian xảy ra càng lâu ? (như với tín hiệu màu tím (12.66s) hay màu xanh dương (11.5s), tuy nhiên với màu xanh dương, những tín hiệu bất thường xảy ra từ sớm, mức độ biến động của tín hiệu không cao, tuy nhiên thời gian xảy ra lại là cao nhất (14.14s).\n\nVề cách ttf được lấy: liệu ttf được tính bằng thời gian xảy ra failure rồi trace back về iter hiện tại, hay ngay từ đầu đã xác định được ttf rồi ?, nếu nói ngay từ đầu đã tìm được ttf thì không hợp lý, do tính giảm đều ở ttf qua các iter, và việc ttf nó thế nào phụ thuộc vào thực nghiệm của failure chứ không phải tính từ đầu.\n\nVậy là hiểu một cách lý tính thì rất khó để từ một đoạn tính hiệu ban đầu suy ra ttf được, và nếu test case mà bao gồm các đoạn ngay sau failure thì thực sự là rất khó đoán.\n\nDựa vào biểu đồ ở  [link này](https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/2017GL074677) thì tại mỗi failure, stress sẽ bị giảm, sau đó lại tăng cho đến khi gặp một failure khác.","metadata":{}}]}