You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
581 lines
19 KiB
581 lines
19 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Pengenalan kepada Kebarangkalian dan Statistik\n",
|
|
"Dalam buku nota ini, kita akan bermain-main dengan beberapa konsep yang telah kita bincangkan sebelum ini. Banyak konsep daripada kebarangkalian dan statistik diwakili dengan baik dalam perpustakaan utama untuk pemprosesan data dalam Python, seperti `numpy` dan `pandas`.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"import pandas as pd\n",
|
|
"import random\n",
|
|
"import matplotlib.pyplot as plt"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Pembolehubah Rawak dan Taburan\n",
|
|
"Mari kita mulakan dengan mengambil sampel 30 nilai dari taburan seragam dari 0 hingga 9. Kita juga akan mengira min dan varians.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"sample = [ random.randint(0,10) for _ in range(30) ]\n",
|
|
"print(f\"Sample: {sample}\")\n",
|
|
"print(f\"Mean = {np.mean(sample)}\")\n",
|
|
"print(f\"Variance = {np.var(sample)}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Untuk menganggar secara visual berapa banyak nilai berbeza yang terdapat dalam sampel, kita boleh plot **histogram**:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.hist(sample)\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Menganalisis Data Sebenar\n",
|
|
"\n",
|
|
"Min dan varians adalah sangat penting apabila menganalisis data dunia sebenar. Mari muatkan data tentang pemain besbol dari [SOCR MLB Height/Weight Data](http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_MLB_HeightsWeights)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"df = pd.read_csv(\"../../data/SOCR_MLB.tsv\",sep='\\t', header=None, names=['Name','Team','Role','Weight','Height','Age'])\n",
|
|
"df\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"> Kami menggunakan pakej yang dipanggil [**Pandas**](https://pandas.pydata.org/) di sini untuk analisis data. Kami akan bercakap lebih lanjut mengenai Pandas dan bekerja dengan data dalam Python kemudian dalam kursus ini.\n",
|
|
"\n",
|
|
"Mari kita kira nilai purata untuk umur, ketinggian dan berat:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"df[['Age','Height','Weight']].mean()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Sekarang mari kita fokus pada ketinggian, dan kira sisihan piawai serta varians:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"print(list(df['Height'])[:20])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"mean = df['Height'].mean()\n",
|
|
"var = df['Height'].var()\n",
|
|
"std = df['Height'].std()\n",
|
|
"print(f\"Mean = {mean}\\nVariance = {var}\\nStandard Deviation = {std}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Selain daripada min, adalah munasabah untuk melihat nilai median dan kuartil. Ia boleh divisualisasikan menggunakan **graf kotak**:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.figure(figsize=(10,2))\n",
|
|
"plt.boxplot(df['Height'].ffill(), vert=False, showmeans=True)\n",
|
|
"plt.grid(color='gray', linestyle='dotted')\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Kita juga boleh membuat plot kotak bagi subset dataset kita, contohnya, dikelompokkan mengikut peranan pemain.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"df.boxplot(column='Height', by='Role', figsize=(10,8))\n",
|
|
"plt.xticks(rotation='vertical')\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"> **Nota**: Rajah ini mencadangkan, secara purata, ketinggian pemain pertama lebih tinggi daripada ketinggian pemain kedua. Nanti kita akan belajar bagaimana kita boleh menguji hipotesis ini dengan lebih formal, dan bagaimana untuk menunjukkan bahawa data kita adalah signifikan secara statistik untuk membuktikannya. \n",
|
|
"\n",
|
|
"Umur, ketinggian dan berat semua adalah pembolehubah rawak berterusan. Apakah agaknya taburan mereka? Cara yang baik untuk mengetahuinya ialah dengan melukis histogram nilai-nilai tersebut: \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"df['Weight'].hist(bins=15, figsize=(10,6))\n",
|
|
"plt.suptitle('Weight distribution of MLB Players')\n",
|
|
"plt.xlabel('Weight')\n",
|
|
"plt.ylabel('Count')\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Taburan Normal\n",
|
|
"\n",
|
|
"Mari kita cipta sampel buatan berat yang mengikuti taburan normal dengan min dan varians yang sama seperti data sebenar kita:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"generated = np.random.normal(mean, std, 1000)\n",
|
|
"generated[:20]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.figure(figsize=(10,6))\n",
|
|
"plt.hist(generated, bins=15)\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.figure(figsize=(10,6))\n",
|
|
"plt.hist(np.random.normal(0,1,50000), bins=300)\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Oleh kerana kebanyakan nilai dalam kehidupan sebenar diedarkan secara normal, kita tidak seharusnya menggunakan penjana nombor rawak seragam untuk menjana data sampel. Berikut adalah apa yang berlaku jika kita cuba menjana berat dengan taburan seragam (dijana oleh `np.random.rand`):\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"wrong_sample = np.random.rand(1000)*2*std+mean-std\n",
|
|
"plt.figure(figsize=(10,6))\n",
|
|
"plt.hist(wrong_sample)\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Selang Keyakinan\n",
|
|
"\n",
|
|
"Mari kita kira selang keyakinan untuk berat dan ketinggian pemain besbol. Kita akan menggunakan kod [dari perbincangan stackoverflow ini](https://stackoverflow.com/questions/15033511/compute-a-confidence-interval-from-sample-data):\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import scipy.stats\n",
|
|
"\n",
|
|
"def mean_confidence_interval(data, confidence=0.95):\n",
|
|
" a = 1.0 * np.array(data)\n",
|
|
" n = len(a)\n",
|
|
" m, se = np.mean(a), scipy.stats.sem(a)\n",
|
|
" h = se * scipy.stats.t.ppf((1 + confidence) / 2., n-1)\n",
|
|
" return m, h\n",
|
|
"\n",
|
|
"for p in [0.85, 0.9, 0.95]:\n",
|
|
" m, h = mean_confidence_interval(df['Weight'].fillna(method='pad'),p)\n",
|
|
" print(f\"p={p:.2f}, mean = {m:.2f} ± {h:.2f}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Ujian Hipotesis\n",
|
|
"\n",
|
|
"Mari kita terokai peranan berbeza dalam set data pemain besbol kami:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"df.groupby('Role').agg({ 'Weight' : 'mean', 'Height' : 'mean', 'Age' : 'count'}).rename(columns={ 'Age' : 'Count'})"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Mari uji hipotesis bahawa Pemain Pertama Bas lebih tinggi daripada Pemain Kedua Bas. Cara paling mudah untuk melakukan ini adalah dengan menguji selang keyakinan:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"for p in [0.85,0.9,0.95]:\n",
|
|
" m1, h1 = mean_confidence_interval(df.loc[df['Role']=='First_Baseman',['Height']],p)\n",
|
|
" m2, h2 = mean_confidence_interval(df.loc[df['Role']=='Second_Baseman',['Height']],p)\n",
|
|
" print(f'Conf={p:.2f}, 1st basemen height: {m1-h1[0]:.2f}..{m1+h1[0]:.2f}, 2nd basemen height: {m2-h2[0]:.2f}..{m2+h2[0]:.2f}')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Kita dapat melihat bahawa julat masa tidak bertindih.\n",
|
|
"\n",
|
|
"Cara yang lebih tepat dari segi statistik untuk membuktikan hipotesis adalah dengan menggunakan **ujian t-Student**:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from scipy.stats import ttest_ind\n",
|
|
"\n",
|
|
"tval, pval = ttest_ind(df.loc[df['Role']=='First_Baseman',['Height']], df.loc[df['Role']=='Second_Baseman',['Height']],equal_var=False)\n",
|
|
"print(f\"T-value = {tval[0]:.2f}\\nP-value: {pval[0]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Dua nilai yang dikembalikan oleh fungsi `ttest_ind` adalah:\n",
|
|
"* nilai p boleh dianggap sebagai kebarangkalian dua taburan mempunyai min yang sama. Dalam kes kami, ia sangat rendah, bermakna terdapat bukti kukuh yang menyokong bahawa pemain pertama adalah lebih tinggi.\n",
|
|
"* nilai t adalah nilai pertengahan perbezaan min yang dinormalisasi yang digunakan dalam ujian t, dan ia dibandingkan dengan nilai ambang untuk nilai keyakinan tertentu.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Mensimulasikan Taburan Normal dengan Teorem Had Tengah\n",
|
|
"\n",
|
|
"Penjana pseudo-rawak dalam Python direka untuk memberikan taburan seragam. Jika kita ingin membuat penjana untuk taburan normal, kita boleh menggunakan teorem had tengah. Untuk mendapatkan nilai yang diedarkan secara normal, kita hanya akan mengira purata sampel yang dijana secara seragam.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def normal_random(sample_size=100):\n",
|
|
" sample = [random.uniform(0,1) for _ in range(sample_size) ]\n",
|
|
" return sum(sample)/sample_size\n",
|
|
"\n",
|
|
"sample = [normal_random() for _ in range(100)]\n",
|
|
"plt.figure(figsize=(10,6))\n",
|
|
"plt.hist(sample)\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Korelasi dan Evil Baseball Corp\n",
|
|
"\n",
|
|
"Korelasi membolehkan kita mencari hubungan antara urutan data. Dalam contoh mainan kita, mari kita andaikan terdapat sebuah syarikat besbol jahat yang membayar pemainnya mengikut ketinggian mereka - semakin tinggi pemain tersebut, semakin banyak wang yang dia terima. Katakan terdapat gaji asas sebanyak $1000, dan bonus tambahan dari $0 hingga $100, bergantung pada ketinggian. Kita akan mengambil pemain sebenar dari MLB, dan mengira gaji khayalan mereka:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"heights = df['Height'].fillna(method='pad')\n",
|
|
"salaries = 1000+(heights-heights.min())/(heights.max()-heights.mean())*100\n",
|
|
"print(list(zip(heights, salaries))[:10])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Mari kita kira kovarians dan korelasi bagi urutan-urutan tersebut. `np.cov` akan memberikan kita yang dipanggil **matriks kovarians**, yang merupakan lanjutan kovarians kepada pelbagai pemboleh ubah. Elemen $M_{ij}$ dalam matriks kovarians $M$ adalah korelasi antara pemboleh ubah input $X_i$ dan $X_j$, dan nilai diagonal $M_{ii}$ adalah varians bagi $X_{i}$. Begitu juga, `np.corrcoef` akan memberikan kita **matriks korelasi**.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"print(f\"Covariance matrix:\\n{np.cov(heights, salaries)}\")\n",
|
|
"print(f\"Covariance = {np.cov(heights, salaries)[0,1]}\")\n",
|
|
"print(f\"Correlation = {np.corrcoef(heights, salaries)[0,1]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Korelasi sama dengan 1 bermaksud terdapat **hubungan linear** yang kuat antara dua pemboleh ubah. Kita boleh lihat hubungan linear secara visual dengan memplot satu nilai terhadap yang lain:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.figure(figsize=(10,6))\n",
|
|
"plt.scatter(heights,salaries)\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Mari kita lihat apa yang berlaku jika hubungannya tidak linear. Katakan bahawa syarikat kita memutuskan untuk menyembunyikan pergantungan linear yang jelas antara ketinggian dan gaji, dan memperkenalkan sedikit bukan linear dalam formula, seperti `sin`:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"salaries = 1000+np.sin((heights-heights.min())/(heights.max()-heights.mean()))*100\n",
|
|
"print(f\"Correlation = {np.corrcoef(heights, salaries)[0,1]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Dalam kes ini, korelasi adalah sedikit lebih kecil, tetapi masih agak tinggi. Kini, untuk menjadikan hubungan itu kurang jelas, kita mungkin mahu menambah beberapa unsur rawak tambahan dengan menambah beberapa pembolehubah rawak kepada gaji. Mari lihat apa yang berlaku:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"salaries = 1000+np.sin((heights-heights.min())/(heights.max()-heights.mean()))*100+np.random.random(size=len(heights))*20-10\n",
|
|
"print(f\"Correlation = {np.corrcoef(heights, salaries)[0,1]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.figure(figsize=(10,6))\n",
|
|
"plt.scatter(heights, salaries)\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"> Bolehkah anda teka mengapa titik-titik itu tersusun menjadi garisan menegak seperti ini?\n",
|
|
"\n",
|
|
"Kita telah memerhati korelasi antara konsep yang direka secara artifisial seperti gaji dan pemboleh ubah yang diperhatikan *tinggi*. Mari kita lihat juga jika dua pemboleh ubah yang diperhatikan, seperti tinggi dan berat, juga berkorelasi:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"np.corrcoef(df['Height'].ffill(),df['Weight'])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Malangnya, kami tidak mendapat sebarang keputusan - hanya beberapa nilai `nan` pelik. Ini kerana beberapa nilai dalam siri kami tidak ditakrifkan, yang diwakili sebagai `nan`, yang menyebabkan hasil operasi itu juga tidak ditakrifkan. Dengan melihat matriks, kita dapat lihat bahawa `Weight` adalah lajur bermasalah, kerana korelasi sendiri antara nilai `Height` telah dikira.\n",
|
|
"\n",
|
|
"> Contoh ini menunjukkan kepentingan **penyediaan data** dan **pembersihan**. Tanpa data yang betul, kita tidak dapat mengira apa-apa.\n",
|
|
"\n",
|
|
"Mari kita gunakan kaedah `fillna` untuk mengisi nilai yang hilang, dan mengira korelasi:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"np.corrcoef(df['Height'].fillna(method='pad'), df['Weight'])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Memang terdapat korelasi, tetapi tidaklah sehebat dalam contoh buatan kami. Sebenarnya, jika kita melihat plot taburan satu nilai terhadap nilai yang lain, hubungannya akan menjadi kurang jelas:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plt.figure(figsize=(10,6))\n",
|
|
"plt.scatter(df['Weight'],df['Height'])\n",
|
|
"plt.xlabel('Weight')\n",
|
|
"plt.ylabel('Height')\n",
|
|
"plt.tight_layout()\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Kesimpulan\n",
|
|
"\n",
|
|
"Dalam buku nota ini kita telah belajar bagaimana untuk melaksanakan operasi asas ke atas data untuk mengira fungsi statistik. Kita kini tahu bagaimana menggunakan peralatan matematik dan statistik yang mantap untuk membuktikan beberapa hipotesis, dan bagaimana untuk mengira selang keyakinan bagi pemboleh ubah arbitrari berdasarkan sampel data.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Penafian**: \nDokumen ini telah diterjemahkan menggunakan perkhidmatan terjemahan AI [Co-op Translator](https://github.com/Azure/co-op-translator). Walaupun kami berusaha untuk ketepatan, sila maklum bahawa terjemahan automatik mungkin mengandungi kesilapan atau ketidaktepatan. Dokumen asal dalam bahasa asalnya hendaklah dianggap sebagai sumber yang sahih. Untuk maklumat penting, terjemahan oleh profesional manusia adalah disyorkan. Kami tidak bertanggungjawab terhadap sebarang salah faham atau kesilapan tafsir yang timbul daripada penggunaan terjemahan ini.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"interpreter": {
|
|
"hash": "86193a1ab0ba47eac1c69c1756090baa3b420b3eea7d4aafab8b85f8b312f0c5"
|
|
},
|
|
"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.9.6"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "0f899e3c5019f948e7c787b22f3b2304",
|
|
"translation_date": "2026-01-16T17:39:31+00:00",
|
|
"source_file": "1-Introduction/04-stats-and-probability/notebook.ipynb",
|
|
"language_code": "ms"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |