Python实现机器学习算法:K近邻和决策树详解
随着数据越来越庞大,传统的统计方法无法满足现代数据分析的需求。机器学习算法成为了数据科学的重要部分。在机器学习中,K近邻算法和决策树算法是两个非常常用的算法。现在我们来详细探讨一下这两个算法的实现。
K近邻算法
K近邻算法,简称KNN算法,是一种基于实例的学习方法。它的核心思想是根据相邻样本的特征进行预测。KNN算法是一种无参数的算法,它没有训练过程,因此它被认为是一种经验风险最小化算法。
KNN算法的实现步骤如下:
1. 计算测试样本与各个训练样本之间的距离。
2. 根据距离计算出K个最近邻居。
3. 根据K个最近邻居中出现最多的类别来决定测试样本的类别。
KNN算法在编程时需要注意以下几点:
· 需要将样本之间的距离计算出来,距离的计算方式可以使用欧几里得距离、曼哈顿距离等。
· KNN算法是考虑最近邻样本的方法,因此需要选定合适的K值。
下面是Python代码实现:
```python
import numpy as np
from collections import Counter
class KNN:
def __init__(self, k=5, distance_method='euclidean'):
self.k = k
self.distance_method = distance_method
def fit(self, x_train, y_train):
self.x_train = x_train
self.y_train = y_train
def predict(self, x_test):
predictions = []
for test_sample in x_test:
distances = []
for train_sample in self.x_train:
if self.distance_method == 'euclidean':
distance = np.sqrt(np.sum((test_sample - train_sample) ** 2))
elif self.distance_method == 'manhattan':
distance = np.sum(abs(test_sample - train_sample))
distances.append(distance)
distances = np.array(distances)
indices = np.argsort(distances)
indices = indices[:self.k]
k_nearest_classes = self.y_train[indices]
most_common_class = Counter(k_nearest_classes).most_common(1)
predictions.append(most_common_class[0][0])
return predictions
```
在代码中,我们首先定义了KNN类。并且我们可以通过传入k值和距离计算方式来初始化该类。在fit方法中,我们将训练数据和训练标签保存下来。在predict方法中,我们首先计算测试样本和训练样本之间的距离,然后根据距离排序,选取距离最近的k个邻居。最后,我们使用Counter对象来统计邻居中出现最多的类别,作为测试样本的预测类别。
决策树算法
决策树算法是一种基于树形结构的有监督学习算法。它通过将数据集分成不同的子集来构建一个树形结构的分类模型。每个叶子节点代表一个类别。决策树学习的过程就是从根节点开始,根据节点上的特征,将数据样本分配到不同的子节点中去。这个过程重复递归进行,直到某个节点的所有样本都属于同一类别,或者达到预先设定的终止条件。
决策树算法的实现步骤如下:
1. 选择最优特征划分数据集。
2. 根据最优特征划分数据集,使得各个子集的类别尽可能一致。
3. 递归地建立决策树。
4. 终止条件:当前节点所有样本属于同一类别,或者当前节点无法再进行特征划分。
决策树算法在编程时需要注意以下几点:
· 需要选择合适的特征划分方法,可以使用信息增益、信息增益比等方法。
· 需要考虑如何处理连续型特征。
下面是Python代码实现:
```python
import numpy as np
from collections import Counter
class Node:
def __init__(self, feature=None, feature_i=None, pred=None, left=None, right=None):
self.feature = feature
self.feature_i = feature_i
self.pred = pred
self.left = left
self.right = right
class DecisionTree:
def __init__(self, impurity='gini', max_depth=None):
self.impurity = impurity
self.max_depth = max_depth
def _gini(self, y):
_, counts = np.unique(y, return_counts=True)
p = counts / len(y)
gini = 1 - np.sum(p ** 2)
return gini
def _entropy(self, y):
_, counts = np.unique(y, return_counts=True)
p = counts / len(y)
entropy = -np.sum(p * np.log2(p))
return entropy
def _select_feature(self, x, y):
feature_scores = []
if self.impurity == 'gini':
impurity_func = self._gini
elif self.impurity == 'entropy':
impurity_func = self._entropy
base_score = impurity_func(y)
for i in range(x.shape[1]):
sample_values = np.unique(x[:, i])
feature_score = base_score
for value in sample_values:
left_idx = x[:, i] < value
right_idx = x[:, i] >= value
left_y = y[left_idx]
right_y = y[right_idx]
left_score = impurity_func(left_y) * len(left_y)
right_score = impurity_func(right_y) * len(right_y)
score = base_score - (left_score + right_score) / len(y)
feature_score += score
feature_scores.append(feature_score)
feature_scores = np.array(feature_scores)
return np.argmin(feature_scores), np.min(feature_scores)
def _build_tree(self, x, y, depth=0):
if len(np.unique(y)) == 1:
return Node(pred=y[0])
elif depth == self.max_depth:
most_common_y = Counter(y).most_common(1)[0][0]
return Node(pred=most_common_y)
else:
feature_i, _ = self._select_feature(x, y)
feature_values = np.unique(x[:, feature_i])
node = Node(feature=feature_i, feature_i=feature_i)
for value in feature_values:
idx = x[:, feature_i] == value
if np.sum(idx) == 0:
most_common_y = Counter(y).most_common(1)[0][0]
node.left = Node(pred=most_common_y)
else:
left_x = x[idx]
left_y = y[idx]
node.left = self._build_tree(left_x, left_y, depth + 1)
if np.sum(~idx) == 0:
most_common_y = Counter(y).most_common(1)[0][0]
node.right = Node(pred=most_common_y)
else:
right_x = x[~idx]
right_y = y[~idx]
node.right = self._build_tree(right_x, right_y, depth + 1)
return node
def fit(self, x_train, y_train):
self.tree = self._build_tree(x_train, y_train)
def predict(self, x_test):
predictions = []
for sample in x_test:
node = self.tree
while node.feature is not None:
if sample[node.feature] < np.unique(x_train[:, node.feature])[0]:
node = node.left
else:
node = node.right
predictions.append(node.pred)
return predictions
```
在代码中,我们首先定义了Node类,表示决策树上的节点。它有一个属性feature表示该节点的特征,feature_i表示该特征在数据集中的位置,pred表示该节点的预测类别,left和right表示该节点左右子节点。
然后我们定义了DecisionTree类,它有两个属性:impurity表示特征选择的方法,max_depth表示建立决策树的最大深度。在_fit方法中,我们通过_build_tree方法递归地建立决策树。在_predict方法中,我们对测试样本进行遍历,递归寻找对应的叶子节点,返回该节点的预测类别。
结语
KNN算法和决策树算法是机器学习中非常常用的算法,对于数据分析工作来说都是必备技能。Python是机器学习中最受欢迎的编程语言之一,它的实现让我们更方便地学习和使用这些算法。希望本文对您对于KNN算法和决策树算法的理解有所帮助。