Lewati ke konten utama

Tutorial Scikit-Learn: Analitik Baseball Bag. 1

Tutorial scikit-learn untuk memprediksi jumlah kemenangan MLB per musim dengan memodelkan data ke model klastering KMeans dan model regresi linear.
· 14 mnt Baca

Jelajahi bersama AI

Bahasa pemrograman Python adalah pilihan yang sangat baik untuk data science dan analitik prediktif, karena dilengkapi dengan banyak paket yang mencakup sebagian besar kebutuhan analisis data Anda. Untuk machine learning di Python, Scikit-learn (sklearn) adalah pilihan yang sangat baik dan dibangun di atas NumPy, SciPy, dan Matplotlib (masing-masing untuk array N-dimensi, komputasi ilmiah, dan visualisasi data).

Dalam tutorial ini, Anda akan melihat cara mudah memuat data dari basis data dengan sqlite3, bagaimana mengeksplorasi data dan meningkatkan kualitasnya dengan pandas dan matplotlib, dan bagaimana kemudian menggunakan paket Scikit-Learn untuk mengekstrak wawasan yang valid dari data Anda.

Jika Anda ingin mengikuti kursus machine learning, lihat kursus DataCamp Supervised Learning with scikit-learn.

Bagian 1: Memprediksi Kemenangan Tim MLB per Musim

Pada proyek ini, Anda akan menguji beberapa model machine learning dari sklearn untuk memprediksi jumlah pertandingan yang dimenangkan oleh tim Major League Baseball pada musim tersebut, berdasarkan statistik tim dan variabel lain dari musim itu. Jika saya seorang penjudi (dan saya jelas seorang penjudi), saya bisa membangun model menggunakan data historis dari musim-musim sebelumnya untuk memproyeksikan musim yang akan datang. Mengingat sifat deret waktunya, Anda dapat menghasilkan indikator seperti rata-rata kemenangan per tahun selama lima tahun sebelumnya, dan faktor-faktor lain semacam itu, untuk membuat model yang sangat akurat. Namun itu di luar cakupan tutorial ini, dan Anda akan memperlakukan setiap baris sebagai independen. Setiap baris data kita akan berisi satu tim untuk satu tahun tertentu.

Sean Lahman mengompilasi data ini di situs webnya dan data tersebut diubah menjadi sebuah basis data sqlite di sini.

Impor Data

Anda akan membaca data dengan mengeksekusi kueri pada basis data sqlite menggunakan paket sqlite3 dan mengonversinya menjadi DataFrame dengan pandas. Data Anda akan difilter untuk hanya memasukkan tim modern yang saat ini aktif dan hanya tahun ketika tim bermain 150 pertandingan atau lebih.

Pertama, unduh berkas “lahman2016.sqlite” (di sini). Lalu, muat Pandas dan ubah namanya menjadi pd demi efisiensi. Anda mungkin ingat bahwa pd adalah alias umum untuk Pandas. Terakhir, muat sqlite3 dan hubungkan ke basis data, seperti ini:

# import `pandas` and `sqlite3`import pandas as pdimport sqlite3# Connecting to SQLite Databaseconn = sqlite3.connect('lahman2016.sqlite')

Berikutnya, tulis kueri, eksekusi, dan ambil hasilnya.

# Querying Database for all seasons where a team played 150 or more games and is still active today. query = '''select * from Teams inner join TeamsFranchiseson Teams.franchID == TeamsFranchises.franchIDwhere Teams.G >= 150 and TeamsFranchises.active == 'Y';'''# Creating dataframe from query.Teams = conn.execute(query).fetchall()

Tip: Jika Anda ingin mempelajari lebih lanjut tentang penggunaan SQL dengan Python, pertimbangkan untuk mengambil kursus DataCamp Introduction to Databases in Python.

Menggunakan pandas, Anda kemudian mengonversi hasil ke DataFrame dan mencetak 5 baris pertama menggunakan metode head():

# Convert `Teams` to DataFrame
teams_df = pd.DataFrame(_____)

# Print out first 5 rows
print(_______________)

