Pemrosesan Awal Data dalam Machine learning

  • Post
    Pemrosesan Awal Data dalam Machine learning

    Preprocessing data merupakan proses menyiapkan data mentah dan membuatnya sesuai untuk model pembelajaran mesin. Ini adalah langkah pertama dan penting saat membuat model pembelajaran mesin.

    Saat membuat proyek pembelajaran mesin, kami tidak selalu menemukan data yang bersih dan diformat. Dan saat melakukan operasi apa pun dengan data, itu wajib untuk membersihkannya dan memasukkannya ke dalam cara yang diformat. Jadi untuk ini, kami menggunakan tugas preprocessing data.

    Mengapa kita membutuhkan Data Preprocessing?

    Data dunia nyata biasanya berisi derau, nilai yang hilang, dan mungkin dalam format yang tidak dapat digunakan yang tidak dapat langsung digunakan untuk model pembelajaran mesin. Pemrosesan awal data merupakan tugas-tugas yang diperlukan untuk membersihkan data dan membuatnya sesuai untuk model pembelajaran mesin yang juga meningkatkan akurasi dan efisiensi model pembelajaran mesin.

    Ini melibatkan langkah-langkah di bawah ini:

    • Mendapatkan dataset
    • Mengimpor perpustakaan
    • Mengimpor set data
    • Menemukan Data yang Hilang
    • Mengkodekan Data Kategoris
    • Memisahkan set data menjadi set pelatihan dan pengujian
    • Penskalaan fitur

    1) Dapatkan Dataset

    Untuk membuat model pembelajaran mesin, hal pertama yang kami butuhkan adalah kumpulan data karena model pembelajaran mesin berfungsi sepenuhnya pada data. Data yang dikumpulkan untuk masalah tertentu dalam format yang tepat dikenal sebagai kumpulan data .

    Dataset mungkin memiliki format yang berbeda untuk keperluan yang berbeda, seperti jika kita ingin membuat model machine learning untuk keperluan bisnis, maka dataset akan berbeda dengan dataset yang dibutuhkan untuk liver patient. Jadi setiap dataset berbeda dari dataset lain. Untuk menggunakan dataset dalam kode kami, kami biasanya memasukkannya ke dalam file CSV . Namun, terkadang, kami mungkin juga perlu menggunakan file HTML atau xlsx.

    Apa itu File CSV?

    CSV adalah singkatan dari file ” Comma-Separated Values “; Ini adalah format file yang memungkinkan kita menyimpan data tabel, seperti spreadsheet. Ini berguna untuk kumpulan data yang sangat besar dan dapat menggunakan kumpulan data ini dalam program.

    Disini kita akan menggunakan demo dataset untuk preprocessing data, dan untuk latihan bisa didownload dari sini, ” https://www.superdatascience.com/pages/machine-learning . Untuk masalah dunia nyata, kita bisa mendownload dataset secara online dari berbagai sumber seperti https://www.kaggle.com/uciml/datasets , https://archive.ics.uci.edu/ml/index.php dll.

    Kita juga dapat membuat dataset kita dengan mengumpulkan data menggunakan berbagai API dengan Python dan memasukkan data tersebut ke dalam file .csv.

    2) Mengimpor Perpustakaan

    Untuk melakukan preprocessing data menggunakan Python, kita perlu mengimpor beberapa pustaka Python yang telah ditentukan sebelumnya. Perpustakaan ini digunakan untuk melakukan beberapa pekerjaan tertentu. Ada tiga library khusus yang akan kami gunakan untuk preprocessing data, yaitu:

    Numpy: Pustaka Numpy Python digunakan untuk memasukkan semua jenis operasi matematika ke dalam kode. Ini adalah paket dasar untuk kalkulasi ilmiah dengan Python. Ini juga mendukung untuk menambahkan array dan matriks multidimensi yang besar. Jadi, dengan Python, kita dapat mengimpornya sebagai:

    1. impor numpy sebagai nm

    Di sini kita telah menggunakan nm , yang merupakan nama pendek dari Numpy, dan itu akan digunakan di seluruh program.

    Matplotlib: Library kedua adalah matplotlib , yang merupakan library plotting 2D Python, dan dengan library ini, kita perlu mengimpor pyplot sub-library . Perpustakaan ini digunakan untuk memplot semua jenis grafik dengan Python untuk kode. Itu akan diimpor seperti di bawah ini:

    1. impor matplotlib.pyplot sebagai mpt

    Di sini kami telah menggunakan mpt sebagai nama pendek untuk perpustakaan ini.

    Pandas: Pustaka terakhir adalah pustaka Pandas, yang merupakan salah satu pustaka Python paling terkenal dan digunakan untuk mengimpor dan mengelola kumpulan data. Ini adalah manipulasi data sumber terbuka dan pustaka analisis. Itu akan diimpor seperti di bawah ini:

    Di sini, kami menggunakan pd sebagai nama pendek untuk perpustakaan ini. Perhatikan gambar di bawah ini:

    3) Mengimpor Set Data

    Sekarang kami perlu mengimpor kumpulan data yang telah kami kumpulkan untuk proyek pembelajaran mesin kami. Tetapi sebelum mengimpor dataset, kita perlu mengatur direktori saat ini sebagai direktori kerja. Untuk mengatur direktori kerja di Spyder IDE, kita perlu mengikuti langkah-langkah di bawah ini:

    1. Simpan file Python Anda di direktori yang berisi dataset.
    2. Buka opsi File explorer di Spyder IDE, dan pilih direktori yang diperlukan.
    3. Klik tombol F5 atau jalankan opsi untuk menjalankan file.

    Catatan: Kita dapat menetapkan direktori apa pun sebagai direktori kerja, tetapi harus berisi kumpulan data yang diperlukan.

    Di sini, pada gambar di bawah ini, kita dapat melihat file Python beserta dataset yang dibutuhkan. Sekarang, folder saat ini disetel sebagai direktori kerja.

    read_csv () fungsi:

    Sekarang untuk mengimpor dataset, kita akan menggunakan read_csv () fungsi pustaka pandas, yang digunakan untuk membaca file csvfile dan melakukan berbagai operasi padanya. Dengan menggunakan fungsi ini, kita dapat membaca file csv secara lokal maupun melalui URL.

    Kita bisa menggunakan fungsi read_csv seperti di bawah ini:

    1. data_set =  pd .read_csv (‘Dataset.csv’)

    Di sini, data_set adalah nama variabel untuk menyimpan dataset kita, dan di dalam fungsinya, kita telah mengirimkan nama dataset kita. Setelah kami menjalankan baris kode di atas, itu akan berhasil mengimpor dataset dalam kode kami. Kita juga dapat memeriksa dataset yang diimpor dengan mengklik pada penjelajah variabel bagian , lalu klik dua kali pada data_set . Perhatikan gambar di bawah ini:

    Seperti pada gambar di atas, pengindeksan dimulai dari 0, yang merupakan pengindeksan default dengan Python. Kami juga dapat mengubah format dataset kami dengan mengklik opsi format.

    Mengekstrak variabel dependen dan independen:

    Dalam pembelajaran mesin, penting untuk membedakan matriks fitur (variabel independen) dan variabel dependen dari kumpulan data. Dalam dataset kami, ada tiga variabel independen yaitu Negara, Usia , dan Gaji , dan satu adalah variabel dependen yang Dibeli .

    Mengekstrak variabel independen:

    Untuk mengekstrak variabel independen, kita akan menggunakan metode iloc [] dari pustaka Pandas. Ini digunakan untuk mengekstrak baris dan kolom yang diperlukan dari dataset.

    1. x =  data_set .iloc [:,: – 1] .values

    Pada kode di atas, titik dua pertama (:) digunakan untuk mengambil semua baris, dan titik dua kedua (:) untuk semua kolom. Di sini kami telah menggunakan: -1, karena kami tidak ingin mengambil kolom terakhir karena berisi variabel dependen. Jadi dengan melakukan ini, kita akan mendapatkan matriks fitur.

    Dengan menjalankan kode di atas, kita akan mendapatkan output sebagai:

    1. [[‘India’ 38.0 68000.0]
    2. [‘France’ 43.0 45000.0]
    3. [‘Germany’ 30.0 54000.0]
    4. [‘France’ 48.0 65000.0]
    5. [‘Germany’ 40.0 nan]
    6. [‘India’ 35.0 58000.0]
    7. [‘Germany’ nan 53000.0]
    8. [‘France’ 49.0 79000.0]
    9. [‘India’ 50.0 88000.0]
    10. [‘France’ 37.0 77000.0]]

    Seperti yang bisa kita lihat pada output di atas, hanya ada tiga variabel.

    Mengekstrak variabel dependen:

    Untuk mengekstrak variabel dependen, sekali lagi, kita akan menggunakan metode Pandas .iloc [].

    1. y =  data_set .iloc [:, 3] .values

    Di sini kita telah mengambil semua baris dengan kolom terakhir saja. Ini akan memberikan array variabel dependen.

    Dengan menjalankan kode di atas, kita akan mendapatkan output sebagai:

    Keluaran:

    array ([‘No’, ‘Yes’, ‘No’, ‘No’, ‘Yes’, ‘Yes’, ‘No’, ‘Yes’, ‘No’, ‘Yes’],

    dtype = object)

    Catatan: Jika Anda menggunakan bahasa Python untuk pembelajaran mesin, ekstraksi wajib dilakukan, tetapi untuk bahasa R tidak diperlukan.

    4) Menangani Data yang Hilang:

    Langkah selanjutnya dari preprocessing data adalah menangani data yang hilang di dataset. Jika kumpulan data kami berisi beberapa data yang hilang, hal itu dapat menimbulkan masalah besar untuk model pembelajaran mesin kami. Oleh karena itu perlu untuk menangani nilai-nilai yang hilang yang ada dalam dataset.

    Cara menangani data yang hilang:

    Ada dua cara utama untuk menangani data yang hilang, yaitu:

    Dengan menghapus baris tertentu: Cara pertama digunakan untuk menangani nilai null secara umum. Dengan cara ini, kami hanya menghapus baris atau kolom tertentu yang terdiri dari nilai null. Tetapi cara ini tidak begitu efisien dan menghapus data dapat menyebabkan hilangnya informasi yang tidak akan memberikan keluaran yang akurat.

    Dengan menghitung mean: Dengan cara ini, kita akan menghitung mean dari kolom atau baris yang mengandung nilai yang hilang dan akan meletakkannya di tempat nilai yang hilang. Strategi ini berguna untuk fitur-fitur yang memiliki data numerik seperti umur, gaji, tahun, dll. Disini kita akan menggunakan pendekatan ini.

    Untuk menangani nilai yang hilang, kami akan menggunakan pustaka Scikit-learn dalam kode kami, yang berisi berbagai pustaka untuk membangun model pembelajaran mesin. Di sini kita akan menggunakan Imputer kelas sklearn.preprocessing perpustakaan. Di bawah ini adalah kode untuk itu:

    1. #handling missing data (Replacing missing data with the mean value)
    2. from sklearn.preprocessing import Imputer
    3. imputer= Imputer(missing_values=’NaN’, strategy=’mean’, axis = 0)
    4. #Fitting imputer object to the independent variables x.
    5. imputerimputer= imputer.fit(x[:, 1:3])
    6. #Replacing missing data with the calculated mean value
    7. x[:, 1:3]= imputer.transform(x[:, 1:3])

    Keluaran:

    array([[‘India’, 38.0, 68000.0],

    [‘France’, 43.0, 45000.0],

    [‘Germany’, 30.0, 54000.0],

    [‘France’, 48.0, 65000.0],

    [‘Germany’, 40.0, 65222.22222222222],

    [‘India’, 35.0, 58000.0],

    [‘Germany’, 41.111111111111114, 53000.0],

    [‘France’, 49.0, 79000.0],

    [‘India’, 50.0, 88000.0],

    [‘France’, 37.0, 77000.0]], dtype=object

    Seperti yang bisa kita lihat pada output di atas, nilai yang hilang telah diganti dengan sarana nilai kolom istirahat.

    5) Pengkodean data Kategorikal:

    Data kategoris adalah data yang memiliki beberapa kategori seperti pada dataset kita; Ada dua variabel kategori, Negara , dan Dibeli .

    Karena model pembelajaran mesin sepenuhnya berfungsi pada matematika dan angka, tetapi jika kumpulan data kita memiliki variabel kategorikal, hal itu dapat menimbulkan masalah saat membuat model. Jadi perlu untuk mengkodekan variabel kategorikal ini menjadi angka.

    Untuk variabel Negara:

    Pertama, kami akan mengubah variabel negara menjadi data kategorikal. Jadi untuk melakukan ini, kita akan menggunakan kelas LabelEncoder () dari perpustakaan preprocessing .

    1. #Catgorical data
    2. #for Country Variable
    3. from sklearn.preprocessing import LabelEncoder
    4. label_encoder_x= LabelEncoder()
    5. x[:, 0]= label_encoder_x.fit_transform(x[:, 0])

    Keluaran:

    Out[15]:

    array([[2, 38.0, 68000.0],

    [0, 43.0, 45000.0],

    [1, 30.0, 54000.0],

    [0, 48.0, 65000.0],

    [1, 40.0, 65222.22222222222],

    [2, 35.0, 58000.0],

    [1, 41.111111111111114, 53000.0],

    [0, 49.0, 79000.0],

    [2, 50.0, 88000.0],

    [0, 37.0, 77000.0]], dtype=object)

    [0, 37.0, 77000.0]], dtype = object)

    Penjelasan:

    Dalam kode di atas, kita telah mengimpor LabelEncoder kelas perpustakaan sklearn . Kelas ini telah berhasil mengkodekan variabel menjadi digit.

    Namun dalam kasus kami, ada tiga variabel negara, dan seperti yang dapat kita lihat pada keluaran di atas, variabel-variabel ini dikodekan menjadi 0, 1, dan 2. Dengan nilai-nilai ini, model pembelajaran mesin dapat mengasumsikan bahwa ada beberapa korelasi di antara ini. variabel yang akan menghasilkan keluaran yang salah. Jadi untuk menghilangkan masalah ini, kami akan menggunakan encoding dummy .

    Variabel Dummy:

    Variabel dummy adalah variabel yang memiliki nilai 0 atau 1. Nilai 1 menunjukkan keberadaan variabel tersebut dalam kolom tertentu, dan variabel lainnya menjadi 0. Dengan dummy encoding, kita akan memiliki jumlah kolom yang sama dengan jumlah kategori.

    Dalam dataset kami, kami memiliki 3 kategori sehingga akan menghasilkan tiga kolom yang memiliki nilai 0 dan 1. Untuk Dummy Encoding, kita akan menggunakan kelas OneHotEncoder perpustakaan preprocessing .

    1. #for Country Variable
    2. from sklearn.preprocessing import LabelEncoder, OneHotEncoder
    3. label_encoder_x= LabelEncoder()
    4. x[:, 0]= label_encoder_x.fit_transform(x[:, 0])
    5. #Encoding for dummy variables
    6. onehot_encoder= OneHotEncoder(categorical_features= [0])
    7. x= onehot_encoder.fit_transform(x).toarray()

    Keluaran:

    array([[0.00000000e+00, 0.00000000e+00, 1.00000000e+00, 3.80000000e+01,

    6.80000000e+04],

    [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 4.30000000e+01,

    4.50000000e+04],

    [0.00000000e+00, 1.00000000e+00, 0.00000000e+00, 3.00000000e+01,

    5.40000000e+04],

    [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 4.80000000e+01,

    6.50000000e+04],

    [0.00000000e+00, 1.00000000e+00, 0.00000000e+00, 4.00000000e+01,

    6.52222222e+04],

    [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, 3.50000000e+01,

    5.80000000e+04],

    [0.00000000e+00, 1.00000000e+00, 0.00000000e+00, 4.11111111e+01,

    5.30000000e+04],

    [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 4.90000000e+01,

    7.90000000e+04],

    [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, 5.00000000e+01,

    8.80000000e+04],

    [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 3.70000000e+01,

    7.70000000e+04]])

    Seperti yang dapat kita lihat pada output di atas, semua variabel dikodekan menjadi angka 0 dan 1 dan dibagi menjadi tiga kolom.

    Ini dapat dilihat lebih jelas di bagian variabel explorer, dengan mengklik opsi x sebagai:

    Untuk Variabel yang Dibeli:

    1. labelencoder_y =  LabelEncoder ()
    2. y =  labelencoder_y .fit_transform (y)

    Untuk variabel kategori kedua, kita hanya akan menggunakan objek labelencoder dari kelas LableEncoder . Di sini kami tidak menggunakan kelas OneHotEncoder karena variabel yang dibeli hanya memiliki dua kategori ya atau tidak, dan yang secara otomatis dikodekan menjadi 0 dan 1.

    Keluaran:

    Out[17]: array([0, 1, 0, 0, 1, 1, 0, 1, 0, 1])

    Itu juga bisa dilihat sebagai:

    6) Memisahkan Set Data menjadi set Pelatihan dan Set Pengujian

    Dalam pemrosesan awal data pembelajaran mesin, kami membagi kumpulan data kami menjadi satu set pelatihan dan set pengujian. Ini adalah salah satu langkah penting dari prapemrosesan data karena dengan melakukan ini, kami dapat meningkatkan performa model pembelajaran mesin kami.

    Misalkan, jika kita telah memberikan pelatihan untuk model pembelajaran mesin kita dengan set data dan kita mengujinya dengan set data yang sama sekali berbeda. Kemudian, akan menimbulkan kesulitan bagi model kita untuk memahami korelasi antar model.

    Jika kita melatih model kita dengan sangat baik dan akurasi pelatihannya juga sangat tinggi, tetapi kita memberikan set data baru padanya, maka itu akan menurunkan performanya. Jadi kami selalu mencoba membuat model pembelajaran mesin yang berkinerja baik dengan set pelatihan dan juga dengan set data pengujian. Di sini, kami dapat mendefinisikan kumpulan data ini sebagai:

    Set Pelatihan: Subset dari kumpulan data untuk melatih model pembelajaran mesin, dan kita sudah mengetahui hasilnya.

    Set pengujian: Subset dari set data untuk menguji model machine learning, dan dengan menggunakan set pengujian, model memprediksi keluaran.

    Untuk memisahkan dataset, kita akan menggunakan baris kode di bawah ini:

    1. from sklearn.model_selection import train_test_split
    2. x_train, x_test, y_train, y_test= train_test_split(x, y, test_size= 0.2, random_state=0)

    Penjelasan:

    • Dalam kode di atas, baris pertama digunakan untuk memisahkan array dari kumpulan data menjadi rangkaian acak dan subset pengujian.
    • Pada baris kedua, kami telah menggunakan empat variabel untuk keluaran kami yaitu
      • x_train: fitur untuk data pelatihan
      • x_test: fitur untuk menguji data
      • y_train: Variabel dependen untuk data pelatihan
      • y_test: Variabel independen untuk data pengujian
    • Dalam fungsi train_test_split () , kita telah melewati empat parameter di mana dua yang pertama adalah untuk array data, dan test_size untuk menentukan ukuran set pengujian. Test_size mungkin .5, .3, atau .2, yang memberi tahu rasio pembagian set pelatihan dan pengujian.
    • Parameter terakhir random_state digunakan untuk mengatur seed generator acak sehingga Anda selalu mendapatkan hasil yang sama, dan nilai yang paling sering digunakan adalah 42.

    Keluaran:

    Dengan menjalankan kode di atas, kita akan mendapatkan 4 variabel berbeda, yang dapat dilihat di bawah bagian variabel explorer.

    Seperti yang dapat kita lihat pada gambar di atas, variabel x dan y dibagi menjadi 4 variabel berbeda dengan nilai yang sesuai.

    7) Penskalaan Fitur

    Penskalaan fitur adalah langkah terakhir dari prapemrosesan data dalam pembelajaran mesin. Ini adalah teknik untuk menstandarisasi variabel independen dari kumpulan data dalam rentang tertentu. Dalam penskalaan fitur, kami menempatkan variabel kami dalam rentang yang sama dan dalam skala yang sama sehingga tidak ada variabel yang mendominasi variabel lainnya.

    Pertimbangkan dataset di bawah ini:

    Seperti yang bisa kita lihat, nilai kolom usia dan gaji tidak memiliki skala yang sama. Model pembelajaran mesin didasarkan pada jarak Euclidean , dan jika kita tidak menskalakan variabel, maka akan menyebabkan beberapa masalah dalam model pembelajaran mesin kita.

    Jarak euclidean diberikan sebagai:

    Jika kita menghitung dua nilai dari umur dan gaji, maka nilai gaji akan mendominasi nilai umur, dan akan menghasilkan hasil yang salah. Jadi untuk menghilangkan masalah ini, kita perlu melakukan penskalaan fitur untuk pembelajaran mesin.

    Ada dua cara untuk melakukan penskalaan fitur dalam pembelajaran mesin:

    Standardisasi

    Normalisasi

    Di sini, kami akan menggunakan metode standarisasi untuk dataset kami.

    Untuk penskalaan fitur, kami akan mengimpor kelas StandardScaler dari pustaka sklearn.preprocessing sebagai:

    1. dari sklearn.preprocessing import StandardScaler

    Sekarang, kita akan membuat objek kelas StandardScaler untuk variabel atau fitur independen. Dan kemudian kami akan menyesuaikan dan mengubah set data pelatihan.

    1. st_x =  StandardScaler ()
    2. x_train =  st_x .fit_transform (x_train)

    Untuk set data uji, kita akan langsung menerapkan fungsi transform () daripada fit_transform () karena sudah dilakukan di set pelatihan.

    1. x_test =  st_x .transform (x_test)

    Keluaran:

    Dengan menjalankan baris kode di atas, kita akan mendapatkan nilai skala untuk x_train dan x_test sebagai:

    x_train:

    x_test:

    Seperti yang bisa kita lihat pada output di atas, semua variabel diskalakan antara nilai -1 hingga 1.

    Catatan: Di sini, kami belum menskalakan variabel dependen karena hanya ada dua nilai 0 dan 1. Tetapi jika variabel-variabel ini memiliki rentang nilai yang lebih banyak, maka kami juga perlu menskalakan variabel-variabel tersebut.

    Menggabungkan semua langkah:

    Sekarang, pada akhirnya, kita dapat menggabungkan semua langkah bersama untuk membuat kode lengkap kita lebih mudah dipahami.

    1. # importing libraries
    2. import numpy as nm
    3. import matplotlib.pyplot as mtp
    4. import pandas as pd
    5. #importing datasets
    6. data_set= pd.read_csv(‘Dataset.csv’)
    7. #Extracting Independent Variable
    8. x= data_set.iloc[:, :-1].values
    9. #Extracting Dependent variable
    10. y= data_set.iloc[:, 3].values
    11. #handling missing data(Replacing missing data with the mean value)
    12. from sklearn.preprocessing import Imputer
    13. imputer= Imputer(missing_values=’NaN’, strategy=’mean’, axis= 0)
    14. #Fitting imputer object to the independent varibles x.
    15. imputerimputer= imputer.fit(x[:, 1:3])
    16. #Replacing missing data with the calculated mean value
    17. x[:, 1:3]= imputer.transform(x[:, 1:3])
    18. #for Country Variable
    19. from sklearn.preprocessing import LabelEncoder, OneHotEncoder
    20. label_encoder_x= LabelEncoder()
    21. x[:, 0]= label_encoder_x.fit_transform(x[:, 0])
    22. #Encoding for dummy variables
    23. onehot_encoder= OneHotEncoder(categorical_features= [0])
    24. x= onehot_encoder.fit_transform(x).toarray()
    25. #encoding for purchased variable
    26. labelencoder_y= LabelEncoder()
    27. y= labelencoder_y.fit_transform(y)
    28. # Splitting the dataset into training and test set.
    29. from sklearn.model_selection import train_test_split
    30. x_train, x_test, y_train, y_test= train_test_split(x, y, test_size= 0.2, random_state=0)
    31. #Feature Scaling of datasets
    32. from sklearn.preprocessing import StandardScaler
    33. st_x= StandardScaler()
    34. x_train= st_x.fit_transform(x_train)
    35. x_test= st_x.transform(x_test)

    Pada kode di atas, kami telah memasukkan semua langkah preprocessing data secara bersamaan. Namun ada beberapa langkah atau baris kode yang tidak diperlukan untuk semua model pembelajaran mesin. Jadi kami dapat mengecualikannya dari kode kami agar dapat digunakan kembali untuk semua model.

     

     

    credit. javatpoint

    Ampuh! Ini rahasia mengembangkan aplikasi secara instan, tinggal download dan kembangkan. Gabung sekarang juga! Premium Membership [PRIVATE] https://premium.codeorayo.com

Tagged: 

  • You must be logged in to reply to this topic.