Python机器学习基础

【无监督学习】

一、聚类

1.1 K-means方法及应用

k-means算法以k为参数,把n个对象分成k个簇,使簇内具有较高的相似度,而簇间的相似度较低。

其处理过程如下: .

  1. 随机选择k个点作为初始的聚类中心;
  2. 对于剩下的点,根据其与聚类中心的距离,将其归入最近的簇
  3. 对每个簇,计算所有点的均值作为新的聚类中心
  4. 重复2、3直到聚类中心不再发生改变
    Python机器学习基础_第1张图片
    数据实例:
    1999年全国31个省份城镇居民家庭平均每人全年消费性支出数据
#导入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])

1.2 DBSCAN方法及应用

DBSCAN算法是一种基于密度的聚类算法:

  • 聚类的时候不需要预先指定簇的个数
  • 最终的簇的个数不定

DBSCAN算法将数据点分为三类:

  • 核心点:在半径Eps内含有超过MinPts数目的点
  • 边界点:在半径Eps内点的数量小于MinPts ,但是落在核心点的邻域内
  • 噪音点:既不是核心点也不是边界点的点
    Python机器学习基础_第2张图片
    DBSCAN算法流程:
  1. 将所有点标记为核心点、边界点或噪声点;
  2. 删除噪声点;
  3. 为距离在Eps之内的所有核心点之间赋予一条边;
  4. 每组连通的核心点形成一个;
  5. 将每个边界点指派到一个与之关联的核心点的簇中(哪一个核心点的半径范围之内)。

Python机器学习基础_第3张图片
Python机器学习基础_第4张图片
Python机器学习基础_第5张图片
数据实例:

现有大学校园网的日志数据, 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]

Python机器学习基础_第6张图片

二、降维

2.1 PCA方法及其应用

主成分分析( Principal Component Analysis , PCA )是最常用的一种降维方法,通常用于高维数据集的探索与可视化,还可以用作数据压缩和预处理等。

PCA可以把具有相关性的高维变量合成为线性无关低维变量,称为主成分。主成分能够尽可能保留原始数据的信息。

原理:矩阵的主成分就是其协方差矩阵对应的特征向量,按照对应的特征值大小进行排序,最大的特征值就是第一主成分 ,其次是第二主成分,以此类推。

输入:
样本集D= {x1, x2…xm};
低维空间维数d’.
过程:

  1. 对所有样本进行中心化(方法见下图);
  2. 计算样本的协方差矩阵XXT;
  3. 对协方差矩阵XXT做特征值分解;
  4. 取最大的d’个特征值所对应的特征向量w1, w2… wa.
    在这里插入图片描述

输出:
投影矩阵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()

2.2 NMF方法及实例

非负矩阵分解( Non-negative Matrix Factorization , NMF )是在矩阵中所有元素均为非负数约束条件之下的矩阵分解方法。

基本思想:给定一个非负矩阵V , NMF能够找到一个非负矩阵W和一个非负矩阵H ,使得矩阵w和H的乘积近似等于矩阵V中的值。Vn*m = Wn*k * Hk*m
Python机器学习基础_第7张图片

  • w矩阵:基础图像矩阵,相当于从原矩阵V中抽取出来的特征
  • H矩阵:系数矩阵。

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()

Python机器学习基础_第8张图片
Python机器学习基础_第9张图片
Python机器学习基础_第10张图片

三、基于聚类的图像分割

图像分割:利用图像的灰度、颜色、纹理、形状等特征,把图像分成若干个互不重叠的区域,并使这些特征在同一区域内呈现相似性,在不同的区域之间存在明显的差异性。然后就可以将分割的图像中具有独特性质的区域提取出来用于不同的研究。

图像分割技术已在实际生活中得到广泛的应用。例如:在机车检验领域,可以应用到轮毂裂纹图像的分割,及时发现裂纹,保证行车安全;在生物医学工程方面,对肝脏CT图像进行分割,为临床治疗和病理学研究提供帮助。

