knn算法,带你走入机器学习
机器学习是一个朝气蓬勃的计算机新领域.这个领域充满着乐趣,同样也存在着无限的挑战.今天,我们就从一个简单的机器学习算法k值最邻近算法(k_nearst_neighbor,knn)入手走进机器学习的神圣殿堂.
knn简介
基础知识
在学习k值最邻近算法之前,我们先来认识一下距离概念.我们在评估两个事物间的相似性时通常会比较这两个事物特征间的差距,而事物具有多个特征,在机器学习里边,我们会把一个事物看做一个n维坐标点,维数取决于特征数,坐标点在坐标轴上的映射即是其每个特征的评分值.因此,两个事物的相似性可以用坐标轴上两点的距离来表示.通常我们选用的距离表示方式包括欧氏距离和曼哈顿距离.如果用(x,y),(x1,y1)来表示两点的话,欧式距离即两点间的直线距离,公式表示为:
曼哈顿距离即路线距离,公式表示为:
ρ=|X1-X2|+|Y1-Y2|
.事物间距离越大相似性越小,反之同理.knn算法距离的计算采用的是欧式距离.
机器学习过程
机器学习的大致过程包括,数据清洗—>模型训练—>模型测试---->模型检验
机器学习分类
机器学习大致可以分为监测学习和非监测学习,二者的区别就在于训练数据是否具有标签.
knn算法
k值最邻近算法是一个基础及其学习算法,它的计算原理比较简单,预测精度较低,问题较多,一般不做实际的使用.
它的原理是将测试数据集中元素与训练数据集中元数求距离以后由小到大排序后选取距离最小的一个数据范围(k),又叫超参数,并在此范围内求标签众数,将众数作为预测结果输出.
knn基本操作代码实现
# 从excel文件中读取数据
data = pd.read_excel('电影分类数据.xlsx')
# 处理数据
data1 = data.loc[:, :'电影类型']
data2 = data.loc[:, '电影名':]
# 求距离
for i in range(data2['电影名'].size):
data[f'distance{i + 1}'] = np.sqrt(
list(((data1.loc[:, '搞笑镜头':'打斗镜头'].values - data2.iloc[i, 1:].values) ** 2).sum(axis=1)))
data = data.sort_values(by=f'distance{i + 1}')
# 输出结果print(pd.Series(data.index).mode())
knn算法精度问题
机器学习所做的预测也不是百分百准确,我们将机器学习预测得到结果的准确度称为机器学习精度.
通俗理解,精度的计算,就是计算准确结果占所有预测次数的频率.
计算精度的代码实现如下:
# 从文件中读取数据
file_name_list = os.listdir('D:\python project\数据分析\digits\\testDigits')
# 处理数据函数
def get_excel(file_name_list):
data = np.vstack(
[np.array(list( ''.join((pd.read_table('D:\python project\数据分析\digits\\trainingDigits' + f'\\{i}', header=None).values.reshape(1,-1)[0]))))for i in file_name_list])
data = pd.DataFrame(data, index=[i for i in file_name_list])
name = file_name_list.split('\\')[-1]
data.to_excel(f'{name}.xlsx')
# 训练加测试
def get_result():
data1 = pd.read_excel('1.xlsx', index_col=0)
data2 = pd.read_excel('2.xlsx', index_col=0)
for j in range(1, 22, 2):
real = []
predict = []
for i in range(data2.index.size):
data1[f'distance{i + 1}'] = np.sqrt(
((data1.iloc[:, :1024].values.astype('int') - data2.iloc[i, :1024].values.astype('int')) ** 2).sum(axis=1))
data = data1.sort_values(by=f'distance{i + 1}')
real.append(pd.Series(data.iloc[:j, :].index).str[0].mode()[0])
predict.append(data2.index[i][0])
data2['real'] = real
data2['predict'] = predict
# 统计正确预测数量
data2['result'] = data2['real'] == data2['predict']
# 输出精度
print(j, data2['result'].sum() / data2['result'].count())
print(data2.groupby('real')['result'].agg('sum') / data2.groupby('real')['result'].agg('count'))
get_result()
Knn算法提高精度
影响knn算法精度的唯一因素就是选取众数范围的问题即k值的选取问题.我们可以给定一个k值额范围,并求每个k值下的精度,作比较以后确定k值(超参数),上面代码已实现.
机器学习第三方包sklearn
sklearn是python的一个第三方机器学习工具包,囊括了大部分机器学习算法,且其底层优C语言编写,比python代码实现的机器学习算法效率提高了很多.且其代码实现简单,大大提高了开发者工作效率.
下载方式: pip install sklearn
# sklearn 实现 knn
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
data1 = pd.read_excel('1.xlsx', index_col=0)
data2 = pd.read_excel('2.xlsx', index_col=0)
# 处理数据
train_x = data1
train_y = pd.Series(data1.index).str[0]
text_x = data2
text_y = pd.Series(data2.index).str[0]
# 实例化模型
knn = KNeighborsClassifier(n_neighbors=5)
# 拟合训练
knn.fit(train_x, train_y)
# 测试
predict_y = knn.predict(text_x)
print(predict_y)
# 输出精度
print(knn.score(text_x, text_y))
网格交叉验证
网格交叉验证是一种基本的交叉验证思想,底层逻辑包含了交叉验证思想.交叉验证即将数据集分成n等份后依次选出一份作为测试集,其他作为训练集,并此数据进行训练,总共进行n次训练,将n次训练精度的平均值作为此模型的精度输出.网格搜索是在此基础上检验不同k值下的knn算法输出的精度.
代码实现如下:
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
# K_neighbors实例化
knn = KNeighborsClassifier()
# 初始化网格模型
params = {'n_neighbors': range(2, 20)}
grid_cv = GridSearchCV(knn, param_grid=params, cv=10)
# 评估模型精度
grid_cv.fit(concat_data, pd.Series(concat_data.index).str[0])
# 输出 最优结果的k值
print(grid_cv.best_params_)
# 输出最高精度
print(grid_cv.best_score_)