共计 2867 个字符,预计需要花费 8 分钟才能阅读完成。
导读 | 今天给大家带来的是关于 Python 机器学习的相关知识, 文章围绕着 Python 底层实现 KNN 展开, 文中有非常详细的解释及代码示例, 需要的朋友可以参考下 |
一、导入数据
借助 python 自带的 pandas 库导入数据,很简单。用的数据是下载到本地的红酒集。
代码如下(示例):
import pandas as pd | |
def read_xlsx(csv_path): | |
data = pd.read_csv(csv_path) | |
print(data) | |
return data |
二、归一化
KNN 算法中将用到距离,因此归一化是一个重要步骤,可以消除数据的量纲。我用了归一化,消除量纲也可以用标准化,但是作为新手,我觉得归一化比较简单。
其中最大最小值的计算用到了 python 中的 numpy 库,pandas 导入的数据是 DateFrame 形式的,np.array() 用来将 DateFrame 形式转化为可以用 numpy 计算的 ndarray 形式。
代码如下(示例):
import numpy as np | |
def MinMaxScaler(data): | |
col = data.shape[1] | |
for i in range(0, col-1): | |
arr = data.iloc[:, i] | |
arr = np.array(arr) #将 DataFrame 形式转化为 ndarray 形式,方便后续用 numpy 计算 | |
min = np.min(arr) | |
max = np.max(arr) | |
arr = (arr-min)/(max-min) | |
data.iloc[:, i] = arr | |
return data |
三、分训练集和测试集
先将数据值和标签值分别用 x 和 y 划分开,设置随机数种子 random_state,若不设置,则每次运行的结果会不相同。test_size 表示测试集比例。
def train_test_split(data, test_size=0.2, random_state=None): | |
col = data.shape[1] | |
x = data.iloc[:, 0:col-1] | |
y = data.iloc[:, -1] | |
x = np.array(x) | |
y = np.array(y) | |
# 设置随机种子,当随机种子非空时,将锁定随机数 | |
if random_state: | |
np.random.seed(random_state) | |
# 将样本集的索引值进行随机打乱 | |
# permutation 随机生成 0 -len(data) 随机序列 | |
shuffle_indexs = np.random.permutation(len(x)) | |
# 提取位于样本集中 20% 的那个索引值 | |
test_size = int(len(x) * test_size) | |
# 将随机打乱的 20% 的索引值赋值给测试索引 | |
test_indexs = shuffle_indexs[:test_size] | |
# 将随机打乱的 80% 的索引值赋值给训练索引 | |
train_indexs = shuffle_indexs[test_size:] | |
# 根据索引提取训练集和测试集 | |
x_train = x[train_indexs] | |
y_train = y[train_indexs] | |
x_test = x[test_indexs] | |
y_test = y[test_indexs] | |
# 将切分好的数据集返回出去 | |
# print(y_train) | |
return x_train, x_test, y_train, y_test |
四、计算距离
此处用到欧氏距离,pow() 函数用来计算幂次方。length 指属性值数量,在计算最近邻时用到。
def CountDistance(train,test,length): | |
distance = 0 | |
for x in range(length): | |
distance += pow(test[x] - train[x], 2)**0.5 | |
return distance |
五、选择最近邻
计算测试集中的一条数据和训练集中的每一条数据的距离,选择距离最近的 k 个,以少数服从多数原则得出标签值。其中 argsort 返回的是数值从小到大的索引值,为了找到对应的标签值。
tip: 用 numpy 计算众数的方法
import numpy as np | |
#bincount():统计非负整数的个数,不能统计浮点数 | |
counts = np.bincount(nums) | |
#返回众数 | |
np.argmax(counts) |
少数服从多数原则,计算众数,返回标签值。
def getNeighbor(x_train,test,y_train,k): | |
distance = [] | |
#测试集的维度 | |
length = x_train.shape[1] | |
#测试集合所有训练集的距离 | |
for x in range(x_train.shape[0]): | |
dist = CountDistance(test, x_train[x], length) | |
distance.append(dist) | |
distance = np.array(distance) | |
#排序 | |
distanceSort = distance.argsort() | |
# distance.sort(key= operator.itemgetter(1)) | |
# print(len(distance)) | |
# print(distanceSort[0]) | |
neighbors =[] | |
for x in range(k): | |
labels = y_train[distanceSort[x]] | |
neighbors.append(labels) | |
# print(labels) | |
counts = np.bincount(neighbors) | |
label = np.argmax(counts) | |
# print(label) | |
return label |
调用函数时:
getNeighbor(x_train,x_test[0],y_train,3)
六、计算准确率
用以上 KNN 算法预测测试集中每一条数据的标签值,存入 result 数组,将预测结果与真实值比较,计算预测正确的个数与总体个数的比值,即为准确率。
def getAccuracy(x_test,x_train,y_train,y_test): | |
result = [] | |
k = 3 | |
# arr_label = getNeighbor(x_train, x_test[0], y_train, k) | |
for x in range(len(x_test)): | |
arr_label = getNeighbor(x_train, x_test[x], y_train, k) | |
result.append(arr_label) | |
correct = 0 | |
for x in range(len(y_test)): | |
if result[x] == y_test[x]: | |
correct += 1 | |
# print(correct) | |
accuracy = (correct / float(len(y_test))) * 100.0 | |
print("Accuracy:", accuracy, "%") | |
return accuracy |
总结
KNN 算是机器学习中最简单的算法,实现起来相对简单,到此这篇关于 Python 机器学习之底层实现 KNN 的文章就介绍到这了。
正文完
星哥玩云-微信公众号