图像分割常用方法:

  1. 阈值分割: 对图像灰度值进行度量,设置不同类别的阈值,达到分割的目的。
  2. 边缘分割: 对图像边缘进行检测,即检测图像中灰度值发生跳变的地方,则为一片
    区域的边缘。
  3. 直方图法: 对图像的颜色建立直方图,而直方图的波峰波谷能够表示一块区域的颜
    色值的范围,来达到分割的目的。
  4. 特定理论: 基于聚类分析、小波变换等理论完成图像分割。

数据实例:

目标:利用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")

Python机器学习基础_第11张图片
Python机器学习基础_第12张图片

【监督学习】

四、分类

4.1 K近邻分类器(KNN)

KNN :通过计算待分类数据点,与已有数据集中的所有数据点的距离。取距离最小的前K个点,根据“少数服从多数"的原则,将这个数据点划分为出现次数最多的那个类别。
Python机器学习基础_第13张图片
在sklearn库中,可以使用sklearn.neighbors.KNeighborsClassifier创建一个K近邻分类器 ,主要参数有:

  • n_neighbors :用于指定分类器中K的大小(默认值为5 ,注意与kmeans的区别)
  • weights :设置选中的K个点对分类结果影响的权重(默认值为平均权重"uniform” , 可以选择"distance" 代表越近的点权重越高,
    或者传入自己编写的以距离为参数的权重计算函数)
  • algorithm :设置用于计算临近点的方法,因为当数据量很大的情况下计算当前点和所有点的距离再选出最近的k各点,这个计算量是很费时的,所以(选项中有ball_ tree、 kd_ tree和brute ,分别代表不同的寻找邻居的优化算法,默认值为auto ,根据训练数据自动选择)

4.2 决策树

决策树是一种树形结构的分类器,通过顺序询问分类点的属性决定分类点最终的类别。通常根据特征的信息增益或其他指标,构建一颗决策树。在分类时,只需要按照决策树中的结点依次进行判断,即可得到样本所属类别。
Python机器学习基础_第14张图片
在sklearn库中,可以使用sklearn.tree.DecisionTreeClassifier创建一个决策树用于分类,其主要参数有:

  • criterion :用于选择属性的准则,可以传入"gini" 代表基尼系数,或者"entropy"代表信息增益。
  • max_ features : 表示在决策树结点进行分裂时,从多少个特征中选择最优特征。可以设定固定数目、百分比或其他标准。它
    的默认值是使用所有特征个数。

4.3 朴素贝叶斯

朴素贝叶斯分类器是一个以贝叶斯定理为基础的多分类的分类器。
对于给定数据,首先基于特征的条件独立性假设,学习输入输出的联合概率分布,然后基于此模型,对给定的输入x ,利用贝叶斯定理求出后验概率最大的输出y。
Python机器学习基础_第15张图片
在sklearn库中,实现了三个朴素贝叶斯分类器,如下表所示:

分类器 描述
naive_ bayes.GussianNB 高斯朴素贝叶斯
naive_ bayes.MultinomialNB 针对多项式模型的朴素贝叶斯分类器
naive_ bayes.BernoulliNB 针对多元伯努利模型的朴素贝叶斯分类器

区别在于假设某一特征的所有属于某个类别的观测值符合特定分布,如分类问题的特征包括人的身高,身高符合高斯分布,这类问题适合高斯朴素贝叶斯

在sklearn库中,可以使用sklearn.naive_ _bayes.GaussianNB创建一个高斯朴素贝叶斯分类器,其参数有:

  • priors :给定各个类别的先验概率。如果为空,则按训练数据的实际情况进行统计;如果给定先验概率,则在训练过程中不能更改。

朴素贝叶斯是典型的生成学习方法,由训练数据学习联合概率分布,并求得后验概率分布。

朴素贝叶斯一般在小规模数据上的表现很好,适合进行多分类任务。

4.4 运动状态——程序编写

算法流程

●需要从特征文件和标签文件中将所有数据加载到内存中,由于存在缺失值,此步骤还需要进行简单的数据预处理。

●创建对应的分类器,并使用训练数据进行训练。

●利用测试集预测,通过使用真实值和预测值的比对,计算模型整体的准确率和召回率,来评测模型。

Python机器学习基础_第16张图片

你可能感兴趣的:(【Note】,机器学习,算法,python,数据分析)