day04-样本均衡-置信概率-网格搜索-事件预测-K均值、均值漂移、凝聚层次聚类--
十一、支持向量机
1.原理
1)寻求最优的分类边界,
即被支持向量所夹持的分类带宽度达到最大值,
取其中心线作为分类边界。
最优边界要求:
正确:对大部分样本可以正确地划分类别
泛化:最大化支持向量间接
公平:与支持向量等距
简单:线性、直线或平面,分割超平面。
1)安全性:分类带最宽
2)公平性:分类带中心线
3)简单性:线性边界,分割超平面
4)对于在原始维度空间中无法线性分割的样本,通过特定的核函数
增加特征,即升高维度,在高维度空间寻求分割超平面。
2)基于核函数的升维变换
通过名为核函数的特征变换,增加新的特征,使得低维度空间
中的线性不可分问题变为高纬度空间中的线性可分问题。
2.接口
import sklearn.svm as svm
分类器模型=svm.SVC(kernel=核函数类型, ...)
回归器模型=svm.SVR(kernel=核函数类型, ...)
3.不同核函数的分类效果
1)线性核函数:linear
svm.SVC(kernel='linear'),不通过核函数进行维度提升,
尽量在原始维度空间中寻求线性分类边界。
代码示例:svm_line.py
import numpy as np
import matplotlib.pyplot as mp
import sklearn.model_selection as ms
import sklearn.metrics as sm
import sklearn.svm as svm
x,y = [],[]
with open('../../day01/data/multiple1.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x ,y = np.array(x),np.array(y,dtype=int)
#划分训练集合测试集
train_x,test_x,train_y,test_y = \
ms.train_test_split(x,y,test_size=0.25,random_state=7)
#基于线性核函数的支持向量机分类器
model = svm.SVC(kernel='linear')
model.fit(train_x,train_y)#用训练集进行训练
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()] #列合并
flat_y = np.zeros(len(flat_x), dtype=int)#进行自动分类
flat_y = model.predict(flat_x) #注意,在这里才开始训练
grid_y = flat_y.reshape(grid_x[0].shape)
pred_test_y = model.predict(test_x)#用测试集测试并产生预测值
#获得分类报告
cr = sm.classification_report(test_y,pred_test_y)
print(cr)
mp.figure('SVM Linear Classification',facecolor='lightgray')
mp.title('SVM Linear Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1],
c=test_y, cmap='brg', s=80)
mp.show()
2)多项式核函数:poly
svm.SVC(kernel='poly',degree=最高次幂)
通过多项式函数增加原始样本特征的高次方幂
代码示例:svm_poly.py
import numpy as np
import matplotlib.pyplot as mp
import sklearn.model_selection as ms
import sklearn.metrics as sm
import sklearn.svm as svm
x,y = [],[]
with open('../../day01/data/multiple2.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x ,y = np.array(x),np.array(y,dtype=int)
#划分训练集合测试集
train_x,test_x,train_y,test_y = \
ms.train_test_split(x,y,test_size=0.25,random_state=7)
#基于3次多项式核函数的支持向量机分类器
model = svm.SVC(kernel='poly',degree=3)
model.fit(train_x,train_y)#用训练集进行训练
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()] #列合并
flat_y = np.zeros(len(flat_x), dtype=int)#进行自动分类
flat_y = model.predict(flat_x) #注意,在这里才开始训练
grid_y = flat_y.reshape(grid_x[0].shape)
pred_test_y = model.predict(test_x)#用测试集测试并产生预测值
#获得分类报告
cr = sm.classification_report(test_y,pred_test_y)
print(cr)
mp.figure('SVM Poly Classification',facecolor='lightgray')
mp.title('SVM Poly Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1],
c=test_y, cmap='brg', s=80)
mp.show()
3)径向基核函数
svm.SVC(kernel='rbf',C=正则强度,gamma=正态分布标准差)
超参数:正则强度一般为400,正态分布标准差一般为0.01
代码示例:svm_rbf.py
import numpy as np
import matplotlib.pyplot as mp
import sklearn.model_selection as ms
import sklearn.metrics as sm
import sklearn.svm as svm
x,y = [],[]
with open('../../day01/data/multiple2.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x ,y = np.array(x),np.array(y,dtype=int)
#划分训练集合测试集
train_x,test_x,train_y,test_y = \
ms.train_test_split(x,y,test_size=0.25,random_state=7)
#基于径向基核函数的支持向量机分类器
model = svm.SVC(kernel='rbf',C=600,gamma=0.01)
model.fit(train_x,train_y)#用训练集进行训练
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()] #列合并
flat_y = np.zeros(len(flat_x), dtype=int)#进行自动分类
flat_y = model.predict(flat_x) #注意,在这里才开始训练
grid_y = flat_y.reshape(grid_x[0].shape)
pred_test_y = model.predict(test_x)#用测试集测试并产生预测值
#获得分类报告
cr = sm.classification_report(test_y,pred_test_y)
print(cr)
mp.figure('SVM rbf Classification',facecolor='lightgray')
mp.title('SVM rbf Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1],
c=test_y, cmap='brg', s=80)
mp.show()
4.样本均衡
通过类别权重的均衡化,使较小比例的样本权重较高,
比例较大的样本权重较低,以此平均化不同类别样本对分类
模型的贡献,提高模型性能。
svm.SVC(..., class_weight='balanced')
通过为不同类别的样本设置不同的权重,
平衡比例相差较大的类别为分类器所带来的不同影响。
代码示例:svm_bal.py
import numpy as np
import matplotlib.pyplot as mp
import sklearn.model_selection as ms
import sklearn.metrics as sm
import sklearn.svm as svm
x,y = [],[]
with open('../../day01/data/imbalance.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x ,y = np.array(x),np.array(y,dtype=int)
#划分训练集合测试集
train_x,test_x,train_y,test_y = \
ms.train_test_split(x,y,test_size=0.25,random_state=7)
#基于径向基核函数的支持向量机分类器
model = svm.SVC(kernel='rbf',C=400,gamma=0.01,
class_weight='balanced')#进行样本权重均衡
model.fit(train_x,train_y)#用训练集进行训练
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()] #列合并
flat_y = np.zeros(len(flat_x), dtype=int)#进行自动分类
flat_y = model.predict(flat_x) #注意,在这里才开始训练
grid_y = flat_y.reshape(grid_x[0].shape)
pred_test_y = model.predict(test_x)#用测试集测试并产生预测值
#获得分类报告
cr = sm.classification_report(test_y,pred_test_y)
print(cr)
mp.figure('SVM rbf Classification',facecolor='lightgray')
mp.title('SVM rbf Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1],
c=test_y, cmap='brg', s=80)
mp.show()
5.置信概率
根据样本与分类边界的距离远近,对其预测类别的可信程度进行
量化,离边界越近的样本,置信概率越高,反之,置信概率越低。
根据样本与分类边界的距离表示该样本被分类器归属每个类别的概率。
model = svm.SVC(..., probability=True, ...)
model.predict_proba(输入集)->概率矩阵
概率矩阵中的一行对应输入集中的要给样本,一列表示一个的类别,
而其中的值表示该样本被归属为特定类别的概率。
代码示例:svm_prob.py
import numpy as np
import matplotlib.pyplot as mp
import sklearn.model_selection as ms
import sklearn.metrics as sm
import sklearn.svm as svm
x,y = [],[]
with open('../../day01/data/multiple2.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x ,y = np.array(x),np.array(y,dtype=int)
#划分训练集合测试集
train_x,test_x,train_y,test_y = \
ms.train_test_split(x,y,test_size=0.25,random_state=7)
#基于径向基核函数的支持向量机分类器
model = svm.SVC(kernel='rbf',C=600,gamma=0.01,probability=True)#计算置信概率
model.fit(train_x,train_y)#用训练集进行训练
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()] #列合并
flat_y = np.zeros(len(flat_x), dtype=int)#进行自动分类
flat_y = model.predict(flat_x) #注意,在这里才开始训练
grid_y = flat_y.reshape(grid_x[0].shape)
pred_test_y = model.predict(test_x)#用测试集测试并产生预测值
#获得分类报告
cr = sm.classification_report(test_y,pred_test_y)
# print(cr)
#用其他数据测试置信概率
prob_x=np.array([[2,1.5],[8,9],[4.8,5.2],[4,4],[2.5,7],[7.6,2],[5.4,5.9]])
# print(prob_x)
pred_prob_y = model.predict(prob_x)
# print(pred_prob_y)
probs = model.predict_proba(prob_x) #获得置信概率矩阵
#print(probs)
mp.figure('SVM proba',facecolor='lightgray')
mp.title('SVM proba', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1],c=test_y, cmap='brg', s=80)
mp.scatter(prob_x[:,0], prob_x[:, 1],c=pred_prob_y, cmap='cool', s=70,marker='D')
for i in range(len(probs)):#置信概率标识图
mp.annotate('{}% {}%'.format(round(probs[i,0] * 100,2),round(probs[i,1] * 100,2)),
xy=(prob_x[i,0],prob_x[i,1]),xytext=(12,-12),textcoords='offset points',
horizontalalignment='left',verticalalignment='top',fontsize=9,
bbox={'boxstyle':'round,pad=0.6','fc':'orangered','alpha':0.8})
mp.show()
6.网格搜索
针对超参数组合列表中的每一个超参数组合,实例化给定的模型,
做CV次交叉验证,将其中平均f1得分最高的超参数组合作为最佳
选择,实例化模型
model = ms.GridSearchCV(
基本模型, 超参数组合列表, cv=交叉验证次数)
超参数组合列表:
[{超参数名: [取值列表], 超参数名: [取值列表]}, {...}, ...]
model.fit(输入集, 输出集)
model -> 用最优超参数组合设置的模型
代码示例:svm_gs.py
import numpy as np
import matplotlib.pyplot as mp
import sklearn.model_selection as ms
import sklearn.metrics as sm
import sklearn.svm as svm
import warnings
warnings.filterwarnings("ignore", category=FutureWarning, module="sklearn", lineno=196)
x,y = [],[]
with open('../../day01/data/multiple2.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x ,y = np.array(x),np.array(y,dtype=int)
#划分训练集合测试集
train_x,test_x,train_y,test_y = \
ms.train_test_split(x,y,test_size=0.25,random_state=7)
#超参数组合列表
params = [
{'kernel':['linear'],'C':[1,10,100,1000]},
{'kernel':['poly'],'C':[1],'degree':[2,3,4]},
{'kernel':['rbf'],'C':[1,10,100,1000],'gamma':[1,0.1,0.01,0.001]}]
model = ms.GridSearchCV(svm.SVC(probability=True),params,cv=5)#进行网格优化搜索
model.fit(train_x,train_y)#用训练集进行训练
for param,score in zip(model.cv_results_['params'],#获得超参数组合值
model.cv_results_['mean_test_score']):#获得超参数组合f1分值
print(param,score)
print(model.best_params_)#输出最优超参数组合
print(model.best_score_)#输出最好的模型
print(model.best_estimator_)#输出做好的模型
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()] #列合并
flat_y = np.zeros(len(flat_x), dtype=int)#进行自动分类
flat_y = model.predict(flat_x) #注意,在这里才开始训练
grid_y = flat_y.reshape(grid_x[0].shape)
pred_test_y = model.predict(test_x)#用测试集测试并产生预测值
#获得分类报告
cr = sm.classification_report(test_y,pred_test_y)
# print(cr)
#用其他数据测试置信概率
prob_x=np.array([[2,1.5],[8,9],[4.8,5.2],[4,4],[2.5,7],[7.6,2],[5.4,5.9]])
# print(prob_x)
pred_prob_y = model.predict(prob_x)
# print(pred_prob_y)
probs = model.predict_proba(prob_x) #获得置信概率矩阵
#print(probs)
mp.figure('Grid Search',facecolor='lightgray')
mp.title('Grid Search', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1],c=test_y, cmap='brg', s=80)
mp.scatter(prob_x[:,0], prob_x[:, 1],c=pred_prob_y, cmap='cool', s=70,marker='D')
for i in range(len(probs)):#置信概率标识图
mp.annotate('{}% {}%'.format(round(probs[i,0] * 100,2),round(probs[i,1] * 100,2)),
xy=(prob_x[i,0],prob_x[i,1]),xytext=(12,-12),textcoords='offset points',
horizontalalignment='left',verticalalignment='top',fontsize=9,
bbox={'boxstyle':'round,pad=0.6','fc':'orangered','alpha':0.8})
mp.show()
代码示例:svm_evt.py 事件预测
import numpy as np
import sklearn.preprocessing as sp
import sklearn.model_selection as ms
import sklearn.svm as svm
class DigitEncoder():
def fit_transform(self,y):
return y.astype(int)
def transform(self,y):
return y.astype(int)
def inverse_transform(self,y):
return y.astype(str)
data=[]
#二元分类
with open('../../day01/data/event.txt','r') as f:
for line in f.readlines():
data.append(line[:-1].split(','))
#多元分类
with open('../../day01/data/events.txt','r') as f:
for line in f.readlines():
data.append(line[:-1].split(','))
#np.delete(数组,下标,行列标志) 行列标志:0,行,1列
data = np.delete(np.array(data).T,1,0)
encoders,x=[],[]
for row in range(len(data)):
if data[row][0].isdigit():
encoder=DigitEncoder()
else:
encoder=sp.LabelEncoder()
if row < len(data) - 1:
x.append(encoder.fit_transform(data[row]))
else:
y=encoder.fit_transform(data[row])
encoders.append(encoder)
x = np.array(x).T
print(set(y))
train_x,test_x,train_y,test_y = ms.train_test_split(x,y,test_size=0.25,
random_state=5)
model = svm.SVC(kernel='rbf',class_weight='balanced')
print(ms.cross_val_score(model,train_x,train_y,cv=3,scoring='accuracy').mean())#验证模型性能
model.fit(train_x,train_y)
pred_test_y = model.predict(test_x)
print((pred_test_y == test_y).sum()/(pred_test_y.size))#获得实际模型分数 ,与验证模型性能分数对比
#假设采集了新样本,开始预测事件
data = [['Tuesday','12:30:00','21','23']]
data = np.array(data).T
x=[]
for row in range(len(data)):
encoder = encoders[row]
x.append(encoder.transform(data[row]))
x=np.array(x).T
pred_y = model.predict(x)
print(encoders[-1].inverse_transform(pred_y))#预测输出
7.事件预测:支持向量机回归器
svm.SVR(kernel='rbf',C=10,epsilon=0.2)
epsilon量化宽度
代码实例:svm_trf.py交通预测
import numpy as np
import sklearn.preprocessing as sp
import sklearn.model_selection as ms
import sklearn.svm as svm
import sklearn.metrics as sm
class DigitEncoder():
def fit_transform(self,y):
return y.astype(int)
def transform(self,y):
return y.astype(int)
def inverse_transform(self,y):
return y.astype(str)
data=[]
with open('../../day01/data/traffic.txt','r') as f:
for line in f.readlines():
data.append(line[:-1].split(','))
data = np.array(data).T
encoders,x=[],[]
for row in range(len(data)):
if data[row][0].isdigit():
encoder=DigitEncoder()
else:
encoder=sp.LabelEncoder()
if row < len(data) - 1:
x.append(encoder.fit_transform(data[row]))
else:
y=encoder.fit_transform(data[row])
encoders.append(encoder)
x = np.array(x).T
train_x,test_x,train_y,test_y = ms.train_test_split(x,y,test_size=0.25,
random_state=5)
#支持向量机回归器
model = svm.SVR(kernel='rbf',C=10,epsilon=0.2)
model.fit(train_x,train_y)
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y,pred_test_y))#进行评分
data = [['Tuesday','13:35','San Francisco','yes']]
data = np.array(data).T
x=[]
for row in range(len(data)):
encoder = encoders[row]
x.append(encoder.transform(data[row]))
x=np.array(x).T
pred_y = model.predict(x)
print(int(pred_y))#预测交通流量输出
十二、聚类
1.概念
分类 vs 聚类
class cluster
有监督 无监督
样本相似性:欧氏距离
在输出未知的前提下,仅根据已知的输入寻找样本之间的内在联系,
据此将输入样本划分为不同的族群。
1.量化相似度
1)欧氏距离
(欧几里得:《几何原理》、笛卡尔:《解析几何》)
有两个坐标点在数轴上:P(x1),Q(x2)
距离为:|x1-x2|
二维坐标中的两个点:P(x1,y1),Q(x2,y2)
两点距离为:|PQ|=sqrt((x1-x2)^2+(y1-y2)^2)
三维坐标中的两个点:P(x1,y1,z1),Q(x2,y2,z2)
两点距离为:|PQ|=sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2)
n维坐标中的两个点:P(x1,y1,z1,...,n1), Q(x2,y2,z2,...,n2)
两点距离为:
|PQ|=sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2+..+(n1-n2)^2)
2)量化相似度概念:
两个N维样本之间的欧氏距离越小,就越相似,反之相似度越小。
2.K均值聚类算法(km算法)
1)概念:
每个聚类都存在聚类中心,聚类中的样本围绕中心均匀分布。
每个聚类的几何中心(平均值)应该与该聚类的聚类中心重合。
第一步首先聚类数K是已知的,然后随机选择K个样本作为初始聚类中心,
计算每个样本与各个聚类中心的欧氏距离,选择距离最近的聚类中心
作为样本的聚类归属,完成了一次划分。
第二步接着,计算每个聚类中所有样本的几何中心(各个特征的平均值),
如果所得到的几何中心与产生此聚类的聚类中心重合或足够接近,
则完成聚类,否则以几何中心作为新的聚类中心,重复之前的聚类划分,
再次计算几何中心。
多次迭代以上过程,直到几何中心与聚类中心足够接近为止。
2)注意点:
1)聚类数k必须事先已知。也可借助评估指标获得优选的聚类数
2)聚类中心的初始选择会影响到最终聚类划分的结果
初始聚类中心尽量选择距离较远的样本
3)接口:
import sklearn.cluster as sc
sc.k_means(n_clusters=分类数量)
4)代码示例:km.py
import numpy as np
import sklearn.cluster as sc
import matplotlib.pyplot as mp
x= []
with open('../../day01/data/multiple3.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data)
x = np.array(x)
#K均值聚类器
model = sc.KMeans(n_clusters=4)
model.fit(x)
centers = model.cluster_centers_ #获得聚类中心点
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()] #列合并
flat_y = np.zeros(len(flat_x), dtype=int)#进行自动分类
flat_y = model.predict(flat_x) #注意,在这里才开始训练
grid_y = flat_y.reshape(grid_x[0].shape)
pred_y = model.predict(x)#在这里测试并产生预测值
mp.figure('K-Means Cluster',facecolor='lightgray')
mp.title('K-Means Cluster', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=pred_y, cmap='brg', s=80)
mp.scatter(centers[:, 0], centers[:, 1], marker='+',
c='gold', s=1080,linewidths=1)#聚类中心点
mp.tight_layout()
mp.show()
5)代码示例:quant.py 图像预处理之颜色量化
import scipy.misc as sm
import matplotlib.pyplot as mp
import sklearn.cluster as sc
#通过K均值聚类量化图像中的颜色
def quant(image,n_clusters):
x = image.reshape(-1,1)
model = sc.KMeans(n_clusters = n_clusters)
model.fit(x)
#y = model.predict(x) #这样获得y的速度比较慢
y = model.labels_ #这样获得y的速度比较快
centers = model.cluster_centers_.squeeze() #获得聚类中心,squeeze删除二维数组中多余维度,变成一维
return centers[y].reshape(image.shape)
original = sm.imread('../../day01/data/lily.jpg',True)#读取图片的源格式
quant4 = quant(original,4) #四色
quant3 = quant(original,3) #三色
quant2 = quant(original,2) #两色
mp.figure('Image',facecolor='lightgray')
mp.subplot(221)
mp.title('Original',fontsize=16)
mp.axis('off')
mp.imshow(original,cmap='gray')
mp.subplot(222)
mp.title('quant4',fontsize=16)
mp.axis('off')
mp.imshow(quant4,cmap='gray')
mp.subplot(223)
mp.title('quant3',fontsize=16)
mp.axis('off')
mp.imshow(quant3,cmap='gray')
mp.subplot(224)
mp.title('quant2',fontsize=16)
mp.axis('off')
mp.imshow(quant2,cmap='gray')
mp.tight_layout()
mp.show()
3.均值漂移聚类
1)概念:
首先假定样本空间中的每个聚类均服从某种已知的概率分布规则,
然后用不同的概率密度函数拟合样本中的统计直方图,不断移动
密度函数的中心(即均值)的位置,直到获得最佳拟合效果为止。
这些概率密度函数的峰值就是聚类的中心,再根据每个样本到各
个中心的距离,选择最近的聚类中心所属的类别作为该样本类别。
2)优点:
1)无需事先给定聚类数,算法会自动识别统计直方图的中心数量。
2)聚类中心不依据于最初假定,聚类划分的结果相对稳定
2)样本服从某种概率规律,否则算法的准确性会降低。
3)接口:
import sklearn.cluster as sc
bw=sc.estimate_bandwidth(x,n_samples=len(x),quantile=0.1)
estimate_bandwidth量化带宽,决定每次调整概率密度函数的步进量
quantile直方条宽度
model = sc.MeanShift(bandwidth=bw,bin_seeding=True)#均值漂移聚类器
bin_seeding通常为True ,默认为False
4)代码示例:shift.py
import numpy as np
import sklearn.cluster as sc
import matplotlib.pyplot as mp
x= []
with open('../../day01/data/multiple3.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data)
x = np.array(x)
#estimate_bandwidth量化带宽,决定每次调整概率密度函数的步进量
#quantile直方条宽度
bw = sc.estimate_bandwidth(x,n_samples=len(x),quantile=0.1)
#均值漂移聚类器
model = sc.MeanShift(bandwidth=bw,bin_seeding=True)
model.fit(x)
centers = model.cluster_centers_ #获得聚类中心点
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()] #列合并
flat_y = np.zeros(len(flat_x), dtype=int)#进行自动分类
flat_y = model.predict(flat_x) #注意,在这里才开始训练
grid_y = flat_y.reshape(grid_x[0].shape)
pred_y = model.predict(x)#在这里测试并产生预测值
mp.figure('Means Shift Cluster',facecolor='lightgray')
mp.title('Means Shift Cluster', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=pred_y, cmap='brg', s=80)
mp.scatter(centers[:, 0], centers[:, 1], marker='+',
c='gold', s=1080,linewidths=1)#聚类中心点
mp.tight_layout()
mp.show()
4.凝聚层次聚类
1)概念:
首先假定每个样本都是一个独立的聚类,统计总聚类数,如果大
于所要求的聚类数,就从每个样本出发,连接离它欧氏距离最近
的样本,在扩大聚类的规模的同时减少聚类数,重复以上过程,
直到总聚类数满足要求为止。
2)特点:
1)没有所谓聚类中心,适用于中心特性不明显的样本
2)无需事先给定聚类中心
3)在选择被凝聚样本的过程中,还可以分别按照距离优先和
连续性优先两种方式选连接的样本。
3)接口:
import sklearn.cluster as sc
model = sc.AgglomerativeClustering(n_clusters=4,linkage='average')
n_clusters= 要求的聚类数量
linkage='average',连接条件,平均值
pred_y = model.fit_predict(x)
注意:model.fit_predict训练和测试都同时完成,
不需要再做训练模型和测试模型,直接使用
3)代码:
示例一:agglo.py
import numpy as np
import sklearn.cluster as sc
import matplotlib.pyplot as mp
x= []
with open('../../day01/data/multiple3.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data)
x = np.array(x)
model = sc.AgglomerativeClustering(n_clusters=4)#凝聚层次聚类器
pred_y = model.fit_predict(x)
mp.figure('AgglomerativeClustering',facecolor='lightgray')
mp.title('AgglomerativeClustering', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.scatter(x[:, 0], x[:, 1], c=pred_y, cmap='brg', s=80)
mp.tight_layout()
mp.show()
示例二:spiral.py
import numpy as np
import sklearn.cluster as sc
import matplotlib.pyplot as mp
import sklearn.neighbors as nb #最近邻
n_samples = 500
t = 2.5 * np.pi * (1+2*np.random.rand(n_samples,1)) #产生500个随机数样本,阿基米德螺线
x = 0.05 * t * np.cos(t)
y = 0.05 * t * np.sin(t)
n = 0.05 * np.random.rand(n_samples,2) #添加噪声
x = np.hstack((x,y)) + n
#无连续性的凝聚层次聚类
model_nonc = sc.AgglomerativeClustering(linkage='average',n_clusters=3)
pred_y_nonc = model_nonc.fit_predict(x)
#近邻筛选器
conn = nb.kneighbors_graph(x,10,include_self=False)#include_self是否包括自己,True包括
#有连续性的凝聚层次聚类 connectivity 指定近邻筛选器
model_conn = sc.AgglomerativeClustering(linkage='average',n_clusters=3,connectivity=conn)
pred_y_conn = model_conn.fit_predict(x)
mp.figure('nonc',facecolor='lightgray')
mp.title('nonc', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.axis('equal') #设为等轴
mp.scatter(x[:,0], x[:,1], c=pred_y_nonc,cmap='brg', s=40,alpha=0.5)
mp.figure('connectivity',facecolor='lightgray')
mp.title('connectivity', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.axis('equal') #设为等轴
mp.scatter(x[:,0], x[:,1], c=pred_y_conn,cmap='brg', s=40,alpha=0.5)
mp.tight_layout()
mp.show()