Setiap kolom berisi data terkait satu tim dan tahun tertentu. Beberapa variabel yang lebih penting tercantum di bawah. Daftar lengkap variabel dapat ditemukan di sini.

  • yearID - Tahun
  • teamID - Tim
  • franchID - Waralaba (terhubung ke tabel TeamsFranchise)
  • G - Jumlah pertandingan dimainkan
  • W - Kemenangan
  • LgWin - Juara Liga (Y atau N)
  • WSWin - Pemenang World Series (Y atau N)
  • R - Run dicetak
  • AB - At bat
  • H - Hit oleh pemukul
  • HR - Home run oleh pemukul
  • BB - Walk oleh pemukul
  • SO - Strikeout oleh pemukul
  • SB - Basis tercuri
  • CS - Tertangkap mencuri
  • HBP - Pemukul terkena lemparan
  • SF - Sacrifice fly
  • RA - Run lawan yang dicetak
  • ER - Earned run yang diizinkan
  • ERA - Rata-rata earned run
  • CG - Complete game
  • SHO - Shutout
  • SV - Save
  • IPOuts - Out yang dilempar (inning dilempar x 3)
  • HA - Hit yang diizinkan
  • HRA - Home run yang diizinkan
  • BBA - Walk yang diizinkan
  • SOA - Strikeout oleh pitcher
  • E - Error
  • DP - Double play
  • FP - Persentase fielding
  • name - Nama lengkap tim

Bagi Anda yang mungkin kurang akrab dengan baseball, berikut penjelasan singkat cara permainan ini berjalan, beserta beberapa variabel yang disertakan.

Baseball dimainkan antara dua tim (yang bisa Anda temukan kembali di data dengan name atau teamID) yang masing-masing terdiri dari sembilan pemain. Kedua tim ini bergantian menjadi tim pemukul dan tim bertahan. Tim pemukul berupaya mencetak run dengan bergiliran memukul bola yang dilemparkan oleh pitcher dari tim bertahan, lalu berlari berlawanan arah jarum jam mengelilingi empat base: pertama, kedua, ketiga, dan home plate. Tim bertahan berusaha mencegah run dengan mengeliminasi pemukul atau pelari base dengan berbagai cara dan sebuah run (R) dicetak ketika seorang pemain berkeliling base dan kembali ke home plate. Seorang pemain dari tim pemukul yang mencapai base dengan selamat akan berusaha maju ke base berikutnya saat giliran rekan setimnya memukul, misalnya pada sebuah hit (H), basis tercuri (SB), atau dengan cara lain.

baseball

Kedua tim bertukar antara memukul dan bertahan setiap kali tim bertahan mencatat tiga out. Satu giliran memukul untuk kedua tim, dimulai dari tim tamu, merupakan satu inning. Satu pertandingan terdiri dari sembilan inning, dan tim dengan jumlah run lebih banyak di akhir pertandingan menjadi pemenang. Baseball tidak memiliki jam pertandingan dan meskipun sebagian besar pertandingan berakhir pada inning kesembilan, jika pertandingan imbang setelah sembilan inning maka akan dilanjutkan ke extra innings dan akan berlanjut tanpa batas hingga salah satu tim unggul di akhir inning tambahan.

Untuk penjelasan mendetail mengenai permainan baseball, lihat peraturan resmi Major League Baseball.

Membersihkan dan Menyiapkan Data

Seperti yang Anda lihat di atas, DataFrame belum memiliki header kolom. Anda dapat menambahkan header dengan meneruskan daftar header Anda ke atribut columns dari pandas.

Fungsi len() akan memberi tahu berapa banyak baris yang Anda hadapi: 2.287 bukan jumlah titik data yang besar untuk dikerjakan, jadi semoga tidak terlalu banyak nilai null.

Sebelum menilai kualitas data, mari singkirkan terlebih dahulu kolom yang tidak diperlukan atau yang diturunkan dari kolom target (Wins). Di sinilah pengetahuan tentang data yang Anda kerjakan menjadi sangat berharga. Tidak masalah seberapa banyak Anda tahu tentang pengkodean atau statistik jika Anda tidak memiliki pengetahuan tentang data yang Anda kerjakan. Menjadi penggemar baseball seumur hidup jelas membantu saya dalam proyek ini.

# Dropping your unnecesary column variables.
drop_cols = ['lgID','franchID','divID','Rank','Ghome','L','DivWin','WCWin','LgWin','WSWin','SF','name','park','attendance','BPF','PPF','teamIDBR','teamIDlahman45','teamIDretro','franchID','franchName','active','NAassoc']

df = teams_df.drop(drop_cols, axis=1)

