< Home
4. Machine Learning¶
Assignment¶
Fit a machine learning model to your data
What I've learnt this week¶
I try to learn about Neil's sample code with my dataset.<br>
First I put reading csv code, as all the codes need it.
In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# === 1. Load dataset ===
df = pd.read_csv('./datasets/Wine_dataset.csv') # Modify file name if different
Neural Networks¶
In [1]:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
df = pd.read_csv('./datasets/Wine_dataset.csv')
x = df[df.keys()[11]]
print(x)
#x = np.linspace(-3,3,100)
plt.plot(x,1/(1+np.exp(-x)),label='sigmoid')
plt.plot(x,np.tanh(x),label='tanh')
plt.plot(x,np.where(x < 0,0,x),label='ReLU')
plt.plot(x,np.where(x < 0,0.1*x,x),'--',label='leaky ReLU')
plt.legend()
plt.show()
plt.scatter(df[df.keys()[10]],df[df.keys()[1]],c='b')
plt.scatter(df[df.keys()[11]],df[df.keys()[1]], c='r')
#plt.plot(df[df.keys()[1]])
plt.show()
0 1.04
1 1.05
2 1.03
3 0.86
4 1.04
...
173 0.64
174 0.70
175 0.59
176 0.60
177 0.61
Name: Hue, Length: 178, dtype: float64
In [1]:
import jax
import jax.numpy as jnp
from jax import random,grad,jit
import pandas as pd
# -----------------------------
# ① Wine データ読み込み
# -----------------------------
df = pd.read_csv('./datasets/Wine_dataset.csv')
# Alcohol → X, Color intensity → y
X_np = df[['Alcohol']].to_numpy()
#from chatGPT
y_min = df['Color intensity'].min()
y_max = df['Color intensity'].max()
y_np = (df[['Color intensity']] - y_min) / (y_max - y_min)
X = jnp.array(X_np)
y = jnp.array(y_np.to_numpy()).reshape(-1, 1)
# 乱数キー
key = random.PRNGKey(0)
# -----------------------------
# forward
# -----------------------------
@jit
def forward(params,layer_0):
Weight1,bias1,Weight2,bias2 = params
layer_1 = jnp.tanh(layer_0@Weight1 + bias1)
#layer_2 = jax.nn.sigmoid(layer_1@Weight2 + bias2)
layer_2 = layer_1 @ Weight2 + bias2 # ← これだけでOK
return layer_2
# loss
@jit
def loss(params):
ypred = forward(params,X)
return jnp.mean((ypred - y)**2)
# update
@jit
def update(params, rate=0.5):
gradient = grad(loss)(params)
return jax.tree.map(lambda p,g: p - rate * g, params, gradient)
# -----------------------------
# ③ パラメータ初期化(ここだけ形を修正)
# -----------------------------
def init_params(key):
key1,key2 = random.split(key)
Weight1 = 0.5 * random.normal(key1,(1,4)) # 入力1
bias1 = jnp.zeros(4)
Weight2 = 0.5 * random.normal(key2,(4,1)) # 出力1
bias2 = jnp.zeros(1)
return (Weight1,bias1,Weight2,bias2)
params = init_params(key)
# -----------------------------
# 学習ループ
# -----------------------------
for step in range(501):
params = update(params, rate=0.1)
if step % 100 == 0:
print(f"step {step} loss={loss(params):.4f}")
# 結果
pred = forward(params, X)
jnp.set_printoptions(precision=2)
#print(jnp.c_[X, pred])
result = jnp.c_[X, pred]
print(
jnp.vstack([
result[:5],
result[-5:]
])
)
step 0 loss=0.0389 step 100 loss=0.0389 step 200 loss=0.0389 step 300 loss=0.0389 step 400 loss=0.0389 step 500 loss=0.0389 [[14.23 0.32] [13.2 0.32] [13.16 0.32] [14.37 0.32] [13.24 0.32] [13.71 0.32] [13.4 0.32] [13.27 0.32] [13.17 0.32] [14.13 0.32]]
Next, I asked chatGPT to make python code of analysis of wine data using the example code.
In [4]:
import jax
import jax.numpy as jnp
from jax import random, grad, jit
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# ============================
# 1. Load Dataset
# ============================
df = pd.read_csv('./datasets/Wine_dataset.csv')
# Split into features (X) and labels (y)
X = df.drop("class", axis=1).values
y = df["class"].values
# Convert labels from 1,2,3 → 0,1,2
y = y - 1
# Standardize features (mean 0, std 1)
X = (X - X.mean(axis=0)) / X.std(axis=0)
# Convert to jax.numpy
X = jnp.array(X, dtype=jnp.float32)
y = jnp.array(y, dtype=jnp.int32)
# Split into train (80%) and test (20%)
train_size = int(len(y) * 0.8)
xtrain, xtest = X[:train_size], X[train_size:]
ytrain, ytest = y[:train_size], y[train_size:]
print("Train samples:", len(xtrain))
print("Test samples:", len(xtest))
print("Feature size:", X.shape[1])
# ============================
# 2. Hyperparameters
# ============================
input_size = X.shape[1] # Number of features (13)
hidden_size = 32 # Hidden layer size
output_size = 3 # 3 classes
learning_rate = 0.05
train_steps = 2000
# Random key for initialization
key = random.PRNGKey(0)
# ============================
# 3. Initialize Parameters
# ============================
def init_params(key, input_size, hidden_size, output_size):
k1, k2, k3 = random.split(key, 3)
W1 = 0.1 * random.normal(k1, (input_size, hidden_size))
b1 = jnp.zeros(hidden_size)
W2 = 0.1 * random.normal(k2, (hidden_size, output_size))
b2 = jnp.zeros(output_size)
return (W1, b1, W2, b2)
params = init_params(key, input_size, hidden_size, output_size)
# ============================
# 4. Forward Pass
# ============================
@jit
def forward(params, x):
W1, b1, W2, b2 = params
h = jnp.tanh(x @ W1 + b1) # Hidden layer with tanh activation
logits = h @ W2 + b2 # Output layer (logits)
return logits
# ============================
# 5. Loss Function (Cross-Entropy)
# ============================
@jit
def loss(params, x, y):
logits = forward(params, x)
exp = jnp.exp(logits)
probs = exp / jnp.sum(exp, axis=1, keepdims=True)
log_probs = -jnp.log(probs[jnp.arange(len(y)), y])
return jnp.mean(log_probs)
# ============================
# 6. Parameter Update (Gradient Descent)
# ============================
@jit
def update(params, x, y, rate):
grads = grad(loss)(params, x, y)
return jax.tree.map(lambda p, g: p - rate * g, params, grads)
# ============================
# 7. Training Loop
# ============================
print("Start learning...")
for step in range(train_steps):
params = update(params, xtrain, ytrain, learning_rate)
if step % 200 == 0:
print(f"step {step}, loss={loss(params, xtrain, ytrain):.4f}")
# ============================
# 8. Evaluate on Test Data
# ============================
logits = forward(params, xtest)
pred = jnp.argmax(logits, axis=1)
accuracy = jnp.mean(pred == ytest)
print("\n=== Test Accuracy ===")
print(f"Accuracy: {accuracy * 100:.2f}%")
# ============================
# 9. Show Sample Predictions
# ============================
print("\n=== Prediction examples ===")
for i in range(10):
print(f"True: {int(ytest[i])+1} Predicted: {int(pred[i])+1}")
Train samples: 142 Test samples: 36 Feature size: 13 Start learning... step 0, loss=0.9613 step 200, loss=0.0671 step 400, loss=0.0366 step 600, loss=0.0252 step 800, loss=0.0190 step 1000, loss=0.0151 step 1200, loss=0.0123 step 1400, loss=0.0104 step 1600, loss=0.0089 step 1800, loss=0.0077 === Test Accuracy === Accuracy: 100.00% === Prediction examples === True: 3 Predicted: 3 True: 3 Predicted: 3 True: 3 Predicted: 3 True: 3 Predicted: 3 True: 3 Predicted: 3 True: 3 Predicted: 3 True: 3 Predicted: 3 True: 3 Predicted: 3 True: 3 Predicted: 3 True: 3 Predicted: 3
Loss Curve¶
I learnt making loss curve using sklearn and made it with help of Mr. Tuchiya.
In [5]:
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import StandardScaler
from sklearn import model_selection
import numpy as np
from datetime import datetime as dt
X = df.loc[:,['Color intensity','Hue','Total phenols']]
columns = X.columns
X = X.to_numpy()
print(X.shape)
df_a = df.dropna(subset=['Alcohol'])
df_a['Alcohol'] = df_a['Alcohol'].astype(int) # 念のため整数化
Y = df_a['Alcohol'].to_numpy()
Y = np.ravel(Y)
print(Y.shape)
scaler = StandardScaler()
X = scaler.fit_transform(X)
#Y = scaler.fit_transform(Y)
X_train,X_test,y_train,y_test = model_selection.train_test_split(X,Y,test_size=0.2)
print(X_train.shape, X_test.shape,y_train.shape,y_test.shape)
model = MLPClassifier()
starttime = dt.now()
model.fit(X_train,y_train)
endtime = dt.now()
print("Predict:",model.score(X_test,y_test)," time:", (endtime.timestamp() - starttime.timestamp()))
plt.title("Loss Curve")
plt.plot(model.loss_curve_)
plt.xlabel("Iteration")
plt.ylabel("Loss")
plt.grid()
(178, 3) (178,) (142, 3) (36, 3) (142,) (36,) Predict: 0.4444444444444444 time: 0.04396510124206543
/Users/lauramt/miniforge3/lib/python3.12/site-packages/sklearn/neural_network/_multilayer_perceptron.py:781: ConvergenceWarning: Stochastic Optimizer: Maximum iterations (200) reached and the optimization hasn't converged yet. warnings.warn(
In [ ]: