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

575 lines
18 KiB

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Pendahuluan tentang Probabilitas dan Statistik\n",
"Dalam buku catatan ini, kita akan bereksperimen dengan beberapa konsep yang telah kita bahas sebelumnya. Banyak konsep dari probabilitas dan statistik yang sangat terwakili dalam perpustakaan 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 sebanyak 30 nilai dari distribusi uniform dari 0 hingga 9. Kita juga akan menghitung rata-rata dan variansi.\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 dapat membuat **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 baseball 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 umur, 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, dan hitung standar deviasi serta variansnya: \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 mean, masuk akal untuk melihat nilai median dan kuartil. Mereka dapat divisualisasikan menggunakan **box plot**:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure(figsize=(10,2))\n",
"plt.boxplot(df['Height'].ffill(), orientation='horizontal', 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 semuanya adalah variabel acak kontinu. Menurut Anda, bagaimana distribusinya? Cara yang baik untuk mengetahuinya adalah dengan memplot histogram nilainya: \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 contoh buatan dari bobot yang mengikuti distribusi normal dengan rata-rata dan varians yang sama seperti data asli 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 didistribusikan secara normal, kita tidak boleh menggunakan generator angka acak uniform untuk menghasilkan data sampel. Berikut adalah apa 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 baseball. 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'].ffill(),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 First Basemen lebih tinggi daripada Second Basemen. Cara termudah 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 menggunakan **uji 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",
"* p-value dapat dianggap sebagai probabilitas dua distribusi memiliki rata-rata yang sama. Dalam kasus kami, nilainya sangat rendah, yang berarti ada bukti kuat yang mendukung bahwa pemain pertama lebih tinggi.\n",
"* t-value adalah nilai antara dari perbedaan rata-rata ter-normalisasi yang digunakan dalam uji t, dan dibandingkan terhadap nilai ambang untuk nilai kepercayaan tertentu.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Mensimulasikan Distribusi Normal dengan Teorema Limit Tengah\n",
"\n",
"Generator pseudo-acak di Python dirancang untuk memberikan distribusi uniform. Jika kita ingin membuat generator untuk distribusi normal, kita bisa menggunakan teorema limit tengah. Untuk mendapatkan nilai yang terdistribusi normal, kita hanya akan 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 berpura-pura ada sebuah perusahaan bisbol jahat yang membayar pemainnya sesuai dengan 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 asli dari MLB, dan menghitung gaji imajiner mereka:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"heights = df['Height'].ffill()\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-urutan tersebut. `np.cov` akan memberi kita apa yang disebut **matriks kovarians**, yang merupakan perluasan 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 sama dengan 1 berarti ada hubungan **linear** yang kuat antara dua variabel. Kita dapat melihat hubungan linear 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 beberapa non-linearitas 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 itu menjadi kurang jelas, kita mungkin ingin menambahkan beberapa 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 yang dibuat secara artifisial seperti gaji dan variabel yang diamati *tinggi badan*. Mari kita juga lihat apakah dua variabel yang diamati, 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 seri kami tidak terdefinisi, yang diwakili sebagai `nan`, yang menyebabkan hasil operasi juga tidak terdefinisi. Dengan melihat matriks, kita dapat melihat bahwa `Weight` adalah kolom yang bermasalah, karena korelasi diri antara nilai `Height` telah dihitung.\n",
"\n",
"> Contoh ini menunjukkan pentingnya **persiapan data** dan **pembersihan**. Tanpa data yang tepat, kita tidak bisa menghitung apa pun.\n",
"\n",
"Mari kita gunakan metode `fillna` untuk mengisi nilai yang hilang, dan hitung korelasinya:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"np.corrcoef(df['Height'].ffill(), df['Weight'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Memang ada korelasi, tetapi tidak sekuat contoh buatan kami. Memang, jika kita melihat diagram sebar dari satu nilai terhadap nilai lain, hubungan tersebut akan jauh lebih tidak 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 catatan ini kita telah belajar bagaimana melakukan operasi dasar pada data untuk menghitung fungsi statistik. Sekarang kita tahu bagaimana menggunakan perangkat matematika dan statistik yang kuat untuk membuktikan beberapa hipotesis, dan bagaimana menghitung interval kepercayaan untuk variabel arbitrer dengan 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 berupaya untuk mencapai akurasi, harap diketahui bahwa terjemahan otomatis mungkin mengandung kesalahan atau ketidakakuratan. Dokumen asli dalam bahasa aslinya harus dianggap sebagai sumber yang sah. Untuk informasi penting, disarankan menggunakan terjemahan profesional oleh manusia. Kami tidak bertanggung jawab atas kesalahpahaman atau penafsiran yang keliru 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"
}
},
"nbformat": 4,
"nbformat_minor": 4
}