# Print out first rows of `df`
print(_________)

Seperti yang Anda baca di atas, nilai null memengaruhi kualitas data, yang pada gilirannya dapat menyebabkan masalah pada algoritme machine learning.

Itulah mengapa Anda akan menghapusnya berikutnya. Ada beberapa cara untuk mengeliminasi nilai null, tetapi mungkin lebih baik untuk terlebih dahulu menampilkan jumlah nilai null untuk setiap kolom agar Anda dapat memutuskan cara terbaik menanganinya.

# Print out null values of all columns of `df`
print(_________.sum(axis=0).tolist())

Dan di sinilah Anda akan melihat trade-off: Anda butuh data bersih, tetapi Anda juga tidak memiliki banyak data untuk dibuang. Dua kolom memiliki jumlah nilai null yang relatif kecil. Ada 110 nilai null di kolom SO (Strike Out) dan 22 di kolom DP (Double Play). Dua kolom lainnya memiliki jumlah yang relatif besar. Ada 419 nilai null di kolom CS (Caught Stealing) dan 1777 di kolom HBP (Hit by Pitch).

Jika Anda menghapus baris di mana kolom memiliki sejumlah kecil nilai null, Anda kehilangan sedikit di atas lima persen data kita. Karena Anda mencoba memprediksi kemenangan, run yang dicetak dan run yang diizinkan sangat berkorelasi dengan target. Anda ingin data di kolom-kolom tersebut sangat akurat.

Strike out (SO) dan double play (DP) tidak sepenting itu.

Menurut saya, lebih baik Anda mempertahankan baris-baris tersebut dan mengisi nilai null dengan nilai median dari masing-masing kolom menggunakan metode fillna(). Tertangkap mencuri (CS) dan terkena lemparan (HBP) juga bukan variabel yang sangat penting. Dengan begitu banyak nilai null di kolom-kolom ini, sebaiknya hilangkan kolom-kolom tersebut semuanya.

# Eliminating columns with null values
df = df.drop(['CS','HBP'], axis=1)

# Filling null values
df['SO'] = df['SO'].fillna(df['SO'].median())
df['DP'] = df['DP'].fillna(df['DP'].median())

# Print out null values of all columns of `df`
print(df.isnull().sum(axis=0).tolist())

Mengeksplorasi dan Memvisualisasikan Data

Sekarang setelah Anda membersihkan data, Anda dapat melakukan eksplorasi. Anda bisa mendapatkan pemahaman yang lebih baik tentang himpunan data dengan beberapa visualisasi sederhana. matplotlib adalah pustaka yang sangat baik untuk visualisasi data.

Anda mengimpor matplotlib.pyplot dan menamainya ulang menjadi plt demi efisiensi. Jika Anda bekerja dengan Jupyter notebook, Anda perlu menggunakan magic %matplotlib inline.

Anda akan mulai dengan membuat histogram kolom target agar dapat melihat distribusi kemenangan.

# import the pyplot module from matplotlibimport matplotlib.pyplot as plt# matplotlib plots inline  %matplotlib inline# Plotting distribution of winsplt.hist(df['W'])plt.xlabel('Wins')plt.title('Distribution of Wins')plt.show()

grafik distribusi

Perhatikan bahwa jika Anda tidak menggunakan Jupyter notebook, Anda harus menggunakan plt.show() untuk menampilkan plot.

Cetak rata-rata kemenangan (W) per tahun. Anda dapat menggunakan metode mean() untuk ini.

print(df['_'].______)

Membuat bin untuk kolom target bisa berguna saat mengeksplorasi data Anda, tetapi Anda perlu memastikan untuk tidak memasukkan fitur apa pun yang Anda hasilkan dari kolom target saat melatih model. Menyertakan kolom label yang dihasilkan dari kolom target dalam set pelatihan Anda seperti memberikan jawaban ujian kepada model.

Untuk membuat label kemenangan Anda, Anda akan membuat fungsi bernama assign_win_bins yang akan menerima nilai integer (kemenangan) dan mengembalikan integer 1–5 tergantung pada nilai input.

Selanjutnya, Anda akan membuat kolom baru win_bins dengan menggunakan metode apply() pada kolom kemenangan dan meneruskan fungsi assign_win_bins().

