# Почему предсказания дерева решений не совпадает с ожиданием?

``````import numpy as np
import pandas as pd

class MyTreeClf:
def __init__(self, max_depth=5, min_samples_split=2, max_leafs=20):
self.max_depth = max_depth
self.min_samples_split = min_samples_split
self.max_leafs = max_leafs
self.tree = None
self.leafs_cnt = 0

def node_entropy(self, probs):
return -np.sum([p * np.log2(p) for p in probs if p > 0])

def node_ig(self, x_col, y, split_value):

return 0

entropy_after = (len(y[left_mask]) / len(y) * self.node_entropy(left_probs) +
entropy_before = self.node_entropy(np.bincount(y) / len(y))

return entropy_before - entropy_after

def get_best_split(self, X: pd.DataFrame, y: pd.Series):
best_col, best_split_value, best_ig = None, None, -np.inf

for col in X.columns:
sorted_unique_values = np.sort(X[col].unique())

for i in range(1, len(sorted_unique_values)):
split_value = (sorted_unique_values[i - 1] + sorted_unique_values[i]) / 2

ig = self.node_ig(X[col], y, split_value)

if ig > best_ig:
best_ig = ig
best_col = col
best_split_value = split_value

return best_col, best_split_value

def fit(self, X: pd.DataFrame, y: pd.Series, depth=1, node=None):
if self.max_leafs < 2:
self.leafs_cnt = 2

if node is None:
node = {}
self.tree = node

best_col, best_split_value = self.get_best_split(X, y)

node['type'] = None
node['feature'] = best_col
node['threshold'] = best_split_value

tmp_leafs = 2

if len(y.unique()) == 1:
self.leafs_cnt += 1
tmp_leafs -= 1
node['type'] = 'leaf'
node['class_counts'] = dict(zip(*np.unique(y, return_counts=True)))
return

if len(y) == 1:
self.leafs_cnt += 1
tmp_leafs -= 1
node['type'] = 'leaf'
node['class_counts'] = dict(zip(*np.unique(y, return_counts=True)))
return

if depth > self.max_depth or len(y) < self.min_samples_split or (tmp_leafs + self.leafs_cnt) > self.max_leafs:
self.leafs_cnt += 1
tmp_leafs -= 1
node['type'] = 'leaf'
node['class_counts'] = dict(zip(*np.unique(y, return_counts=True)))
return

if best_col is None:
self.leafs_cnt += 1
tmp_leafs -= 1
node['type'] = 'leaf'
node['class_counts'] = dict(zip(*np.unique(y, return_counts=True)))
return

node['type'] = 'node'
node['feature'] = best_col
node['threshold'] = best_split_value

tmp_leafs += 2

node['left'] = {}
node['right'] = {}

def bypass_tree(self, node, sample):
while node['type'] == 'node':
feature_value = sample[node['feature']]
if feature_value <= node['threshold']:
node = node['left']
else:
node = node['right']

if node['type'] == 'leaf':
return node

def predict(self, X: pd.DataFrame):
classification = []
proba = self.predict_proba(X)
for p in proba:
if p > 0.5:
classification.append(1)
else:
classification.append(0)

return classification

def predict_proba(self, X: pd.DataFrame):
proba = []

for _, sample in X.iterrows():
node = self.bypass_tree(self.tree, sample)
if node:
overall_cnt = sum(node['class_counts'].values())
class1_cnt = node['class_counts'].get(1, 0)
class1_proba = (class1_cnt / overall_cnt) if overall_cnt > 0 else 0.0

proba.append(class1_proba)

return np.array(proba)

df.columns = ['variance', 'skewness', 'curtosis', 'entropy', 'target']
X, y = df.iloc[:, :4], df['target']

model1 = MyTreeClf(max_depth=3, min_samples_split=2, max_leafs=5)
model1.fit(X, y)

result1 = model1.predict_proba(X)
print(result1)

from sklearn.tree import DecisionTreeClassifier

model2 = DecisionTreeClassifier(max_depth=3, min_samples_split=2, max_leaf_nodes=5)
model2.fit(X, y)

result2 = model2.predict_proba(X)

print(result2[:, 1])``````

Здравствуйте. Пытаюсь сделать методы '''predict()''' и '''predict_proba()''' и когда сверяю результаты моего '''predict_proba()''' и в реализации от sklearn, то значения не совпадают. Я предполагаю что проблема либо в неправильном подсчете вероятностей, либо же в неправильных сплитах данных.

Проверка

Входные данные: два набора параметров для дерева решений

Выходные данные: возвращенные предсказания (их сумма) вероятностей и меток

Sample Input:
{"max_depth": 3, "min_samples_split": 2, "max_leafs": 1}

Sample Output:
11.2443438914 (у меня был ответ 10.0)

К сожалению, того самого датасета у меня нет, но я использую для проверки sklearn и датасет "Banknote authentication"
Вот ссылка: https://archive.ics.uci.edu/static/public/267/bank...
Подробнее про задачу: https://stepik.org/lesson/333977/step/7?unit=317388
• Вопрос задан
• 90 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Maksim_64
Data Analyst
А почему ты решил, что вероятности должны совпадать с твоей реализацией.
predict_proba из scikit-learn не в коем случае не считает вероятности а калибрует их. И он вполне может это делать плохо.

DecisionTreeClassifier в принципе не является детерминистическим, результаты могут отличаться (не обязательно, но могут.
Ответ написан
Ваш ответ на вопрос

### Войдите, чтобы написать ответ

Похожие вопросы
от 170 000 до 190 000 ₽
SpectrumData Екатеринбург
от 150 000 до 250 000 ₽
Wanted. Лимассол
До 6 000 €
14 сент. 2024, в 10:35
10000 руб./за проект
14 сент. 2024, в 10:09
10000 руб./за проект
14 сент. 2024, в 08:35
18000 руб./за проект