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.
Data-Science-For-Beginners/translations/id/1-Introduction/04-stats-and-probability/notebook.ipynb

581 lines
19 KiB

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Pengantar Probabilitas dan Statistik\n",
"Dalam notebook ini, kita akan mencoba beberapa konsep yang telah kita bahas sebelumnya. Banyak konsep dari probabilitas dan statistik yang diwakili dengan baik dalam pustaka utama untuk pemrosesan data di 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": [
"## Variabel Acak dan Distribusi\n",
"Mari kita mulai dengan mengambil sampel 30 nilai dari distribusi uniform dari 0 hingga 9. Kita juga akan menghitung mean 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 memperkirakan secara visual berapa banyak nilai berbeda yang ada dalam sampel, kita bisa menggambar **histogram**:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.hist(sample)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Menganalisis Data Nyata\n",
"\n",
"Rata-rata dan varians sangat penting saat menganalisis data dunia nyata. Mari kita muat data tentang pemain bisbol 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 paket yang disebut [**Pandas**](https://pandas.pydata.org/) di sini untuk analisis data. Kami akan membahas lebih lanjut tentang Pandas dan bekerja dengan data di Python nanti dalam kursus ini.\n",
"\n",
"Mari kita hitung nilai rata-rata untuk usia, tinggi, 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 tinggi badan, dan hitung deviasi standar 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 nilai rata-rata, masuk akal untuk melihat nilai median dan kuartil. Mereka dapat divisualisasikan menggunakan **diagram 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 dapat membuat plot kotak dari subset dataset kita, misalnya, dikelompokkan berdasarkan peran 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": [
"> **Catatan**: Diagram ini menunjukkan, bahwa rata-rata, tinggi pemain base pertama lebih tinggi daripada tinggi pemain base kedua. Nanti kita akan belajar bagaimana kita dapat menguji hipotesis ini secara lebih formal, dan bagaimana menunjukkan bahwa data kita signifikan secara statistik untuk membuktikannya. \n",
"\n",
"Usia, tinggi, dan berat badan semuanya adalah variabel acak kontinu. Menurut Anda, bagaimana distribusinya? Cara yang baik untuk mengetahuinya adalah dengan memplot 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": [
"## Distribusi Normal\n",
"\n",
"Mari buat sampel buatan dari berat yang mengikuti distribusi normal dengan mean dan variansi yang sama seperti data nyata 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": [
"Karena sebagian besar nilai dalam kehidupan nyata terdistribusi secara normal, kita sebaiknya tidak menggunakan generator angka acak uniform untuk menghasilkan data sampel. Berikut ini yang terjadi jika kita mencoba menghasilkan berat dengan distribusi uniform (dihasilkan 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": [
"## Interval Kepercayaan\n",
"\n",
"Sekarang mari kita hitung interval kepercayaan untuk berat dan tinggi pemain bisbol. Kita akan menggunakan kode [dari diskusi 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": [
"## Pengujian Hipotesis\n",
"\n",
"Mari kita jelajahi peran yang berbeda dalam dataset pemain baseball kita:\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 kita uji hipotesis bahwa pemain First Basemen lebih tinggi daripada Second Basemen. Cara paling sederhana untuk melakukan ini adalah dengan menguji interval kepercayaan:\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 bahwa intervalnya tidak tumpang tindih.\n",
"\n",
"Cara yang secara statistik lebih benar untuk membuktikan hipotesis adalah dengan menggunakan **Student t-test**:\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",
"* p-value dapat dianggap sebagai probabilitas dari dua distribusi memiliki mean yang sama. Dalam kasus kami, nilainya sangat rendah, yang berarti ada bukti kuat yang mendukung bahwa pemain base pertama lebih tinggi.\n",
"* t-value adalah nilai antara dari perbedaan mean yang dinormalisasi yang digunakan dalam uji t, dan nilai ini dibandingkan dengan nilai ambang untuk nilai kepercayaan tertentu.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Mensimulasikan Distribusi Normal dengan Teorema Limit Sentral\n",
"\n",
"Generator pseudo-acak di Python dirancang untuk memberikan distribusi uniform. Jika kita ingin membuat generator untuk distribusi normal, kita dapat menggunakan teorema limit sentral. Untuk mendapatkan nilai yang terdistribusi normal, kita cukup menghitung rata-rata dari sampel yang dihasilkan secara uniform.\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 memungkinkan kita menemukan hubungan antara urutan data. Dalam contoh mainan kita, mari kita berpura-pura ada sebuah perusahaan baseball jahat yang membayar pemainnya berdasarkan tinggi badan mereka - semakin tinggi pemain, semakin banyak uang yang dia dapatkan. Misalkan ada gaji pokok sebesar $1000, dan bonus tambahan dari $0 hingga $100, tergantung pada tinggi badan. Kita akan mengambil pemain nyata dari MLB, dan menghitung gaji imajinasi 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": [
"Sekarang mari kita hitung kovarians dan korelasi dari urutan tersebut. `np.cov` akan memberi kita yang disebut **matriks kovarians**, yang merupakan perpanjangan dari kovarians ke banyak variabel. Elemen $M_{ij}$ dari matriks kovarians $M$ adalah korelasi antara variabel input $X_i$ dan $X_j$, dan nilai diagonal $M_{ii}$ adalah varians dari $X_{i}$. Demikian pula, `np.corrcoef` akan memberi 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 yang sama dengan 1 berarti ada **hubungan linier** yang kuat antara dua variabel. Kita dapat melihat hubungan linier secara visual dengan memplot satu nilai terhadap nilai lainnya:\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 terjadi jika relasinya tidak linier. Misalkan perusahaan kita memutuskan untuk menyembunyikan ketergantungan linier yang jelas antara tinggi badan dan gaji, dan memperkenalkan sedikit non-linieritas ke dalam rumus, 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 kasus ini, korelasinya sedikit lebih kecil, tetapi masih cukup tinggi. Sekarang, untuk membuat hubungan tersebut menjadi kurang jelas, kita mungkin ingin menambahkan sedikit keacakan ekstra dengan menambahkan beberapa variabel acak ke gaji. Mari kita lihat apa yang terjadi:\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": [
"> Bisakah Anda menebak mengapa titik-titik itu berbaris menjadi garis vertikal seperti ini?\n",
"\n",
"Kita telah mengamati korelasi antara konsep rekayasa buatan seperti gaji dan variabel teramati *tinggi badan*. Mari kita juga lihat apakah kedua variabel teramati, seperti tinggi badan dan berat badan, juga berkorelasi:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].ffill(),df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Sayangnya, kami tidak mendapatkan hasil apa pun - hanya beberapa nilai `nan` yang aneh. Ini disebabkan oleh fakta bahwa beberapa nilai dalam deret kami tidak terdefinisi, yang diwakili sebagai `nan`, yang menyebabkan hasil operasi juga menjadi tidak terdefinisi. Dengan melihat matriks, kita dapat melihat bahwa `Weight` adalah kolom yang bermasalah, karena korelasi sendiri antara nilai `Height` telah dihitung.\n",
"\n",
"> Contoh ini menunjukkan pentingnya **persiapan data** dan **pembersihan**. Tanpa data yang tepat, kita tidak dapat menghitung apa pun.\n",
"\n",
"Mari kita gunakan metode `fillna` untuk mengisi nilai yang hilang, dan menghitung korelasinya: \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 ada korelasi, tetapi tidak sekuat dalam contoh buatan kita. Memang, jika kita melihat plot sebar satu nilai terhadap yang lain, hubungan tersebut akan jauh 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 notebook ini kita telah belajar bagaimana melakukan operasi dasar pada data untuk menghitung fungsi statistik. Kini kita tahu bagaimana menggunakan perangkat matematika dan statistik yang tepat untuk membuktikan beberapa hipotesis, serta bagaimana menghitung interval kepercayaan untuk variabel sembarang berdasarkan sampel data.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Penafian**: \nDokumen ini telah diterjemahkan menggunakan layanan terjemahan AI [Co-op Translator](https://github.com/Azure/co-op-translator). Meskipun kami berusaha untuk mencapai ketepatan, harap diketahui bahwa terjemahan otomatis mungkin mengandung kesalahan atau ketidakakuratan. Dokumen asli dalam bahasa aslinya harus dianggap sebagai sumber yang sahih. Untuk informasi penting, disarankan menggunakan jasa terjemahan profesional oleh manusia. Kami tidak bertanggung jawab atas kesalahpahaman atau salah tafsir yang timbul dari 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:38:29+00:00",
"source_file": "1-Introduction/04-stats-and-probability/notebook.ipynb",
"language_code": "id"
}
},
"nbformat": 4,
"nbformat_minor": 4
}