学习向量量化(LVQ)

学习向量量化(LVQ)

是一种无模型的数据点聚类方法。可以用来执行分类任务。

(他很难搞清楚反应变量y和预测器x之间存在什么样的联系。因而在许多现实的场景中,它是作为一种黑箱方法来加以应用的。)

步骤:

  • 为数据集里的每个类别选择k个初始的原始向量,如果是一个两分类问题,并且每个分类中有两个原型向量,那我们就需要设置4个初始的原型向量,它们是从输入的数据集中随机选择的。
  • 接着进行循环,直到ε值变成0或者预先设定的阈值。我们得确定一个ε值并在每次循环中都使之减小。
  • 每次循环中,我们都要采样一个输入点,采用欧式距离找到离它最近的原型向量。然后按下面的操作更新最近邻点的原型向量。
  • 如果它的原型向量的类别标签和输入数据点的相同,则在原型向量上增加原型向量和数据点的差异。
  • 如果类别标签不同,则在原型向

    源码

from sklearn.datasets import load_iris

import numpy as np
from sklearn.metrics import euclidean_distances
data=load_iris()
x=data['data']
y=data['target']
#对变量进行缩放
from sklearn.preprocessing import MinMaxScaler
minmax=MinMaxScaler()
x=minmax.fit_transform(x)

#操作方法
#1.声明LVQ的参数
R=2
n_classes=2
epsilon=0.9
epsion_dec_factor=0.001
#2.定义一个类来保存原型向量
class prototype(object):
       def _init_(self,class_id,p_vector,epsilon):
              self.class_id=class_id
              self.p_vector=p_vector
              self.epsilon=epsilon

       def updata(self,u_vector,increment=True):
              if increment:
                     #将原型向量向输入向量靠近
                     self.p_vector=self.p_vector+self.epsilon*(u_vector-self.p_vector)
              else:
                     #使原型向量远离输入向量
                     self.p_vector=self.p_vector-self.epsilon*(u_vector-self.p_vector)
#3.找到离给定向量最近的原型向量
def find_closest(in_vector,proto_vectors):
       closest=None
       closest_distance=9999
       for p_v in proto_vectors:
              distance=euclidean_distances(in_vector,p_v.p_vector)
              if distance                      closest_distance =distance
                     closest=p_v
       return closest
#4.找到最近的原型向量的类别ID
def find_class_id(test_vector,p_vectors):
       return find_closest(test_vector,p_vectors).class_id
#5.选择初始化的k×原型向量类别数
p_vectors=[]
for i in range(n_classes):
       #选择一个类
       y_subset=np.where(y==i)
       #为选中的类选择元组
       x_subset=x[y_subset]
       #获得R个随机下标,介于0~50
       samples=np.random.randint(0,len(x_subset),R)
       #选择p_vectors
       for sample in samples:
              s=x_subset[samples]
              p=prototype(i,s,epsilon)
              p_vectors.append(p)
print ("class_id\t Initial protype vecotr\n")
for p_v in p_vectors:
       print(p_v.class_id,'\t',p_v.vector)

#6.利用已有的数据点,执行循环调整原型向量,对新的点进行分类/聚类
while epsilon>=0.01:
       #随机采样一个训练实例
       rnd_i=np.random.randint(0,149)
       rnd_s=x[rnd_i]
       target_y=y[rad_i]
       #为下一次循环减小ε
       epsilon=epsilon-epsilon_dec_factor
       #查找与给定最相近的原型向量x
       closest_pvector=find_closest(rnd_s,p_vectors)
       #更新最相近的原型向量
       if target_y==closest_pvector.class_id:
              closest_pvector.update(rnd_s)
       else:
              closest_pvector.update(rnd_s,False)
       closest_pvector.epsilon=epsilon
print("class_id \t Final Prototype Vector\n")
for p_vector in p_vectors:
       print(p_vector.class_id,'\t',p_vector.p_vector)
#7.下面是测试代码来检查方法是否正确
predicted_y=[find_class_id(instance,p_vectors) for instance in x]
from sklear.metrics import classification_report
print(classification_report(y,predicted_y,target_names=['Iris-Setosa','Iris-Versicolour','Iris-Virginica']))
 

量上减去原型向量和数据点的差异。

你可能感兴趣的:(学习向量量化,数据挖掘,机器学习,python)