<jupyter_start><jupyter_text>K近邻算法- 根据周围点的标签，投票确定给定点的标签值 算法步骤1. 计算当前已知类别数据集中的点与当前点之间的距离2. 按照距离递增次序排序3. 选取与目标点最近的**K**个点4. 统计k个点中类别出现的频率5. 返回频率最高的类别作为当前点的预测类别 代码实现1. 构建原始数据集<jupyter_code>import pandas as pd
# import numpy as np
# import matplotlib.pyplot as plt
rowdata={'电影名称':['无问西东','后来的我们','前任3','红海行动','唐人街探案','战狼2'],
         '打斗镜头':[1,5,12,108,112,115],
         '接吻镜头':[101,89,97,5,9,8],
         '电影类型':['爱情片','爱情片','爱情片','动作片','动作片','动作片']
        }
movie_data=pd.DataFrame(rowdata)
movie_data<jupyter_output><empty_output><jupyter_text>2. 计算已知数据点和当前点的距离<jupyter_code>new_data=[24,67]
mines= (movie_data.iloc[:6,1:3]-new_data)**2
mines
#dist
summines=mines.sum(1)
summines
dist=list(summines**0.5)
dist<jupyter_output><empty_output><jupyter_text>3. 距离进行升序培训，选出k个点<jupyter_code>distframe=pd.DataFrame({'dist':dist,'labels':movie_data.iloc[:6,3]})
sorteddist=distframe.sort_values(by='dist')[:4]
sorteddist<jupyter_output><empty_output><jupyter_text>4. 确定前k个点所在类别出现的频率<jupyter_code>re=sorteddist.loc[:,'labels'].value_counts()
re<jupyter_output><empty_output><jupyter_text>5. 赋值类别<jupyter_code>result=[]
result.append(re.index[0])
result<jupyter_output><empty_output><jupyter_text>6. 封装函数<jupyter_code>def classify(rowdata,testdata,k):
    result=[]
    #计算dataset中的点和testdata中点之间的距离
    dataset=pd.DataFrame(rowdata)
    distance= (((dataset.iloc[:,1:3]-new_data)**2).sum(1))**0.5
    distlabelframe=pd.DataFrame({'dist':distance,'labels':dataset.iloc[:,3]})
    #排序
    sorteddist=distlabelframe.sort_values(by='dist')[:k]
    #统计类别的频数
    re=sorteddist.loc[:,'labels'].value_counts()
    result.append(re.index[0])
    return result

result= classify(movie_data,new_data,3)
res<jupyter_output><empty_output><jupyter_text>约会网站的分类效果 1. 读入数据<jupyter_code>datingTest= pd.read_table("datingTestSet.txt",header=None)
datingTest.head()<jupyter_output><empty_output><jupyter_text>2. 分析数据<jupyter_code>import matplotlib as mpl
import matplotlib.pyplot as plt

colors=[]
#根据喜欢程度的不同赋予不同的颜色
for i in range(datingTest.shape[0]):
    m=datingTest.iloc[i,-1]
    color='white'
    if(m=='didntLike'):
        color='black'
    if(m=='smallDoses'):
        color='orange'
    if(m=='largeDoses'):
        color='red'
    colors.append(color)
# 绘制散点图
plt.rcParams['font.sans-serif']=['Simhei'] #字体设置为黑体，缺失该句，就无法显示中文
pl=plt.figure(figsize=(12,8))
fig1=pl.add_subplot(221)
plt.scatter(datingTest.iloc[:,1],datingTest.iloc[:,2],marker='.',color=colors)
plt.xlabel('玩游戏视频所占时间比')
plt.ylabel('每周消费冰淇淋公升数')


fig2=pl.add_subplot(222)
plt.scatter(datingTest.iloc[:,0],datingTest.iloc[:,1],marker='.',color=colors)
plt.xlabel('每年常客飞行里程')
plt.ylabel('玩游戏视频所占时间比')


fig2=pl.add_subplot(223)
plt.scatter(datingTest.iloc[:,0],datingTest.iloc[:,2],marker='.',color=colors)
plt.xlabel('每年常客飞行里程')
plt.ylabel('每周消费冰淇淋公升数')

plt.show()<jupyter_output><empty_output><jupyter_text>3. 数值归一化<jupyter_code>"""
归一化
"""
def minmax(dataset):
    minDf=dataset.min()
    maxDf=dataset.max()
    normalset=(dataset-minDf)/(maxDf-minDf)
    return normalset

datingT= pd.concat([minmax(datingTest.iloc[:,:3]),datingTest.iloc[:,3]],axis=1)
#datingT
#valueset=datingTest.iloc[:,:3]
#mindef=valueset.min()



"""
切分训练集和测试集
"""
def randSplit(dataset,rate=0.9):
    n=dataset.shape[0]
    m=int(n*rate)
    train=dataset.iloc[:m,:]
    test=dataset.iloc[m:,:]
    test.index=range(test.shape[0])
    return train,test
def datingClass(train,test,k):
    n=train.shape[1]-1
    m=test.shape[0]
    result=[]
    for i in range(m):
        #计算数据和样本集的距离
        distance=((((train.iloc[:,:n]-test.iloc[:,:n])**2).sum(1))**0.5)
        labeldist=pd.DataFrame({'dist':distance,'labels':train.iloc[:,n]})
        #排序并取前k个
        kneardist= labeldist.sort_values(by='dist')[:k]
        re=kneardist.loc[:,'labels'].value_counts()
        result.append(re.index[0])

    result=pd.Series(result)
    test['predict'] =result
    #预测准确率
    accuracy=(test.iloc[:,-1]==test.iloc[:,-2]).mean()
    print(f'模型预测准确率为{accuracy}')
    return test

train,test= randSplit(datingTest,0.9)
datingClass(train,test,5)
range(10)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.190185546875, 'fraction_numerical': 0.026611328125, 'mean_word_length': 6.3953068592057765, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '320247', 'license': 'Apache-2.0', 'n_tokens_mistral': 2005, 'n_tokens_neox': 2113, 'n_words': 159, 'path': '_posts/machinelearning/k-mean.ipynb', 'repo_name': 'hexiaoliangRick/blog_old', 'size': '4096'}