{"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","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Importing the Libraries\nimport numpy as np\nimport pandas as pd\nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom matplotlib import colors\nimport seaborn as sns\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.decomposition import PCA\nfrom sklearn.mixture import BayesianGaussianMixture,GaussianMixture\nfrom yellowbrick.cluster import KElbowVisualizer\nfrom sklearn.metrics import silhouette_score\nfrom sklearn.cluster import KMeans\nfrom sklearn.preprocessing import RobustScaler\n","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:09:08.014253Z","iopub.execute_input":"2022-07-06T05:09:08.015339Z","iopub.status.idle":"2022-07-06T05:09:08.021860Z","shell.execute_reply.started":"2022-07-06T05:09:08.015298Z","shell.execute_reply":"2022-07-06T05:09:08.020744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df=pd.read_csv(\"../input/tabular-playground-series-jul-2022/data.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:09:11.533510Z","iopub.execute_input":"2022-07-06T05:09:11.533894Z","iopub.status.idle":"2022-07-06T05:09:12.368496Z","shell.execute_reply.started":"2022-07-06T05:09:11.533864Z","shell.execute_reply":"2022-07-06T05:09:12.367478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.describe()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:09:13.896526Z","iopub.execute_input":"2022-07-06T05:09:13.896918Z","iopub.status.idle":"2022-07-06T05:09:14.101491Z","shell.execute_reply.started":"2022-07-06T05:09:13.896887Z","shell.execute_reply":"2022-07-06T05:09:14.100136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T04:46:28.123501Z","iopub.execute_input":"2022-07-06T04:46:28.123924Z","iopub.status.idle":"2022-07-06T04:46:28.153887Z","shell.execute_reply.started":"2022-07-06T04:46:28.123889Z","shell.execute_reply":"2022-07-06T04:46:28.152550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.dtypes","metadata":{"execution":{"iopub.status.busy":"2022-07-06T04:46:30.124547Z","iopub.execute_input":"2022-07-06T04:46:30.125056Z","iopub.status.idle":"2022-07-06T04:46:30.136251Z","shell.execute_reply.started":"2022-07-06T04:46:30.125010Z","shell.execute_reply":"2022-07-06T04:46:30.135232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Exploratory Data Analysis","metadata":{}},{"cell_type":"markdown","source":"# Data distribution:","metadata":{}},{"cell_type":"code","source":"#distribution of data\nfigure = plt.figure(figsize = (16,8))\nfor i in range(29):\n    feature_name = 'f_0{}'.format(i) if i < 10 else 'f_{}'.format(i) \n    plt.subplot(5, 6, i+1)\n    sns.kdeplot(df[feature_name], fill = True)        \nfigure.tight_layout(h_pad=1.0, w_pad=0.5)\nplt.suptitle('Distribution Plots', y=1.02)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-05T12:09:35.866929Z","iopub.execute_input":"2022-07-05T12:09:35.867402Z","iopub.status.idle":"2022-07-05T12:09:51.875351Z","shell.execute_reply.started":"2022-07-05T12:09:35.867367Z","shell.execute_reply":"2022-07-05T12:09:51.874457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Inference:**\n\nIt seems that every float feature is distributed normally. By contrast, that's not what happens when talking about ìnt features.","metadata":{}},{"cell_type":"markdown","source":"# Shapiro-Wilk Test for normality:","metadata":{}},{"cell_type":"markdown","source":"H0:A variable is normally distributed in some population.\n\nH1 : A variable is normally distributed in some population.\n\nReject the null hypothesis if p < 0.05","metadata":{}},{"cell_type":"code","source":"from scipy.stats import shapiro\nfrom termcolor import colored\n\n# We don't care about `id` feature column information\nfor col in df.columns[1:]:\n    stat, p_value = shapiro(df[col])  \n    alpha = 0.05\n    if p_value > alpha: \n        result = colored('Accepted', 'green')  \n    else:\n        result = colored('Rejected','red')        \n    print('Feature: {}\\t Hypothesis: {}'.format(col, result))","metadata":{"execution":{"iopub.status.busy":"2022-07-05T12:09:59.634383Z","iopub.execute_input":"2022-07-05T12:09:59.634751Z","iopub.status.idle":"2022-07-05T12:09:59.904641Z","shell.execute_reply.started":"2022-07-05T12:09:59.634721Z","shell.execute_reply":"2022-07-05T12:09:59.903519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Inference:**\n\nData is normally distributed in f_00,f_01,f_02,f_03,f_04,f_05,f_06,f_14,f_15,f_16,f_17,f_18,f_19,f_20,f_21\n\nData is not normally distributed in f_07,f_08,f_09,f_10,f_11,f_12,f_13,f_22,f_23,f_24,f_25,f_26,f_27,f_28","metadata":{}},{"cell_type":"markdown","source":"# Theoretical quantile charts (Q-Q charts)","metadata":{}},{"cell_type":"code","source":"from scipy import stats\nfigure = plt.figure(figsize = (16,8))\nfor i in range(29):\n    feature_name = 'f_0{}'.format(i) if i < 10 else 'f_{}'.format(i) \n    plt.subplot(5, 6, i+1)\n    stats.probplot(df[feature_name], plot=plt)   \n    plt.title(feature_name)\nfigure.tight_layout(h_pad=1.0, w_pad=0.5)\nplt.suptitle('Q-Q Charts', y=1.02)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-05T12:10:03.290286Z","iopub.execute_input":"2022-07-05T12:10:03.29077Z","iopub.status.idle":"2022-07-05T12:10:12.170767Z","shell.execute_reply.started":"2022-07-05T12:10:03.290727Z","shell.execute_reply":"2022-07-05T12:10:12.169466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Inference:**\n\nA normal probability plot, or more specifically a quantile-quantile (Q-Q) plot, shows the distribution of the data against the expected normal distribution. For normally distributed data, observations should lie approximately on a straight line.\n\nWe can infer columns which is normally distributed and which is not , for normally distributed columns the data points whill lie in one line or close to RED line.","metadata":{}},{"cell_type":"markdown","source":"# Boxplot","metadata":{}},{"cell_type":"code","source":"figure = plt.figure(figsize = (16,8))\nfor i in range(29):\n    feature_name = 'f_0{}'.format(i) if i < 10 else 'f_{}'.format(i) \n    plt.subplot(5, 6, i+1)\n    sns.boxplot(data=df[feature_name])   \n    plt.title(feature_name)\nfigure.tight_layout(h_pad=1.0, w_pad=0.5)\nplt.suptitle('BOX plot', y=1.02)\nplt.show()\n\n\n\n\n","metadata":{"execution":{"iopub.status.busy":"2022-07-05T12:19:12.843065Z","iopub.execute_input":"2022-07-05T12:19:12.843608Z","iopub.status.idle":"2022-07-05T12:19:16.364526Z","shell.execute_reply.started":"2022-07-05T12:19:12.843561Z","shell.execute_reply":"2022-07-05T12:19:16.36312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Inference:**\n\nThese box plots shows the outliers as well as the distribution of data","metadata":{}},{"cell_type":"markdown","source":"# Skewness and Kurtosis","metadata":{}},{"cell_type":"markdown","source":"Skewness = 0: Then normally distributed.\n\nSkewness > 0: Then more weight in the left tail of the distribution.\n\nSkewness < 0: Then more weight in the right tail of the distribution.\n\n\n","metadata":{}},{"cell_type":"markdown","source":"kurtosis for normal distribution is equal to 3.\n\nFor a distribution having kurtosis < 3: It is called playkurtic.\n\nFor a distribution having kurtosis > 3, It is called leptokurtic and it signifies that it tries to produce more outliers rather than the normal distribution.","metadata":{}},{"cell_type":"code","source":"df.skew(axis=0)","metadata":{"execution":{"iopub.status.busy":"2022-07-05T12:11:02.14688Z","iopub.execute_input":"2022-07-05T12:11:02.147401Z","iopub.status.idle":"2022-07-05T12:11:02.246882Z","shell.execute_reply.started":"2022-07-05T12:11:02.147359Z","shell.execute_reply":"2022-07-05T12:11:02.245849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.kurt(axis=0)","metadata":{"execution":{"iopub.status.busy":"2022-07-05T12:11:04.506724Z","iopub.execute_input":"2022-07-05T12:11:04.507637Z","iopub.status.idle":"2022-07-05T12:11:04.584562Z","shell.execute_reply.started":"2022-07-05T12:11:04.507546Z","shell.execute_reply":"2022-07-05T12:11:04.583094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Inference:**\n\nSkewness and kurtosis makes evident that data contains outliers and asymmetry.\n\nSkewness is a measure of the asymmetry of the probability distribution of real-valued random variable.\n\nkurtosis is a measure of the \"tailedness\" of the probability distribution of a real-valued random variable.","metadata":{}},{"cell_type":"markdown","source":"# Correlation heat map","metadata":{}},{"cell_type":"code","source":"corr = df.corr()\nmask = np.triu(np.ones_like(corr, dtype=bool))\nf, ax = plt.subplots(figsize=(20,20))\nax = sns.heatmap(\n    corr, mask=mask,\n    vmin=-1, vmax=1, center=0,annot=True,\n    cmap=sns.diverging_palette(20, 220, n=200),\n    square=True,fmt='.2f'\n)\nax.set_xticklabels(\n    ax.get_xticklabels(),\n    rotation=45,\n    horizontalalignment='right'\n);","metadata":{"execution":{"iopub.status.busy":"2022-07-05T12:11:09.194257Z","iopub.execute_input":"2022-07-05T12:11:09.194707Z","iopub.status.idle":"2022-07-05T12:11:11.74566Z","shell.execute_reply.started":"2022-07-05T12:11:09.194672Z","shell.execute_reply":"2022-07-05T12:11:11.74444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**inference :**\n\nint features are the ones having higher correlation coefficients.\n\nMost correlated features are f_09 and f_08. They're inversely related.then we have f_12 & f_09 , f_13 & f_09 inversly related ..\n","metadata":{}},{"cell_type":"markdown","source":"\n# Scaling of data","metadata":{}},{"cell_type":"markdown","source":"Standard Scalar:\n\nBefore applying PCA or any other Machine Learning technique it is always considered good practice to standardize the data. For this, Standard Scalar is the most commonly used scalar. Standard Scalar is already present in sklearn. So, now we will standardize the feature set using Standard Scalar and store the scaled feature set as a pandas data frame.","metadata":{}},{"cell_type":"code","source":"scalar = RobustScaler()\nscaled_data = pd.DataFrame(scalar.fit_transform(df)) #scaling the data\nscaled_data","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:09:28.872600Z","iopub.execute_input":"2022-07-06T05:09:28.872978Z","iopub.status.idle":"2022-07-06T05:09:29.057203Z","shell.execute_reply.started":"2022-07-06T05:09:28.872947Z","shell.execute_reply":"2022-07-06T05:09:29.056028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Check the Co-relation between features without PCA\nsns.heatmap(scaled_data.corr())","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:09:35.709754Z","iopub.execute_input":"2022-07-06T05:09:35.710105Z","iopub.status.idle":"2022-07-06T05:09:36.465635Z","shell.execute_reply.started":"2022-07-06T05:09:35.710077Z","shell.execute_reply":"2022-07-06T05:09:36.464496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dimensionality Reduction:PCA","metadata":{}},{"cell_type":"code","source":"X=PCA()\npca_values=X.fit_transform(scaled_data)","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:10:44.420659Z","iopub.execute_input":"2022-07-06T05:10:44.421140Z","iopub.status.idle":"2022-07-06T05:10:44.659172Z","shell.execute_reply.started":"2022-07-06T05:10:44.421091Z","shell.execute_reply":"2022-07-06T05:10:44.657691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#shape of PCA model\npca_values.shape","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:11:06.053774Z","iopub.execute_input":"2022-07-06T05:11:06.054282Z","iopub.status.idle":"2022-07-06T05:11:06.061712Z","shell.execute_reply.started":"2022-07-06T05:11:06.054235Z","shell.execute_reply":"2022-07-06T05:11:06.060943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#convert into data frame\npcs=pd.DataFrame(pca_values)\npcs.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:12:55.635346Z","iopub.execute_input":"2022-07-06T05:12:55.636551Z","iopub.status.idle":"2022-07-06T05:12:55.666309Z","shell.execute_reply.started":"2022-07-06T05:12:55.636499Z","shell.execute_reply":"2022-07-06T05:12:55.665196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#The amount of variance of each PCA\nvar=X.explained_variance_ratio_\nvar","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:14:23.675287Z","iopub.execute_input":"2022-07-06T05:14:23.675718Z","iopub.status.idle":"2022-07-06T05:14:23.683809Z","shell.execute_reply.started":"2022-07-06T05:14:23.675685Z","shell.execute_reply":"2022-07-06T05:14:23.682900Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#componenets of PCA ie weights convert as data frame\nwts = pd.DataFrame(X.components_)\nwts.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:15:55.210958Z","iopub.execute_input":"2022-07-06T05:15:55.211465Z","iopub.status.idle":"2022-07-06T05:15:55.248851Z","shell.execute_reply.started":"2022-07-06T05:15:55.211418Z","shell.execute_reply":"2022-07-06T05:15:55.247738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#find cumulative variance\nvar1=np.cumsum(np.round(var,decimals=4)*100)\nvar1","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:16:49.409064Z","iopub.execute_input":"2022-07-06T05:16:49.409633Z","iopub.status.idle":"2022-07-06T05:16:49.417883Z","shell.execute_reply.started":"2022-07-06T05:16:49.409598Z","shell.execute_reply":"2022-07-06T05:16:49.416708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"var","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:18:15.640922Z","iopub.execute_input":"2022-07-06T05:18:15.641317Z","iopub.status.idle":"2022-07-06T05:18:15.650063Z","shell.execute_reply.started":"2022-07-06T05:18:15.641288Z","shell.execute_reply":"2022-07-06T05:18:15.649051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Variance plot for PCA components as obtained:","metadata":{}},{"cell_type":"code","source":"plt.plot(var,color='red')\nplt.plot(var1,color='blue')","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:19:23.225565Z","iopub.execute_input":"2022-07-06T05:19:23.225952Z","iopub.status.idle":"2022-07-06T05:19:23.396489Z","shell.execute_reply.started":"2022-07-06T05:19:23.225922Z","shell.execute_reply":"2022-07-06T05:19:23.395681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Inference :**\n\nPCA components are from 0 to 29 , if we take PCA components from 0 to 27 we are getting 96.75 % as cumulative varieance. Hence PC0 to PC 27 is considered for new data frame","metadata":{}},{"cell_type":"markdown","source":"\n","metadata":{}},{"cell_type":"code","source":"# convert PCA values to Data frame\nnew_df=pd.DataFrame(pca_values[:,0:28])\nnew_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:25:26.377170Z","iopub.execute_input":"2022-07-06T05:25:26.377698Z","iopub.status.idle":"2022-07-06T05:25:26.408110Z","shell.execute_reply.started":"2022-07-06T05:25:26.377657Z","shell.execute_reply":"2022-07-06T05:25:26.406947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Checking Co-relation between features after PCA\nsns.heatmap(new_df.corr())","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:36:09.347610Z","iopub.execute_input":"2022-07-06T05:36:09.348309Z","iopub.status.idle":"2022-07-06T05:36:10.147241Z","shell.execute_reply.started":"2022-07-06T05:36:09.348272Z","shell.execute_reply":"2022-07-06T05:36:10.146150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Optimal K value - Elbow method","metadata":{}},{"cell_type":"code","source":"### Elbow Method for K means\n# Import ElbowVisualizer\nfrom yellowbrick.cluster import KElbowVisualizer\nmodel = KMeans(random_state=42)\n# k is range of number of clusters.\nvisualizer = KElbowVisualizer(model, k=(2,15), timings= True)\nvisualizer.fit(new_df)        # Fit data to visualizer\nvisualizer.show()        # Finalize and render figure","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:34:16.985662Z","iopub.execute_input":"2022-07-06T05:34:16.986065Z","iopub.status.idle":"2022-07-06T05:36:05.048036Z","shell.execute_reply.started":"2022-07-06T05:34:16.986033Z","shell.execute_reply":"2022-07-06T05:36:05.047035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Inference:**\n\nOptimal value for k is 6 as per elbow method","metadata":{}},{"cell_type":"markdown","source":"# Kmeans with 6 clusters","metadata":{}},{"cell_type":"code","source":"model = KMeans(6)\nmodel.fit(new_df)","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:52:13.725517Z","iopub.execute_input":"2022-07-06T05:52:13.726035Z","iopub.status.idle":"2022-07-06T05:52:19.384657Z","shell.execute_reply.started":"2022-07-06T05:52:13.726000Z","shell.execute_reply":"2022-07-06T05:52:19.383256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred = model.fit_predict(new_df)\npred","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:53:31.611052Z","iopub.execute_input":"2022-07-06T05:53:31.611497Z","iopub.status.idle":"2022-07-06T05:53:37.707071Z","shell.execute_reply.started":"2022-07-06T05:53:31.611462Z","shell.execute_reply":"2022-07-06T05:53:37.705750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['Predicted']=pred\ndf.loc[:,['id','Predicted']].head()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:55:56.379454Z","iopub.execute_input":"2022-07-06T05:55:56.380517Z","iopub.status.idle":"2022-07-06T05:55:56.399048Z","shell.execute_reply.started":"2022-07-06T05:55:56.380458Z","shell.execute_reply":"2022-07-06T05:55:56.397801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#distribution of clusters\npl = sns.countplot(x=df[\"Predicted\"])\npl.set_title(\"Distribution Of The Clusters\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:57:48.267773Z","iopub.execute_input":"2022-07-06T05:57:48.268200Z","iopub.status.idle":"2022-07-06T05:57:48.538954Z","shell.execute_reply.started":"2022-07-06T05:57:48.268169Z","shell.execute_reply":"2022-07-06T05:57:48.537269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission=df.loc[:,['id','Predicted']]\nsubmission.shape\n","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:56:37.474500Z","iopub.execute_input":"2022-07-06T05:56:37.474980Z","iopub.status.idle":"2022-07-06T05:56:37.487397Z","shell.execute_reply.started":"2022-07-06T05:56:37.474945Z","shell.execute_reply":"2022-07-06T05:56:37.485497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-06T05:59:26.409588Z","iopub.execute_input":"2022-07-06T05:59:26.410006Z","iopub.status.idle":"2022-07-06T05:59:26.584339Z","shell.execute_reply.started":"2022-07-06T05:59:26.409974Z","shell.execute_reply":"2022-07-06T05:59:26.582825Z"},"trusted":true},"execution_count":null,"outputs":[]}]}