不使用sklearn库编写KNN算法代码解决心脏病预测问题,包括数据处理,算法应用算法调参和模型评估
时间: 2024-02-04 07:02:03 浏览: 91
好的,让我来为您解答这个问题。
首先,我们需要准备数据。可以从UCI机器学习库中下载心脏病数据集。数据集包含13个输入特征和1个二元输出标签,其中1表示患有心脏病,0表示没有。我们需要将数据集分为训练集和测试集。
接下来,我们需要定义距离度量函数。在KNN算法中,我们需要计算测试数据点与每个训练数据点之间的距离。通常使用欧氏距离作为距离度量函数。
接着,我们需要实现KNN算法。算法的核心思想是找到与测试数据点最近的K个训练数据点,并根据它们的标签进行投票,以确定测试数据点的标签。
在KNN算法中,K的值是一个重要的超参数。我们需要通过尝试不同的K值来找到最佳的K值。为了评估模型的性能,我们可以使用准确率、精确率、召回率、F1值等指标。
最后,我们需要对模型进行评估。我们可以使用交叉验证等技术来评估模型的泛化能力。
代码实现如下:
```python
import numpy as np
# 数据处理
def load_data():
data = np.genfromtxt('heart.csv', delimiter=',', skip_header=1)
X = data[:, :-1]
y = data[:, -1].astype(int)
return X, y
def split_data(X, y, test_ratio=0.3):
n_samples = X.shape[0]
n_test = int(n_samples * test_ratio)
indices = np.random.permutation(n_samples)
X_train = X[indices[:-n_test]]
y_train = y[indices[:-n_test]]
X_test = X[indices[-n_test:]]
y_test = y[indices[-n_test:]]
return X_train, y_train, X_test, y_test
# 距离度量函数
def euclidean_distance(x1, x2):
return np.sqrt(np.sum((x1 - x2) ** 2))
# KNN算法
class KNN:
def __init__(self, k=3):
self.k = k
def fit(self, X, y):
self.X_train = X
self.y_train = y
def predict(self, X):
y_pred = np.zeros(X.shape[0])
for i, x in enumerate(X):
distances = [euclidean_distance(x, x_train) for x_train in self.X_train]
k_indices = np.argsort(distances)[:self.k]
k_nearest_labels = [self.y_train[i] for i in k_indices]
y_pred[i] = max(set(k_nearest_labels), key=k_nearest_labels.count)
return y_pred
# 模型调参
def grid_search(X_train, y_train, X_val, y_val):
best_acc = 0
best_k = None
for k in range(1, 10):
knn = KNN(k=k)
knn.fit(X_train, y_train)
y_val_pred = knn.predict(X_val)
acc = np.mean(y_val_pred == y_val)
if acc > best_acc:
best_acc = acc
best_k = k
return best_k
# 模型评估
def evaluate(y_true, y_pred):
acc = np.mean(y_true == y_pred)
tp = np.sum((y_true == 1) & (y_pred == 1))
tn = np.sum((y_true == 0) & (y_pred == 0))
fp = np.sum((y_true == 0) & (y_pred == 1))
fn = np.sum((y_true == 1) & (y_pred == 0))
precision = tp / (tp + fp)
recall = tp / (tp + fn)
f1 = 2 * precision * recall / (precision + recall)
return {'accuracy': acc, 'precision': precision, 'recall': recall, 'f1': f1}
# 主程序
X, y = load_data()
X_train, y_train, X_test, y_test = split_data(X, y, test_ratio=0.3)
best_k = grid_search(X_train, y_train, X_test, y_test)
knn = KNN(k=best_k)
knn.fit(X_train, y_train)
y_test_pred = knn.predict(X_test)
metrics = evaluate(y_test, y_test_pred)
print(metrics)
```
注意,由于KNN算法的计算复杂度较高,因此在处理大规模数据时可能会遇到性能问题。此外,KNN算法对输入数据的特征缩放敏感,因此在应用算法时应该进行特征缩放。
阅读全文