k-means算法以k为参数,把n个对象分成k个簇,使簇内具有较高的相似度,而簇间的相似度较低。
其处理过程如下: .
#导入KMeans库
import numpy as np
from sklearn.cluster import KMeans
#处理数据函数
def loadData(filePath):
fr = open(filePath,'r+')
#注意.readline()与.readlines()是两种不同的方法,不能写错。前者只能读取一行
lines = fr.readlines()
#将数据分为城市名和其他
retData = []
retCityName = []
for line in lines:
#将每一行的数据以逗号隔开(csv文件可以直接使用此方法)
items = line.strip().split(",")
retCityName.append(items[0])
retData.append([float(items[i]) for i in range(1,len(items))])
return retData,retCityName
if __name__ == '__main__':
#上传数据
data,cityName = loadData('city.txt')
#设置簇的数值(此处设值为5,可随意更改,但是必须与CityCluster的维数对应)
km = KMeans(n_clusters=5)
#调用fit_predict方法计算,同时为簇分配序号
label = km.fit_predict(data)
#numpy方法计算中心数值点的平均值,axis=1表示按行求和
expenses = np.sum(km.cluster_centers_,axis=1)
#print(label)
#print(expenses)
CityCluster = [[],[],[],[],[]]
for i in range(len(cityName)):
CityCluster[label[i]].append(cityName[i])
for i in range(len(CityCluster)):
print("Expenses:%.2f" % expenses[i])
print(CityCluster[i])
DBSCAN算法是一种基于密度的聚类算法:
DBSCAN算法将数据点分为三类:
现有大学校园网的日志数据, 290条大学生的校园网使用情况数据,数据包括用户ID ,设备的MAC地址, IP地址,开始上网时间,停止上网时间,上网时长,校园网套餐等。利用已有数据,分析学生上网的模式。
#调用相关库
import numpy as np
import sklearn.cluster as skc
from sklearn import metrics
import matplotlib.pyplot as plt
#定义一个字典,命名为mac2id
mac2id=dict()
onlinetimes=[]
f=open('TestData.txt',encoding='utf-8')
#读入数据代码
for line in f:
#读取mac地址,上网时长,开始上网时间
mac=line.split(',')[2]
onlinetime=int(line.split(',')[6])
starttime=int(line.split(',')[4].split(' ')[1].split(':')[0])
#字典中mac地址对应onlinetime,starttime
if mac not in mac2id:
#根据列表onlinetimes的长度给字典配value值,实质是从零开始编号
mac2id[mac]=len(onlinetimes)
onlinetimes.append((starttime,onlinetime))
else:
onlinetimes[mac2id[mac]]=[(starttime,onlinetime)]
#重组数组,从1*n变成n*1矩阵
real_X=np.array(onlinetimes).reshape((-1,2))
X=real_X[:,0:1]
#DBSCAN参数:eps为半径,min_samples最小样本数,metric计算距离方式( 默认为欧式计算法)
db=skc.DBSCAN(eps=0.01,min_samples=20).fit(X)
#调用DBSCAN方法进行训练,labels为每个数据的簇标签
labels = db.labels_
print('Labels:')
print(labels)
#标签为-1的值表示噪音,计算噪声率
raito=len(labels[labels[:] == -1]) / len(labels)
print('Noise raito:',format(raito, '.2%'))
#计算簇的个数并打印
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
print('Estimated number of clusters: %d' % n_clusters_)
#评价聚类效果
print("Silhouette Coefficient: %0.3f"% metrics.silhouette_score(X, labels))
for i in range(n_clusters_):
print('Cluster ',i,':')
#flatten()在numpy中用于返回一个一维数组
print(list(X[labels == i].flatten()))
#绘制直方图
plt.hist(X,24)
运行结果:
Labels:
[ 0 -1 0 1 -1 1 0 1 2 -1 1 0 1 1 3 -1 -1 3 -1 1 1 -1 1 3
4 -1 1 1 2 0 2 2 -1 0 1 0 0 0 1 3 -1 0 1 1 0 0 2 -1
1 3 1 -1 3 -1 3 0 1 1 2 3 3 -1 -1 -1 0 1 2 1 -1 3 1 1
2 3 0 1 -1 2 0 0 3 2 0 1 -1 1 3 -1 4 2 -1 -1 0 -1 3 -1
0 2 1 -1 -1 2 1 1 2 0 2 1 1 3 3 0 1 2 0 1 0 -1 1 1
3 -1 2 1 3 1 1 1 2 -1 5 -1 1 3 -1 0 1 0 0 1 -1 -1 -1 2
2 0 1 1 3 0 0 0 1 4 4 -1 -1 -1 -1 4 -1 4 4 -1 4 -1 1 2
2 3 0 1 0 -1 1 0 0 1 -1 -1 0 2 1 0 2 -1 1 1 -1 -1 0 1
1 -1 3 1 1 -1 1 1 0 0 -1 0 -1 0 0 2 -1 1 -1 1 0 -1 2 1
3 1 1 -1 1 0 0 -1 0 0 3 2 0 0 5 -1 3 2 -1 5 4 4 4 -1
5 5 -1 4 0 4 4 4 5 4 4 5 5 0 5 4 -1 4 5 5 5 1 5 5
0 5 4 4 -1 4 4 5 4 0 5 4 -1 0 5 5 5 -1 4 5 5 5 5 4
4]
Noise raito: 22.15%
Estimated number of clusters: 6
Silhouette Coefficient: 0.710
Cluster 0 :
[22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22]
Cluster 1 :
[23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23]
Cluster 2 :
[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
Cluster 3 :
[21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21]
Cluster 4 :
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
Cluster 5 :
[7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]
主成分分析( Principal Component Analysis , PCA )是最常用的一种降维方法,通常用于高维数据集的探索与可视化,还可以用作数据压缩和预处理等。
PCA可以把具有相关性的高维变量合成为线性无关的低维变量,称为主成分。主成分能够尽可能保留原始数据的信息。
原理:矩阵的主成分就是其协方差矩阵对应的特征向量,按照对应的特征值大小进行排序,最大的特征值就是第一主成分 ,其次是第二主成分,以此类推。
输入:
样本集D= {x1, x2…xm};
低维空间维数d’.
过程:
输出:
投影矩阵w = (w1, w… wa).
数据实例:
目标:已知鸢尾花数据是4维的,共三类样本。使用PCA实现对鸢尾花数据进行降维,实现在二维平面上的可视化。
代码:
#调用相关库及数据集
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
#定义相关变量
data = load_iris()
y = data.target
X = data.data
#确定PCA维度为2
pca = PCA(n_components=2)
#计算降维数据
reduced_X = pca.fit_transform(X)
#预先设置可视化变量
red_x, red_y = [], []
blue_x, blue_y = [], []
green_x, green_y = [], []
for i in range(len(reduced_X)):
if y[i] == 0:
red_x.append(reduced_X[i][0])
red_y.append(reduced_X[i][1])
elif y[i] == 1:
blue_x.append(reduced_X[i][0])
blue_y.append(reduced_X[i][1])
else:
green_x.append(reduced_X[i][0])
green_y.append(reduced_X[i][1])
#绘制散点图
plt.scatter(red_x, red_y, c='r', marker='x')
plt.scatter(blue_x, blue_y, c='b', marker='D')
plt.scatter(green_x, green_y, c='g', marker='.')
plt.show()
非负矩阵分解( Non-negative Matrix Factorization , NMF )是在矩阵中所有元素均为非负数约束条件之下的矩阵分解方法。
基本思想:给定一个非负矩阵V , NMF能够找到一个非负矩阵W和一个非负矩阵H ,使得矩阵w和H的乘积近似等于矩阵V中的值。Vn*m = Wn*k * Hk*m
NMF能够广泛应用于图像分析、文本.挖掘和语音处理等领域。
矩阵分解优化目标:最小化w矩阵H矩阵的乘积和原始矩阵之间的差别,目标函数如下:
基于KL散度的优化目标,损失函数如下:
具体推导内容参考链接
数据实例:
目标: 已知Olivetti人脸数据共400个,每个数据是64*64大小。由于NMF分解得到的W矩阵相当于从原始矩阵中提取的特征,那么就可以使用NMF对400个人脸数据进行特征提取。
代码:
#导入相关库和数据集
from numpy.random import RandomState
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_olivetti_faces
from sklearn import decomposition
#设置基本参数加载数据
n_row, n_col = 2, 3
n_components = n_row * n_col
image_shape = (64, 64)
dataset = fetch_olivetti_faces(shuffle=True, random_state=RandomState(0))
faces = dataset.data
#设置图像的展示方法
def plot_gallery(title, images, n_col=n_col, n_row=n_row):
#创建图片,指定图片大小
plt.figure(figsize=(2. * n_col, 2.26 * n_row))
#设置标题大小
plt.suptitle(title, size=16)
#enumerate() 函数用于将一个可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标
for i, comp in enumerate(images):
#subplot()函数用于绘制子图
plt.subplot(n_row, n_col, i + 1)
vmax = max(comp.max(), -comp.min())
#数值归一化,并以灰度图形显示
plt.imshow(comp.reshape(image_shape), cmap=plt.cm.gray,interpolation='nearest', vmin=-vmax, vmax=vmax)
#去除子图的坐标轴标签
plt.xticks(())
plt.yticks(())
#调整子图位置
plt.subplots_adjust(0.01, 0.05, 0.99, 0.94, 0.04, 0.)
plot_gallery("First centered Olivetti faces", faces[:n_components])
#设置提取方法名称(对NMF和PCA进行比较)
estimators = [('Eigenfaces - PCA using randomized SVD',decomposition.PCA(n_components=6,whiten=True)),
('Non-negative components - NMF',decomposition.NMF(n_components=6, init='nndsvda', tol=5e-3))]
#图片可视化
for name, estimator in estimators:
print("Extracting the top %d %s..." % (n_components, name))
print(faces.shape)
estimator.fit(faces)
components_ = estimator.components_
plot_gallery(name, components_[:n_components])
plt.show()
图像分割:利用图像的灰度、颜色、纹理、形状等特征,把图像分成若干个互不重叠的区域,并使这些特征在同一区域内呈现相似性,在不同的区域之间存在明显的差异性。然后就可以将分割的图像中具有独特性质的区域提取出来用于不同的研究。
图像分割技术已在实际生活中得到广泛的应用。例如:在机车检验领域,可以应用到轮毂裂纹图像的分割,及时发现裂纹,保证行车安全;在生物医学工程方面,对肝脏CT图像进行分割,为临床治疗和病理学研究提供帮助。
图像分割常用方法:
数据实例:
目标:利用K-means聚类算法对图像像素点颜色进行聚类实现简单的图像分割输出:同一聚类中的点使用相同颜色标记,不同聚类颜色不同
#导入Kmeans包及PIL包
import numpy as np
import PIL.Image as image
from sklearn.cluster import KMeans
#加载图片进行预处理
def loadData(filePath):
#二进制形式打开文件
f = open(filePath,'rb')
data = []
#列表形式保存像素值
img = image.open(f)
#设置图片大小
m,n = img.size
#将所有RGB值归一化处理,范围在01之间
for i in range(m):
for j in range(n):
x,y,z = img.getpixel((i,j))
data.append([x/256.0,y/256.0,z/256.0])
f.close()
#矩阵形式返回data和图片大小
return np.mat(data),m,n
#调用Kmeans算法
imgData,row,col = loadData('bull.jpg')
label = KMeans(n_clusters=4).fit_predict(imgData)
#对像素点进行聚类并输出
label = label.reshape([row,col])
pic_new = image.new("L", (row, col))
#向图片中添加灰度值
for i in range(row):
for j in range(col):
pic_new.putpixel((i,j), int(256/(label[i][j]+1)))
#保存图片
pic_new.save("result-bull-4.jpg", "JPEG")
KNN :通过计算待分类数据点,与已有数据集中的所有数据点的距离。取距离最小的前K个点,根据“少数服从多数"的原则,将这个数据点划分为出现次数最多的那个类别。
在sklearn库中,可以使用sklearn.neighbors.KNeighborsClassifier创建一个K近邻分类器 ,主要参数有:
决策树是一种树形结构的分类器,通过顺序询问分类点的属性决定分类点最终的类别。通常根据特征的信息增益或其他指标,构建一颗决策树。在分类时,只需要按照决策树中的结点依次进行判断,即可得到样本所属类别。
在sklearn库中,可以使用sklearn.tree.DecisionTreeClassifier创建一个决策树用于分类,其主要参数有:
朴素贝叶斯分类器是一个以贝叶斯定理为基础的多分类的分类器。
对于给定数据,首先基于特征的条件独立性假设,学习输入输出的联合概率分布,然后基于此模型,对给定的输入x ,利用贝叶斯定理求出后验概率最大的输出y。
在sklearn库中,实现了三个朴素贝叶斯分类器,如下表所示:
分类器 | 描述 |
---|---|
naive_ bayes.GussianNB | 高斯朴素贝叶斯 |
naive_ bayes.MultinomialNB | 针对多项式模型的朴素贝叶斯分类器 |
naive_ bayes.BernoulliNB | 针对多元伯努利模型的朴素贝叶斯分类器 |
区别在于假设某一特征的所有属于某个类别的观测值符合特定分布,如分类问题的特征包括人的身高,身高符合高斯分布,这类问题适合高斯朴素贝叶斯
在sklearn库中,可以使用sklearn.naive_ _bayes.GaussianNB创建一个高斯朴素贝叶斯分类器,其参数有:
朴素贝叶斯是典型的生成学习方法,由训练数据学习联合概率分布,并求得后验概率分布。
朴素贝叶斯一般在小规模数据上的表现很好,适合进行多分类任务。
算法流程
●需要从特征文件和标签文件中将所有数据加载到内存中,由于存在缺失值,此步骤还需要进行简单的数据预处理。
●创建对应的分类器,并使用训练数据进行训练。
●利用测试集预测,通过使用真实值和预测值的比对,计算模型整体的准确率和召回率,来评测模型。