# Creating bins for the win column
def assign_win_bins(_):
    if W < 50:
        return 1
    if W >= 50 and W <= 69:
        return 2
    if W >= 70 and W <= 89:
        return 3
    if W >= 90 and W <= 109:
        return 4
    if W >= 110:
        return 5
        
# Apply `assign_win_bins` to `df['W']`    
df['win_bins'] = df['_'].apply(______________)

Sekarang mari buat grafik sebar dengan tahun pada sumbu x dan kemenangan pada sumbu y serta sorot kolom win_bins dengan warna.

# Plotting scatter graph of Year vs. Winsplt.scatter(df['yearID'], df['W'], c=df['win_bins'])plt.title('Wins Scatter Plot')plt.xlabel('Year')plt.ylabel('Wins')plt.show()

proyek scikit-learn

Seperti yang Anda lihat pada plot sebar di atas, sangat sedikit musim sebelum 1900 dan permainan pada masa itu sangat berbeda. Karena itu, masuk akal untuk menghapus baris-baris tersebut dari himpunan data.

# Filter for rows where 'yearID' is greater than 1900
df = df[___________________]

Ketika bekerja dengan data kontinu dan membuat model linear, nilai integer seperti tahun dapat menimbulkan masalah. Kemungkinan kecil angka 1950 akan memiliki hubungan yang sama dengan data lain seperti yang akan disimpulkan model.

Anda dapat menghindari masalah ini dengan membuat variabel baru yang memberi label data berdasarkan nilai yearID.

Siapa pun yang mengikuti permainan baseball tahu bahwa seiring berjalannya Major League Baseball (MLB), muncul era-era berbeda di mana jumlah run per pertandingan meningkat atau menurun secara signifikan. Era dead ball pada awal 1900-an adalah contoh era dengan skor rendah dan era steroid pada pergantian abad ke-21 adalah contoh era dengan skor tinggi.

Mari buat grafik di bawah yang menunjukkan seberapa banyak skor pada tiap tahun.

Anda akan mulai dengan membuat kamus runs_per_year dan games_per_year. Lakukan perulangan melalui dataframe menggunakan metode iterrows(). Isi kamus runs_per_year dengan tahun sebagai kunci dan berapa banyak run yang dicetak pada tahun tersebut sebagai nilai. Isi kamus games_per_year dengan tahun sebagai kunci dan berapa banyak pertandingan yang dimainkan pada tahun tersebut sebagai nilai.

# Create runs per year and games per year dictionaries
runs_per_year = {}
games_per_year = {}

for i, row in df.iterrows():
    year = row['yearID']
    runs = row['R']
    games = row['G']
    if year in runs_per_year:
        runs_per_year[year] = runs_per_year[year] + runs
        games_per_year[year] = games_per_year[year] + games
    else:
        runs_per_year[year] = runs
        games_per_year[year] = games
        
print(runs_per_year)
print(games_per_year)

Berikutnya, buat kamus bernama mlb_runs_per_game. Lakukan iterasi melalui kamus games_per_year dengan metode items(). Isi kamus mlb_runs_per_game dengan tahun sebagai kunci dan jumlah run per pertandingan, di seluruh liga, sebagai nilai.

# Create MLB runs per game (per year) dictionary
mlb_runs_per_game = {}
for k, v in games_per_year.items():
    year = k
    games = v
    runs = runs_per_year[year]
    mlb_runs_per_game[year] = runs / games
    
print(mlb_runs_per_game)

Terakhir, buat plot dari kamus mlb_runs_per_game dengan menempatkan tahun pada sumbu x dan run per pertandingan pada sumbu y.

# Create lists from mlb_runs_per_game dictionarylists = sorted(mlb_runs_per_game.items())x, y = zip(*lists)# Create line plot of Year vs. MLB runs per Gameplt.plot(x, y)plt.title('MLB Yearly Runs per Game')plt.xlabel('Year')plt.ylabel('MLB Runs per Game')plt.show()

analitik baseball scikit-learn

Menambahkan Fitur Baru

Sekarang setelah Anda memiliki gambaran yang lebih baik tentang tren perolehan skor, Anda dapat membuat variabel baru yang menunjukkan era tertentu tempat setiap baris data berada berdasarkan yearID. Anda akan mengikuti proses yang sama seperti saat membuat kolom win_bins di atas.

Kali ini, Anda akan membuat kolom dummy; satu kolom baru untuk setiap era. Anda dapat menggunakan metode get_dummies() untuk ini.

# Creating "year_label" column, which will give your algorithm information about how certain years are related 
# (Dead ball eras, Live ball/Steroid Eras)

def assign_label(____):
    if year < 1920:
        return 1
    elif year >= 1920 and year <= 1941:
        return 2
    elif year >= 1942 and year <= 1945:
        return 3
    elif year >= 1946 and year <= 1962:
        return 4
    elif year >= 1963 and year <= 1976:
        return 5
    elif year >= 1977 and year <= 1992:
        return 6
    elif year >= 1993 and year <= 2009:
        return 7
    elif year >= 2010:
        return 8
        
# Add `year_label` column to `df`    
df['year_label'] = df['yearID'].apply(___________)

dummy_df = pd.get_dummies(df['year_label'], prefix='era')

# Concatenate `df` and `dummy_df`
df = pd.concat([df, dummy_df], axis=1)

print(df.head())

Karena Anda sudah menghitung jumlah run MLB per pertandingan untuk setiap tahun, tambahkan data tersebut ke set data.

# Create column for MLB runs per game from the mlb_runs_per_game dictionary
def assign_mlb_rpg(year):
    return mlb_runs_per_game[year]

df['mlb_rpg'] = df['yearID'].apply(assign_mlb_rpg)

Sekarang Anda akan mengonversi tahun menjadi dekade dengan membuat kolom dummy untuk setiap dekade. Lalu Anda dapat menghapus kolom yang tidak lagi dibutuhkan.

# Convert years into decade bins and creating dummy variables
def assign_decade(year):
    if year < 1920:
        return 1910
    elif year >= 1920 and year <= 1929:
        return 1920
    elif year >= 1930 and year <= 1939:
        return 1930
    elif year >= 1940 and year <= 1949:
        return 1940
    elif year >= 1950 and year <= 1959:
        return 1950
    elif year >= 1960 and year <= 1969:
        return 1960
    elif year >= 1970 and year <= 1979:
        return 1970
    elif year >= 1980 and year <= 1989:
        return 1980
    elif year >= 1990 and year <= 1999:
        return 1990
    elif year >= 2000 and year <= 2009:
        return 2000
    elif year >= 2010:
        return 2010
    
df['decade_label'] = df['yearID'].apply(assign_decade)
decade_df = pd.get_dummies(df['decade_label'], prefix='decade')
df = pd.concat([df, decade_df], axis=1)

# Drop unnecessary columns
df = df.drop(['yearID','year_label','decade_label'], axis=1)

Inti dari permainan bisbol adalah berapa banyak run yang Anda cetak dan berapa banyak run yang Anda biarkan. Anda dapat secara signifikan meningkatkan akurasi model dengan membuat kolom yang merupakan rasio dari kolom data lain. Run per pertandingan dan run yang diizinkan per pertandingan akan menjadi fitur yang sangat baik untuk ditambahkan ke set data kita.

Pandas membuat ini sangat sederhana karena Anda membuat kolom baru dengan membagi kolom R dengan kolom G untuk membuat kolom R_per_game.

# Create new features for Runs per Game and Runs Allowed per Game
df['R_per_game'] = df['R'] / df['G']
df['RA_per_game'] = df['RA'] / df['G']

Sekarang lihat bagaimana masing-masing dari dua variabel baru tersebut berkaitan dengan kolom target kemenangan dengan membuat dua grafik sebar. Plot run per pertandingan pada sumbu x untuk satu grafik dan run yang diizinkan per pertandingan pada sumbu x untuk grafik lainnya. Plot kolom W pada masing-masing sumbu y.

# Create scatter plots for runs per game vs. wins and runs allowed per game vs. winsfig = plt.figure(figsize=(12, 6))ax1 = fig.add_subplot(1,2,1)ax2 = fig.add_subplot(1,2,2)ax1.scatter(df['R_per_game'], df['W'], c='blue')ax1.set_title('Runs per Game vs. Wins')ax1.set_ylabel('Wins')ax1.set_xlabel('Runs per Game')ax2.scatter(df['RA_per_game'], df['W'], c='red')ax2.set_title('Runs Allowed per Game vs. Wins')ax2.set_xlabel('Runs Allowed per Game')plt.show()

clusters

Sebelum masuk ke model machine learning apa pun, ada baiknya melihat bagaimana setiap variabel berkorelasi dengan variabel target. Pandas memudahkan hal ini dengan metode corr().

