fuli2020

2020-08-13   阅读量: 833

机器学习-KNN算法

扫码加入数据分析学习群

机器学习的方法是基于数据产生的“模型”的算法,也称“学习算法”,包括有监督学习、无监督学习、半监督学习、强化学习。

有监督学习:指对数据的若干特征与若干标签(类型)之间的关联性进行建模的过程,只要模型被确定,就可以应用到新的未知数据上,这类学习过程可以进一步分为【分类】任务和【回归】任务,在分类任务中,标签都是离散值;而在回归任务中,标签都是连续值。

无监督学习,指对不带任何标签的数据特征进行建模,通常被看成是一种“让数据自己介绍自己”,这类模型包括【聚类】任务和【降维】任务。降维算法可以将数据分为不同的组别,而降维算法追求用更简洁的方式表现数据。

半监督学习方法,介于有监督学习和无监督学习之间,通常可以在数据不完整时使用。

强化学习不同于监督学习,它将学习看作是试探评价过程,以“试错”的方式进行学习,并与环境进行交互已获得奖惩指导行为,以其作为评价。此时系统靠自身的状态和动作进行学习,从而改进行动方案以适应环境。

k-近邻算法,它的本质是通过距离判断两个样本是否相似,如果距离够近就认为他们足够相似属于同一类别。当然只对比一个样本是不够的,误会会很大,我们需要找到离其最近的k个样本,并将这些样本称之为【近邻】。对这k个近邻,查看他们都属于何种类别(这些类别我们称作【标签】),然后根据“少数服从多数,一点算一票”原则进行判断,数量最多的标签类别就是新样本的标签类别,其中涉及到的原理是“越相近越相似”,这也是KNN的基本假设


KNN算法模型:

图片.png

行为样本,列为特征,目标变量为标签

from sklearn.datasets import make_blobs

X,y=make_blobs(n_samples=50,

cluster_std=[0.3,0.3,0.3],

centers=[[0,0],[1,1],[-1,1]],

random_state=4

)

sim_data=pd.DataFrame(X,columns=['x','y'])

sim_data['label']=y


plt.scatter(sim_data['x'],sim_data['y'],c=y)

plt.scatter(0.5,0.5,c='red',maker='x')


p=[0.5,0.5]

X=sim_data.iloc[:,:-1]

y=sim_data.iloc[:,-1]

d=np.power(X-p,2).sum(axis=1)


df_dist=pd.DataFrame({'dist':d,'label':y}) #把计算出来的距离与标签拼接起来

k=5

final_result=df_dist.sort_values(by='dist').iloc[:k,-1]

final_result.mode().values[0] #开始投票


#封装成一个函数

def knn_classify(p,datasets,k):

X=datasets.iloc[:,:-1]

y=datasets.iloc[:,-1]

d=np.power(X-p,2).sum(axis=1)

df_dist=pd.DataFrame({'dist':d,'label':y})

final_result=df_dist.sort_values(by='dist').iloc[:k,-1]

return final_result.mode().values[0]


#sklearn 实现

X,y=make_blobs(n_samples=50,

cluster_std=[0.3,0.3,0.3],

centers=[[0,0],[1,1],[-1,1]],

random_state=4)


from sklearn.neighbors import KNeighborsClassifier

clf=KNeighborsClassifier(n_neighbors=10)

print(clf.fit(X,y)) #学习X和y之间的关系,学习好之后,重要的信息就全部存到clf,这些信息描述的是X和y之间的规律

predict=clf.predict(X) #predict 参数必须是二维数组

clf.score(X,y)

dir(clf) #使用dir的方法来查看类的接口或者属性


sklearn基本建模流程

图片.png


#breast_cancer 数据集

from sklearn.neighbors import KNeighborsClassifier

from sklearn.datasets import load_breast_cancer

from sklearn.model_selection import train_test_split


data=load_breast_cancer()

x=data.data

y=data.target


x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3) #划分训练集和测试集

#建立模型&评估模型

clf=KNeighborsClassifier(n_neighbors=4)

clf=clf.fit(x_train,y_train)

score=clf.score(x_test,y_test)


#绘制学习曲线

score=[]

krange=range(1,20)

for i in krange:

clf=KNeighborsClassifier(n_neighbors=i)

clf=clf.fit(x_train,y_train)

score.append(clf.score(x_test,y_test))

plt.plot(krange,score)

plt.show()


#通过交叉验证找到最好的k值

from sklearn.model_selection import cross_val_score as CVS

cvresult=CVS(clf,x,y,cv=5)

cvresult


#均值:查看模型的平均效果

cvresult.mean()


#方差:查看模型是否稳定

cvresult.var()


#绘制带交叉验证的学习曲线

score=[]

var_=[]

krange=range[1,20]


for i in krange:

clf=KNeighborsClassifier(n_neighbors=i)

cvresult=CVS(clf,x,y,cv=5)

score.append(cvresult.mean())

var_.append(cvresult.var())


plt.plot(krange,score,color='k')

plt.plot(krange,np.array(score)+np.array(var_)*2,c='red',linestyle='--')

plt.plot(krange,np.array(score)-np.array(var_)*2,c='red',linestyle='--')


bestindex=krange[score.index(max(score))]-1

print(bestindex)

print(score[bestindex])


#归一化

from sklearn.preprocessing import MinMaxScaler,StandardScaler

mms=mms.fit(x_train)

x_train_=mms.transform(x_train)

x_test_=mms.transform(x_test)

clf=KNeighborsClassifier(n_neighbors=4)

clf.fit(x_train_,y_train)

clf.score(x_train_,y_train),clf.score(x_test_,y_test)


#加上权重

#实现归一化

clf=KNeighborsClassifier(n_neighbors=9,weights='distance')

clf.fit(x_train_,y_train)

clf.score(x_train_,y_train),clf.score(x_test,y_test)


KNN模型的缺点:
1.计算效率低,耗费计算资源大

2.抗噪性较弱,对噪声数据(异常值)较为敏感

3.模型不稳定,可重复性较弱

4.需要进行归一化处理。除非采用适当的邻近性度量和数据预处理,否则最近邻分类器可能做出错误的预测。


图片.png






47.6465 3 3 关注作者 收藏

评论(0)


暂无数据

推荐课程