fix:memperbaiki model svr

This commit is contained in:
muhamad fais aizat 2025-05-08 14:39:07 +07:00
parent f277d8fcab
commit 0aa83453fc
7 changed files with 73 additions and 99 deletions

View File

@ -27,7 +27,7 @@ async def read_data(db: Session = Depends(get_db)):
FROM predict.price_tomat AS pt
JOIN predict.result_predict AS rp ON pt.id = rp.id
ORDER BY rp.id ASC
LIMIT 1 OFFSET 30) AS tanggal_old,
LIMIT 1 OFFSET 29) AS tanggal_old,
(SELECT tanggal
FROM predict.price_tomat
@ -78,20 +78,25 @@ def predict_price(db: Session = Depends(get_db)):
raise HTTPException(status_code=400, detail="Data tidak cukup untuk melakukan prediksi")
# Preprocessing data
df['RataRata_Kemarin'] = pd.to_numeric(df['RataRata_Kemarin'], errors='coerce')
df['RataRata_Sekarang'] = pd.to_numeric(df['RataRata_Sekarang'], errors='coerce')
kolom_numerik = ['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', 'RataRata_Sekarang']
df[kolom_numerik] = df[kolom_numerik].apply(pd.to_numeric, errors='coerce')
df[kolom_numerik] = df[kolom_numerik].replace(0, np.nan)
# Interpolasi nilai kosong (0 yang sudah jadi NaN)
df[kolom_numerik] = df[kolom_numerik].interpolate(method='linear', limit_direction='both')
# Drop jika masih ada NaN (misalnya di ujung data)
df.dropna(inplace=True)
df['Tanggal'] = pd.to_datetime(df['Tanggal'])
df['RataRata_2Hari_Lalu'] = df['RataRata_Kemarin'].shift(1)
# df['Harga_2Hari_Lalu'] = df['Harga_Kemarin'].shift(1)
df.dropna(inplace=True)
# Normalisasi Data
scaler = StandardScaler()
df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', 'RataRata_2Hari_Lalu', 'RataRata_Sekarang']] = scaler.fit_transform(
df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', 'RataRata_2Hari_Lalu', 'RataRata_Sekarang']]
df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', 'RataRata_Sekarang']] = scaler.fit_transform(
df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', 'RataRata_Sekarang']]
)
X = df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', 'RataRata_2Hari_Lalu']].values
X = df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', ]].values
y = df['RataRata_Sekarang'].values
ids = df['id'].values
tanggal = df['Tanggal'].values
@ -108,15 +113,6 @@ def predict_price(db: Session = Depends(get_db)):
degree = int(settings.nilai_degree) if settings.nilai_degree is not None else 3
coef0 = float(settings.nilai_coef) if settings.nilai_coef is not None else 0.0
# Inisialisasi Model SVR
# if kernel == "linear":
# svr = SVR(kernel=kernel, C=C, epsilon=epsilon)
# else:
# svr = SVR(kernel=kernel, C=C, gamma=gamma, epsilon=epsilon)
# if kernel in ["poly", "sigmoid"]:
# svr.coef0 = coef0
# if kernel == "poly":
# svr.degree = degree
if kernel == "linear":
svr = SVR(kernel="linear", C=C, epsilon=epsilon)
@ -129,19 +125,6 @@ def predict_price(db: Session = Depends(get_db)):
elif kernel == "poly":
svr = SVR(kernel="poly", C=C, gamma=gamma, coef0=coef0, degree=degree, epsilon=epsilon)
# **Melakukan Prediksi Rolling Window**
hasil_prediksi = []
X = df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', 'RataRata_2Hari_Lalu']].values
y = df['RataRata_Sekarang'].values
# # Latih model dengan semua data yang tersedia
# svr.fit(X, y)
# # Prediksi harga untuk semua tanggal di masa depan
# for i in range(len(df)):
# fitur_input = X[i]
# prediksi = svr.predict([fitur_input])[0]
# hasil_prediksi.append(prediksi)
# Latih model dengan data latih
svr.fit(X_train, y_train)
@ -159,14 +142,12 @@ def predict_price(db: Session = Depends(get_db)):
# Gabungkan hasil prediksi ke data uji
for i in range(len(y_pred)):
id_tomat = id_test[i]
tanggal_pred = tanggal_test[i]
hasil = y_pred[i]
hasil_asli = y_test[i]
# Invers hasil prediksi
dummy_row = np.zeros((1, 6)) # [0, 0, 0, 0, 0, hasil_prediksi]
dummy_row[0][5] = hasil
prediksi_asli = float(scaler.inverse_transform(dummy_row)[0][5])
dummy_row = np.zeros((1, 5)) # [0, 0, 0, 0, 0, hasil_prediksi]
dummy_row[0][4] = hasil
prediksi_asli = float(scaler.inverse_transform(dummy_row)[0][4])
existing = db.execute(select(resultPredict).where(resultPredict.c.id == id_tomat)).fetchone()
if existing:
@ -214,7 +195,7 @@ def get_price_history(
latest_date = latest_date_query[0] # Ambil tanggal terbaru
if tanggal_input == latest_date:
# **Melakukan Prediksi 30 Hari ke Depan**
# **Melakukan Prediksi 7 Hari ke Depan**
settings = db.execute(select(settingPredict).where(settingPredict.c.status == True)).fetchone()
if not settings:
raise HTTPException(status_code=400, detail="Tidak ada konfigurasi prediksi yang aktif")
@ -237,11 +218,17 @@ def get_price_history(
raise HTTPException(status_code=400, detail="Data tidak cukup untuk melakukan prediksi")
# Preprocessing
# 3. Perbaiki Format Tanggal
df['Tanggal'] = pd.to_datetime(df['Tanggal'], dayfirst=True, errors='coerce')
kolom_numerik = ['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'RataRata_Kemarin', 'RataRata_Sekarang']
df[kolom_numerik] = df[kolom_numerik].apply(pd.to_numeric, errors='coerce')
df[kolom_numerik] = df[kolom_numerik].replace(0, np.nan)
# Interpolasi nilai kosong (0 yang sudah jadi NaN)
df[kolom_numerik] = df[kolom_numerik].interpolate(method='linear', limit_direction='both')
# Drop jika masih ada NaN (misalnya di ujung data)
df.dropna(inplace=True)
# 4. Hapus Data yang Gagal Dikoreksi (jika ada)
df = df.dropna(subset=['Tanggal']).reset_index(drop=True)
df['Tanggal'] = pd.to_datetime(df['Tanggal'])
# df['Harga_2Hari_Lalu'] = df['Harga_Kemarin'].shift(1)
df.dropna(inplace=True)
# 6. Normalisasi Data
# scaler = MinMaxScaler()

View File

@ -50,29 +50,35 @@ def predict_price(
raise HTTPException(status_code=400, detail="Data tidak cukup untuk melakukan prediksi")
# Preprocessing
df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']] = df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']].apply(pd.to_numeric, errors='coerce')
df.dropna(inplace=True)
df['Tanggal'] = pd.to_datetime(df['Tanggal'])
df['Harga_2Hari_Lalu'] = df['Harga_Kemarin'].shift(1)
# df['Harga_2Hari_Lalu'] = df['Harga_Kemarin'].shift(1).bfill()
# Pastikan semua kolom numerik
kolom_numerik = ['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']
df[kolom_numerik] = df[kolom_numerik].apply(pd.to_numeric, errors='coerce')
df[kolom_numerik] = df[kolom_numerik].replace(0, np.nan)
# Interpolasi nilai kosong (0 yang sudah jadi NaN)
df[kolom_numerik] = df[kolom_numerik].interpolate(method='linear', limit_direction='both')
# Drop jika masih ada NaN (misalnya di ujung data)
df.dropna(inplace=True)
# df['Tanggal'] = pd.to_datetime(df['Tanggal'])
# df.dropna(inplace=True)
# Simpan hasil preprocessing
hasil_preprocessing = df.to_dict(orient='records')
# Normalisasi Data
# scaler = MinMaxScaler()
# df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_2Hari_Lalu', 'Harga_Sekarang']] = scaler.fit_transform(df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_2Hari_Lalu', 'Harga_Sekarang']])
# df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']] = scaler.fit_transform(df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']])
scaler = StandardScaler()
df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_2Hari_Lalu', 'Harga_Sekarang']] = scaler.fit_transform(df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_2Hari_Lalu', 'Harga_Sekarang']])
df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']] = scaler.fit_transform(df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']])
# Simpan hasil normalisasi
hasil_normalisasi = df.to_dict(orient='records')
# Split Data
X = df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_2Hari_Lalu']]
X = df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin']]
y = df['Harga_Sekarang']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
@ -84,23 +90,6 @@ def predict_price(
"y_test": y_test.tolist()
}
# Inisialisasi Model SVR dengan parameter yang dipilih
# svr_params = {
# "kernel": kernel,
# "C": C,
# "gamma": gamma,
# "epsilon": epsilon
# }
# # Jika kernel adalah Polynomial atau Sigmoid, tambahkan coef0
# if kernel in ["poly", "sigmoid"]:
# svr_params["coef0"] = coef0
# # Jika kernel adalah Polynomial, tambahkan degree
# if kernel == "poly":
# svr_params["degree"] = degree
# svr = SVR(**svr_params)
if kernel == "linear":
svr = SVR(kernel="linear", C=C, epsilon=epsilon)
@ -125,7 +114,7 @@ def predict_price(
# Kembalikan skala data
df_prediksi = df.iloc[len(X_train):].copy()
df_prediksi['Tanggal'] = df_prediksi['Tanggal'].dt.date
# df_prediksi['Tanggal'] = df_prediksi['Tanggal'].dt.date
df_prediksi['Harga_Prediksi'] = y_pred
# Daftar kolom yang telah dinormalisasi
@ -150,33 +139,32 @@ def predict_price(
std = np.sqrt(scaler.var_[index])
df_prediksi[kolom] = df_prediksi[kolom] * std + mean
# Ambil nilai min dan max dari scaler
# data_min = scaler.data_min_
# data_max = scaler.data_max_
# feature_names = scaler.feature_names_in_.tolist()
# # Invers Harga_Prediksi berdasarkan skala 'Harga_Sekarang'
# index_harga_sekarang = feature_names.index('Harga_Sekarang')
# min_sekarang = data_min[index_harga_sekarang]
# max_sekarang = data_max[index_harga_sekarang]
# df_prediksi['Harga_Prediksi'] = df_prediksi['Harga_Prediksi'] * (max_sekarang - min_sekarang) + min_sekarang
# df_prediksi['Harga_Prediksi'] = df_prediksi['Harga_Prediksi'].round(0)
# # Invers kolom lain yang tersedia di df_prediksi
# for kolom in cols_scaled:
# if kolom in df_prediksi.columns:
# index = feature_names.index(kolom)
# min_val = data_min[index]
# max_val = data_max[index]
# df_prediksi[kolom] = df_prediksi[kolom] * (max_val - min_val) + min_val
# Export atau tampilkan hasil
hasil_prediksi = df_prediksi[['Tanggal', 'Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak',
'Harga_Kemarin', 'Harga_Sekarang', 'Harga_Prediksi']].to_dict(orient='records')
# # Cek jumlah data bernilai 0 awal
# zero_data_log = {"Sebelum Preprocessing": (df == 0).sum().to_dict()}
# # Konversi ke numerik dan hitung 0 setelah konversi
# df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']] = df[['Pasar_Bandung', 'Pasar_Ngunut', 'Pasar_Ngemplak', 'Harga_Kemarin', 'Harga_Sekarang']].apply(pd.to_numeric, errors='coerce')
# zero_data_log["Setelah Konversi Numerik"] = (df == 0).sum().to_dict()
# # Hapus NaN dan hitung 0 setelah drop NaN
# df.dropna(inplace=True)
# zero_data_log["Setelah Drop NaN Pertama"] = (df == 0).sum().to_dict()
# # Konversi tanggal
# df['Tanggal'] = pd.to_datetime(df['Tanggal'], errors='coerce')
# zero_data_log["Setelah Konversi Tanggal"] = (df == 0).sum().to_dict()
# # Tambah fitur Harga_2Hari_Lalu
# df['Harga_2Hari_Lalu'] = df['Harga_Kemarin'].shift(1)
# zero_data_log["Setelah Tambah Harga_2Hari_Lalu"] = (df == 0).sum().to_dict()
# # Drop NaN setelah penambahan fitur dan hitung 0
# df.dropna(inplace=True)
# zero_data_log["Setelah Drop NaN Kedua"] = (df == 0).sum().to_dict()
@ -188,7 +176,6 @@ def predict_price(
"C": C,
"Gamma": gamma,
"Epsilon": epsilon,
# "Zero_Data_Log": zero_data_log,
"Data_Asli": data_asli,
"Hasil_Preprocessing": hasil_preprocessing,
"Hasil_Normalisasi": hasil_normalisasi,

View File

@ -58,7 +58,7 @@ const Normalisasi = ({ result }) => {
<div className='flex justify-between items-center mb-5'>
<div className='grid gap-3 items-center'>
<h1 className='text-[14px] font-semibold'>Normalisasi Data</h1>
<p className='pr-[30px] text-[10px]'>Tahap ini data dinormalisasi menggunakan StandardScaler agar semua nilai berada dalam rentang -0 hingga 1</p>
<p className='pr-[30px] text-[10px]'>Tahap ini data dinormalisasi menggunakan StandardScaler agar semua nilai berada dalam rentang negatif dan positif </p>
</div>
<div className="relative w-full md:w-[308px] h-[32px]">
<SearchNormal1 className="absolute left-[16px] top-1/2 transform -translate-y-1/2" size={16} />
@ -84,7 +84,7 @@ const Normalisasi = ({ result }) => {
<TableHead className="text-center font-bold text-black">Pasar Ngemplak</TableHead>
<TableHead className="text-center font-bold text-black">Rata-Rata Kemarin</TableHead>
<TableHead className="text-center font-bold text-black">Rata-Rata Sekarang</TableHead>
<TableHead className="text-center font-bold text-black">Harga 2Hari Lalu</TableHead>
{/* <TableHead className="text-center font-bold text-black">Harga 2Hari Lalu</TableHead> */}
</TableRow>
</TableHeader>
<TableBody className="bg-white">
@ -97,7 +97,7 @@ const Normalisasi = ({ result }) => {
<TableCell className="text-center">{item.Pasar_Ngemplak}</TableCell>
<TableCell className="text-center">{item.Harga_Kemarin}</TableCell>
<TableCell className="text-center">{item.Harga_Sekarang}</TableCell>
<TableCell className="text-center">{item.Harga_2Hari_Lalu}</TableCell>
{/* <TableCell className="text-center">{item.Harga_2Hari_Lalu}</TableCell> */}
</TableRow>
))
) : (

View File

@ -79,7 +79,7 @@ const Preprocessing = ({ result }) => {
<div className='flex justify-between items-center mb-5'>
<div className='grid gap-3 items-center'>
<h1 className='text-[14px] font-semibold'>Preprocessing</h1>
<p className='pr-[30px] text-[10px]'>Tahap ini dilakukan untuk mengubah kolom angka menjadi tipe numerik, menghapus nilai yang kosong, mengubah format tanggal menjadi format date time, menambahkan fitur baru Harga 2Hari Lalu sebagai tambahan informasi historis.</p>
<p className='pr-[30px] text-[10px]'>Tahap ini dilakukan untuk mengubah kolom angka menjadi tipe numerik, menghapus nilai yang kosong, mengisi nilai 0 dengan interpolasi linear.</p>
</div>
<div className='xl:flex grid gap-3'>
<div className="relative w-full md:w-[308px] h-[32px]">
@ -108,7 +108,7 @@ const Preprocessing = ({ result }) => {
<TableHead className="text-center font-bold text-black">Pasar Ngemplak</TableHead>
<TableHead className="text-center font-bold text-black">Rata-Rata Kemarin</TableHead>
<TableHead className="text-center font-bold text-black">Rata-Rata Sekarang</TableHead>
<TableHead className="text-center font-bold text-black">Harga 2Hari Lalu</TableHead>
{/* <TableHead className="text-center font-bold text-black">Harga 2Hari Lalu</TableHead> */}
</TableRow>
</TableHeader>
<TableBody className="bg-white">
@ -121,7 +121,7 @@ const Preprocessing = ({ result }) => {
<TableCell className="text-center">{item.Pasar_Ngemplak}</TableCell>
<TableCell className="text-center">{item.Harga_Kemarin}</TableCell>
<TableCell className="text-center">{item.Harga_Sekarang}</TableCell>
<TableCell className="text-center">{item.Harga_2Hari_Lalu}</TableCell>
{/* <TableCell className="text-center">{item.Harga_2Hari_Lalu}</TableCell> */}
</TableRow>
))
) : (

View File

@ -88,7 +88,7 @@ const SplitData = ({ result }) => {
<div className='grid gap-3 items-center'>
<h1 className='text-[14px] font-semibold'>Memisahkan Data Latih dan Uji</h1>
<p className='pr-[30px] text-[10px]'>Data dibagi menjadi dua bagian:</p>
<p className='pr-[30px] text-[10px]'>X: Fitur yang digunakan untuk memprediksi (Pasar Bandung, Pasar Ngunut, Pasar Ngemplak, Harga Rata Rata Kemarin, Harga 2Hari Lalu).</p>
<p className='pr-[30px] text-[10px]'>X: Fitur yang digunakan untuk memprediksi (Pasar Bandung, Pasar Ngunut, Pasar Ngemplak, Harga Rata Rata Kemarin).</p>
<p className='pr-[30px] text-[10px]'>y: Target yang akan diprediksi (Harga Rata Rata Sekarang).</p>
</div>
@ -102,7 +102,7 @@ const SplitData = ({ result }) => {
<TableHead className="text-center font-bold text-black">Pasar Ngunut</TableHead>
<TableHead className="text-center font-bold text-black">Pasar Ngemplak</TableHead>
<TableHead className="text-center font-bold text-black">Rata-Rata Kemarin</TableHead>
<TableHead className="text-center font-bold text-black">Harga 2Hari Lalu</TableHead>
{/* <TableHead className="text-center font-bold text-black">Harga 2Hari Lalu</TableHead> */}
</TableRow>
</TableHeader>
<TableBody className="bg-white">
@ -113,7 +113,7 @@ const SplitData = ({ result }) => {
<TableCell className="text-center">{item.Pasar_Ngunut}</TableCell>
<TableCell className="text-center">{item.Pasar_Ngemplak}</TableCell>
<TableCell className="text-center">{item.Harga_Kemarin}</TableCell>
<TableCell className="text-center">{item.Harga_2Hari_Lalu}</TableCell>
{/* <TableCell className="text-center">{item.Harga_2Hari_Lalu}</TableCell> */}
</TableRow>
))
) : (
@ -193,7 +193,7 @@ const SplitData = ({ result }) => {
<TableHead className="text-center font-bold text-black">Pasar Ngunut</TableHead>
<TableHead className="text-center font-bold text-black">Pasar Ngemplak</TableHead>
<TableHead className="text-center font-bold text-black">Rata-Rata Kemarin</TableHead>
<TableHead className="text-center font-bold text-black">Harga 2Hari Lalu</TableHead>
{/* <TableHead className="text-center font-bold text-black">Harga 2Hari Lalu</TableHead> */}
</TableRow>
</TableHeader>
<TableBody className="bg-white">
@ -204,7 +204,7 @@ const SplitData = ({ result }) => {
<TableCell className="text-center">{item.Pasar_Ngunut}</TableCell>
<TableCell className="text-center">{item.Pasar_Ngemplak}</TableCell>
<TableCell className="text-center">{item.Harga_Kemarin}</TableCell>
<TableCell className="text-center">{item.Harga_2Hari_Lalu}</TableCell>
{/* <TableCell className="text-center">{item.Harga_2Hari_Lalu}</TableCell> */}
</TableRow>
))
) : (