df.corr()['W']

Fitur lain yang dapat Anda tambahkan ke dataset adalah label yang diturunkan dari algoritme klaster K-means yang disediakan oleh sklearn. K-means adalah algoritme klaster sederhana yang membagi data berdasarkan jumlah centroid k yang Anda tentukan. Setiap titik data ditetapkan ke sebuah klaster berdasarkan centroid mana yang memiliki jarak Euclidean terendah dari titik data tersebut.

Anda dapat mempelajari lebih lanjut tentang pengklasteran K-means di sini.

Pertama, buat DataFrame yang mengecualikan variabel target:

attributes = ['G','R','AB','H','2B','3B','HR','BB','SO','SB','RA','ER','ERA','CG',
'SHO','SV','IPouts','HA','HRA','BBA','SOA','E','DP','FP','era_1','era_2','era_3','era_4','era_5','era_6','era_7','era_8','decade_1910','decade_1920','decade_1930','decade_1940','decade_1950','decade_1960','decade_1970','decade_1980','decade_1990','decade_2000','decade_2010','R_per_game','RA_per_game','mlb_rpg']

data_attributes = df[attributes]

# Print the first rows of `df`
print(df.head())

Satu hal yang harus Anda tentukan sebelum menggunakan model K-means adalah berapa banyak klaster yang Anda inginkan. Anda bisa mendapatkan gambaran yang lebih baik tentang jumlah klaster ideal dengan menggunakan fungsi silhouette_score() dari sklearn. Fungsi ini mengembalikan koefisien siluet rata-rata untuk semua sampel. Anda menginginkan skor siluet yang lebih tinggi, dan skor akan menurun saat lebih banyak klaster ditambahkan.

# Import necessary modules from `sklearn` 
from sklearn.cluster import KMeans
from sklearn import metrics

# Create silhouette score dictionary
s_score_dict = {}
for i in range(2,11):
    km = KMeans(n_clusters=i, random_state=1)
    l = km.fit_predict(data_attributes)
    s_s = metrics.silhouette_score(data_attributes, l)
    s_score_dict[i] = [s_s]

# Print out `s_score_dict`
print(s_score_dict)

Sekarang Anda dapat menginisialisasi model. Tetapkan jumlah klaster ke 6 dan random state ke 1. Tentukan jarak Euclidean untuk setiap titik data dengan menggunakan metode fit_transform() lalu visualisasikan klaster dengan grafik sebar.

# Create K-means model and determine euclidian distances for each data pointkmeans_model = KMeans(n_clusters=6, random_state=1)distances = kmeans_model.fit_transform(data_attributes)# Create scatter plot using labels from K-means model as colorlabels = kmeans_model.labels_plt.scatter(distances[:,0], distances[:,1], c=labels)plt.title('Kmeans Clusters')plt.show()

clusters

Sekarang tambahkan label dari klaster Anda ke set data sebagai kolom baru. Tambahkan juga string “labels” ke daftar attributes, untuk digunakan nanti.

# Add labels from K-means model to `df` DataFrame and attributes list
df['labels'] = labels
attributes.append('labels')

# Print the first rows of `df`
print(_________)

Sebelum Anda dapat membangun model, Anda perlu membagi data menjadi set train dan test. Anda melakukan ini karena jika Anda memutuskan untuk melatih model pada data yang sama dengan yang digunakan untuk menguji model, model Anda dapat dengan mudah overfit terhadap data: model akan lebih menghafal data daripada belajar darinya, yang menghasilkan model yang terlalu kompleks untuk data Anda. Hal itu juga menjelaskan mengapa model yang overfit akan berkinerja buruk saat Anda mencoba membuat prediksi dengan data baru.

Tetapi jangan khawatir dulu, ada sejumlah cara untuk melakukan cross-validation pada model Anda.

Kali ini, Anda akan mengambil sampel acak sebesar 75 persen dari data kita untuk set data train dan menggunakan 25 persen sisanya untuk set data test. Buat daftar numeric_cols berisi semua kolom yang akan Anda gunakan dalam model. Selanjutnya, buat DataFrame baru data dari DataFrame df dengan kolom-kolom dalam daftar numeric_cols. Lalu, buat juga set data train dan test dengan melakukan sampling pada DataFrame data.

