77 lines
3.4 KiB
Python
77 lines
3.4 KiB
Python
import numpy as np
|
|
class DecisionTreeRegressor:
|
|
def __init__(self, max_depth=3):
|
|
self.max_depth = max_depth
|
|
self.tree = None
|
|
def fit(self, X, y):
|
|
self.tree = self._grow_tree(X, y)
|
|
def _grow_tree(self, X, y, depth=0):
|
|
n_samples, n_features = X.shape
|
|
if depth < self.max_depth:
|
|
best_feature, best_threshold = self._best_split(X, y)
|
|
if best_feature is not None:
|
|
left_indices = X[:, best_feature] < best_threshold
|
|
right_indices = X[:, best_feature] >= best_threshold
|
|
left_child = self._grow_tree(X[left_indices], y[left_indices], depth + 1)
|
|
right_child = self._grow_tree(X[right_indices], y[right_indices], depth + 1)
|
|
return (best_feature, best_threshold, left_child, right_child)
|
|
return np.mean(y)
|
|
def _best_split(self, X, y):
|
|
best_mse = float('inf')
|
|
best_feature, best_threshold = None, None
|
|
n_samples, n_features = X.shape
|
|
|
|
for feature in range(n_features):
|
|
thresholds = np.unique(X[:, feature])
|
|
for threshold in thresholds:
|
|
left_indices = X[:, feature] < threshold
|
|
right_indices = X[:, feature] >= threshold
|
|
if len(y[left_indices]) > 0 and len(y[right_indices]) > 0:
|
|
left_mse = np.mean((y[left_indices] - np.mean(y[left_indices])) ** 2)
|
|
right_mse = np.mean((y[right_indices] - np.mean(y[right_indices])) ** 2)
|
|
mse = (len(y[left_indices]) * left_mse + len(y[right_indices]) * right_mse) / n_samples
|
|
|
|
if mse < best_mse:
|
|
best_mse = mse
|
|
best_feature = feature
|
|
best_threshold = threshold
|
|
return best_feature, best_threshold
|
|
def predict(self, X):
|
|
return np.array([self._predict_sample(sample, self.tree) for sample in X])
|
|
def _predict_sample(self, sample, node):
|
|
if isinstance(node, tuple):
|
|
feature, threshold, left_child, right_child = node
|
|
if sample[feature] < threshold:
|
|
return self._predict_sample(sample, left_child)
|
|
else:
|
|
return self._predict_sample(sample, right_child)
|
|
return node
|
|
class GradientBoostingRegressor:
|
|
def __init__(self, n_estimators=100, learning_rate=0.1, max_depth=3):
|
|
self.n_estimators = n_estimators
|
|
self.learning_rate = learning_rate
|
|
self.max_depth = max_depth
|
|
self.models = []
|
|
def fit(self, X, y):
|
|
y_pred = np.zeros(y.shape)
|
|
for _ in range(self.n_estimators):
|
|
residuals = y - y_pred
|
|
model = DecisionTreeRegressor(max_depth=self.max_depth)
|
|
model.fit(X, residuals)
|
|
y_pred += self.learning_rate * model.predict(X)
|
|
self.models.append(model)
|
|
def predict(self, X):
|
|
y_pred = np.zeros(X.shape[0])
|
|
for model in self.models:
|
|
y_pred += self.learning_rate * model.predict(X)
|
|
return y_pred
|
|
# Example usage
|
|
if __name__ == "__main__":
|
|
# Sample data
|
|
X = np.array([[1], [2], [3], [4], [5]])
|
|
y = np.array([1.5, 1.7, 3.5, 3.7, 5.0])
|
|
model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=2)
|
|
model.fit(X, y)
|
|
predictions = model.predict(X)
|
|
print("Predictions:", predictions)
|