# Create new DataFrame using only variables to be included in models
numeric_cols = ['G','R','AB','H','2B','3B','HR','BB','SO','SB','RA','ER','ERA','CG','SHO','SV','IPouts','HA','HRA','BBA','SOA','E','DP','FP','era_1','era_2','era_3','era_4','era_5','era_6','era_7','era_8','decade_1910','decade_1920','decade_1930','decade_1940','decade_1950','decade_1960','decade_1970','decade_1980','decade_1990','decade_2000','decade_2010','R_per_game','RA_per_game','mlb_rpg','labels','W']
data = df[numeric_cols]
print(data.head())

# Split data DataFrame into train and test sets
train = data.sample(frac=0.75, random_state=1)
test = data.loc[~data.index.isin(train.index)]

x_train = train[attributes]
y_train = train['W']
x_test = test[attributes]
y_test = test['W']

Memilih Metrik Galat dan Model

Mean Absolute Error (MAE) adalah metrik yang akan Anda gunakan untuk menentukan seberapa akurat model Anda. Metrik ini mengukur seberapa dekat prediksi terhadap hasil akhirnya. Secara khusus, untuk data ini, metrik galat ini akan memberi Anda nilai absolut rata-rata seberapa jauh prediksi Anda meleset dari sasarannya.

Artinya, jika rata-rata prediksi Anda meleset dari jumlah target sebesar 5 kemenangan, metrik galat Anda adalah 5.

Model pertama yang akan Anda latih adalah model regresi linear. Anda dapat mengimpor LinearRegression dan mean_absolute_error masing-masing dari sklearn.linear_model dan sklearn.metrics, lalu membuat model lr. Selanjutnya, Anda akan melakukan fitting pada model, membuat prediksi, dan menentukan mean absolute error dari model tersebut.

# Import `LinearRegression` from `sklearn.linear_model`
from sklearn.linear_model import ___________________

# Import `mean_absolute_error` from `sklearn.metrics`
from sklearn.metrics import mean_absolute_error

# Create Linear Regression model, fit model, and make predictions
lr = LinearRegression(normalize=True)
lr.fit(x_train, y_train)
predictions = lr.predict(x_test)

# Determine mean absolute error
mae = mean_absolute_error(y_test, predictions)

# Print `mae`
print(___)

Jika Anda ingat dari penjelasan di atas, rata-rata jumlah kemenangan adalah sekitar 79 kemenangan. Rata-rata, model meleset hanya sebesar 2,687 kemenangan.

Sekarang coba model regresi Ridge. Impor RidgeCV dari sklearn.linear_model dan buat model rrm. Model RidgeCV memungkinkan Anda menyetel parameter alpha, yaitu parameter kompleksitas yang mengontrol besarnya shrinkage (baca selengkapnya di sini). Model ini akan menggunakan cross-validation untuk menentukan parameter alpha mana yang paling ideal dari yang Anda sediakan.

Sekali lagi, lakukan fitting pada model Anda, buat prediksi, dan tentukan mean absolute error-nya.

# Import `RidgeCV` from `sklearn.linear_model`
from sklearn.linear_model import _______

# Create Ridge Linear Regression model, fit model, and make predictions
rrm = RidgeCV(alphas=(0.01, 0.1, 1.0, 10.0), normalize=True)
rrm.fit(x_train, y_train)
predictions_rrm = rrm.predict(x_test)

# Determine mean absolute error
mae_rrm = mean_absolute_error(y_test, predictions_rrm)
print(________)

Model ini berkinerja sedikit lebih baik, dengan rata-rata meleset sebesar 2,673 kemenangan.

Analitik Olahraga & Scikit-Learn

Bagian pertama dari seri tutorial ini berakhir di sini, di mana Anda telah melihat bagaimana menggunakan scikit-Learn untuk menganalisis data olahraga. Anda mengimpor data dari basis data SQLite, membersihkannya, mengeksplorasi aspeknya secara visual, dan merekayasa sejumlah fitur baru. Anda mempelajari cara membuat model klastering K-means, beberapa model Regresi Linear, dan cara menguji prediksi menggunakan metrik mean absolute error.

Pada bagian kedua, Anda akan melihat cara menggunakan model klasifikasi untuk memprediksi pemain mana yang masuk ke MLB Hall of Fame.

Topik

Terkait

blogs

Tutorial Korelasi di R

blogs

Spaghetti Plot dan Jalur Badai

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026