机器学习:实现人工智能的手段,利用数据或经验进行学习,改善具体算法的性能。
机器学习分类
监督学习(Supervised Learning)从给定的数据集中学习出一个函数,当新的数据到来时,通过函数预测结果。训练集通常由人工标注。
无监督学习(Unsupervised Learning)训练集没有人标注的结果。
半监督学习(Semi-supervised Learning)介于监督学习和无监督学习之间
强化学习(Reinforcement Learning 增强学习) 通过观察来执行什么样的动作来获得最好的回报,每个动作都会对环境有所影响。学习对象根据观察到的周围环境反馈做出判断。
深度学习(Deep Learning)利用深层神经网络模型抽象数据的表示特征。
scikit-learn :简称sklearn,是第三方模块,集成了常用机器学习方法,只需简单调用就能完成大多数机器学习任务。sklearn库是在Numpy,SciPy和matplotlib库的基础上开发而成,在安装sklearn前,需先安装这些依赖库。scikit-learn官网副标题为Machine Learning in Python
sklearn的安装: 安装顺序为Numpy库—Scipy库—matplotlib库—sklearn库(依据python版本下载对应的文件,https://pypi.python.org/pypi/scikit-learn/0.18.1)
sklearn库的基本功能:分类任务、回归任务、 聚类任务、降维任务、模型选择、数据预处理。
聚类任务
K-means:cluster.KMeans AP聚类:cluster.AffinityPropagation (聚类模型:加载模块)
均值漂移:cluster.MeanShift 层次聚类:cluster.AgglomerativeClustering
DBSCAN:cluster.DBSCAN BIRCH:cluster.Brich 谱聚类:cluster.SpectralClustering
降维任务
主成分分析 :decomposition.PCA 截断SVD和LSA :decomposition.TruncatedSVD
字典学习:decomposition.SparseCorder 因子分析:decomposition.FactorAnalysis
独立成分分析 :decomposition.FastlCA 非负矩阵分解:decomposition.NMF
LDA: decomposition.LatentDirchletAllocation
分类任务
最近邻算法:neighbors.NearestNeighbors 支持向量机:svm.SVC
朴素贝叶斯:naive_bayes.GaussianNB 决策树:tree.DecisionTreeClassifier
集成方法:ensemble.BaggingClassifier 神经网络:neural_network.MLPClassifier
回归任务
岭回归:linear_model.Ridge Lasso回归:linear_model.Lasso
弹性网络:linear_model.ElasticNet 最小角回归:linear_model.Lars
贝叶斯回归:linear_model.BayesianRidge 逻辑回归:linear_model.LogisticRegression
多项式回归:linear_model.PolynomialFeatures
from sklearn.datasets import load_iris
小数据集:波士顿房价数据集(回归---load_boston())、鸢尾花数据集(分类---load_iris())、糖尿病数据集(回归---load_diabetes())、手写数字数据集(分类---load_digits())
大数据集:Olivetti脸部图像数据集(降维---fetch_olivetti_faces())、新闻分类数据集(分类---fetch_20newsgroups())、带标签的人脸数据集(分类,降维---fetch_lfw_people())、路透社新闻语料收集库(分类---fetch_rcv1()) 小数据集可直接使用,大数据要在调用时程序自动下载(一次即可)
波士顿房价数据集:应用于回归问题。包含506组数据。用sklearn.datasets.load_boston可加载相关数据集 ,重要参数为return_X_y:表示是否返回target(即价格),默认为False, 只返回data(即属性)。
鸢尾花数据集:用于多分类问题,采集鸢尾花测量数据(萼片长度、萼片宽度、花瓣长度、花瓣宽度)及其所属类别(Iris Setosa,Iris Versicolour,Iris Virginica)。使用sklearn.datasets. load_iris加载数据集。参数有return_X_y:若为True,以(data, target)形式返回数据;默认为False,以字典形式返回数据全部信息(包括 data和target)。
手写数字数据集:包括1797个0-9的手写数字数据,每个数字由8*8 大小的矩阵构成,矩阵中值的范围是0-16,代表颜色的深度。使用sklearn.datasets.load_digits即可加载相关数据集 ,参数包括return_X_y。n_class表示返回数据的类别数,如:n_class=5,则返回0到4的数据样本。
无监督学习:利用无标签数据学习数据的分布或数据与数据之间的关系。有监督学习和无监督学习的最大区别在于数据是否有标签;无监督学习最常应用的场景是聚类和降维。
根据数据的“相似性”将数据分为多类。评估两个不同样本之间的“相似性” ,通常方法为计算两个样本之间的“距离”。 用不同的方法计算样本间的距离会关系到聚类结果的好坏。
常用的聚类方法:欧氏距离、曼哈顿距离、马氏距离、夹角余弦
sklearn vs. 聚类:sklearn提供聚类算法函数在sklearn.cluster模块中,同样的数据集应用于不同的算法,有不同结果,所耗时间也不相。(DBSCAN:相对快速,近邻传播算法时间较长)
sklearn.cluster输入数据形式,标准数据输入格式:[样本个数,特征个数]定义的矩阵形式;相似性矩阵输入格式:由[样本数目]定义的矩阵形式,矩阵中每个元素为两个样本相似度
算法 | 参数 | 可拓展性 | 相似性度量 |
K-means | 聚类个数 | 大规模数据 | 点间距离 |
DBSCAN | 邻域个数及其他超参 | 大规模数据 | 点间距离 |
Gaussian Mixtures | 聚类个数及其他超参 | 复杂,不适合大规模数据 | 马氏距离 |
Brich | 分支因子、阈值等其他超参 | 大规模数据 | 两点间的欧氏距离 |
K-Means所需参数:n_clusters:用于指定聚类中心的个数;init:初始聚类中心的初始化方法 ;max_iter:最大的迭代次数(一般调用时只用给出n_clusters即可,init默认是k-means++,max_iter默认是00);.data:加载的数据;label:聚类后各数据所属的标签 ;fit_predict( ):计算簇中心以及为簇分配序号。
(1)从n个样本对象任意选择k个对象作为初始聚类中心;
(2)根据在步骤 (1) 中设置的k个聚类中心,计算每个对象与这k个中心的距离;
(3)经过步骤 (2) 的计算,所有对象与这个k个中心的距离就计算出来了,接着把所有对象与离它最近的中心归在一个类簇中;
(4)重新计算每个类簇的中心对象的位置;
(5)重复步骤 (3) 和 (4),直到类簇聚类方案中的对象归类几乎不发生变化为止。
过程:1.建立工程,导入sklearn相关包( numpy / KMeans)2.加载数据,创建K-means算法实例,并进行训练,获得标签。3.输出标签,查看结果。
import numpy as np
from sklearn.cluster import KMeans
def loadData(filePath):
fr = open(filePath,'r+') #r+读写打开一个文本文件
lines = fr.readlines() #readlines()一次读取整个文件
retData = [] #readData用来存储城市的各项消费信息
retCityName = [] #retCityName用来存储城市名称
for line in lines:
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') #利用loadData方法读取数据
km = KMeans(n_clusters=4)
label = km.fit_predict(data) #调用Kmeans()fit_predict()方法进行计算
expenses = np.sum(km.cluster_centers_,axis=1)
#print(expenses)
CityCluster = [[],[],[],[]] #将城市按label分成设定的簇
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])
Expenses:5477.90
['天津', '江苏', '浙江', '福建', '重庆', '云南', '西藏']
Expenses:3696.84
['河北', '山西', '内蒙古', '吉林', '黑龙江', '江西', '河南', '陕西', '甘肃', '青海', '宁夏', '新疆']
Expenses:7754.66
['北京', '上海', '广东']
Expenses:4290.59
['辽宁', '安徽', '山东', '湖南', '湖北', '广西', '海南', '四川', '贵州']
#导入模块
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
#读入数据
df = pd.read_csv('China_cities.csv')
print(df.head())
#数据预处理(只留下x,y坐标)
x = df.drop('省级行政区',axis=1)#pandas中.drop()函数用于删除,axis=0指删除index,删除columns时要指定axis=1
x = x.drop('城市',axis=1)
x_np = np.array(x)
print(x_np)
#模型构建与训练
n_clusters = 7 #类簇的数量
estimator = KMeans(n_clusters) #构建聚类器
estimator.fit(x) #训练K-Means聚类器
#数据可视化
markers = ['*','v','+','^','s','x','o']#标记样式列表
colors = ['r','g','m','c','y','b','orange']#标记颜色列表
labels = estimator.labels_ #获得聚类标签
plt.figure(figsize=(9,6))
plt.title('Major Cities in China',fontsize=25)
plt.xlabel('East Longitude',fontsize=18)
plt.ylabel('North Latitude',fontsize=18)
for i in range(n_clusters):
members = labels == i #members是一个布尔型数组
plt.scatter( #绘制散点图
x_np[members,1], #经度数组
x_np[members,0], #维度数组
marker = markers[i], #标记样式
c = colors[i] #标记颜色
)
plt.grid() #显示网格线
plt.savefig('China_cities.png',bbox_inches='tight')
原文链接:https://blog.csdn.net/TXK_Kevin/article/details/113714825
拓展与改进:计算两条数据相似性时,Sklearn 的K-Means默认用的是欧式距离。虽然还有余弦相 似度,马氏距离等多种方法,但没有设定计算距离方法的参数。
DBSCAN是基于密度的算法,聚类时不需预先指定簇的个数,最终簇的个数不定。DBSCAN将数据分为3类:核心点、边界点、噪音点。
DBSCAN主要参数:eps:两个样本被看作邻居节点的最大距离;min_samples:簇的样本数;metric:距离计算方式;如sklearn.cluster.DBSCAN(eps=0.5,min_samples=5,metric='euclidean')
优势:1.不需要指定簇个数;2.可以发现任意形状的簇;3.擅长找到离群点(检测任务);4.两个参数就够了
劣势:1.高维数据有些困难(可以做降维);2.参数难以选择(参数对结果的影响很大);3.Sklearn中效率很慢(数据削减策略)
类似于传销组织发展下线,边界点是无法圈到其他下线,只有上线没有下线;离群点可用于异常检测
可视化:https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/
取Eps=3(半径),MinPts=3(个数),对所有点进行聚类(曼哈顿距离),计算每个点其领域Eps=3内的点的集合。集合内点的个数超过MinPts=3的点为核心点。核心点的邻域内为边界点,否则为噪声点(橙色点为核心点,蓝色点为边界点,黑色点为噪声点)—— 将距离不超过Eps=3的点相互连接,构成一个簇,核心点领域内的点也会被加入到这个簇中。
将每个点以Eps为半径画圆,若圆内的点的个数>=MinPTs,则可认为圆心点为核心点,圆内的其他点为边界点,不在圆内为噪音点。去噪。距离不超过Eps=3的点相互连接,构成一个簇,一个簇中可能有多个核心点。成簇。
在eps邻域和minPoints的基础上,描述样本的紧密相连: 上面3幅图分别表示:密度直达(Y到X是密度直达的,X在核心样本Y的邻域内);密度可达(Y到X建立的关系为密度可达,核心点---其他点);密度相连(X和Y是密度相连,其他点---其他点)
过程:1.建立工程,导入sklearn相关包。2.读入数据并进行处理。3.上网时间聚类,创建DBSCAN算法实例,并进行训练,获得标签。4.输出标签,查看结果。5.画直方图,分析实验结果。
#上网时间聚类
import numpy as np
import sklearn.cluster as skc
from sklearn import metrics
import matplotlib.pyplot as plt
mac2id=dict() #创建一个字典
onlinetimes=[]
f=open('TestData.txt',encoding='utf-8')
for line in f:
mac=line.split(',')[2] #读取mac地址,mac为变量,存储一个数,但后面的mac在for循环体内,会对所有的mac数进行处理
onlinetime=int(line.split(',')[6]) #读取上网时长(15)
starttime=int(line.split(',')[4].split(' ')[1].split(':')[0]) #读取结束时间的时间点-小时(23)2014-07-20 23:10:16.540000000
if mac not in mac2id: #字典的函数:not in,判断键是否在字典中
mac2id[mac]=len(onlinetimes) #mac2id是一个字典,key是mac地址,value是上网时长及开始上网时间
onlinetimes.append((starttime,onlinetime))
else:
onlinetimes[mac2id[mac]]=[(starttime,onlinetime)]
real_X=np.array(onlinetimes).reshape((-1,2))
X=real_X[:,0:1]
db=skc.DBSCAN(eps=0.01,min_samples=20).fit(X) #fix()函数用于计算均值和标准差
labels = db.labels_ #labels_属性记载了样本对应的cluster编号,其中编号为-1的为噪音点
#调用DBSCAN方法进行训练,labels为每个数据的簇标签
print('Labels:')
print(labels)
raito=len(labels[labels[:] == -1]) / len(labels)
print('Noise raito:',format(raito, '.2%'))
#打印数据被记上的标签,计算标签为-1,即噪声数据的比例
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,':')
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]
#上网时长聚类,前面部分不变
real_X=np.array(onlinetimes).reshape((-1,2))
X=np.log(1+real_X[:,1:])
db=skc.DBSCAN(eps=0.14,min_samples=10).fit(X)
labels = db.labels_
#调用DBSCAN方法进行训练,labels为每个数据的簇标签
print('Labels:')
print(labels)
raito=len(labels[labels[:] == -1]) / len(labels)
print('Noise raito:',format(raito, '.2%'))
#打印数据被记上的标签,计算标签为-1,即噪声数据的比例
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,':')
count=len(X[labels == i])
mean=np.mean(real_X[labels == i][:,1])
std=np.std(real_X[labels == i][:,1])
print('\t number of sample: ',count)
print('\t mean of sample : ',format(mean,'.1f'))
print('\t std of sample : ',format(std,'.1f'))
#统计每一个簇内的样本个数,均值,标准差
在保证数据的代表性特性情况下,将高维数据转化为低维数据的过程,可视化、精简数据。
聚类 vs. 降维:都是无监督学习,存在关联,如某些高维数据的聚类可通过降维处理,学界研究也表明代表性聚类算法如K-means与降维算法NMF之间存在等价性。
sklearn vs. 降维:sklearn提供降维算法函数在sklearn.decomposition模块中,有7种,降维过程可理解为对数据集组成成分的分解。
算法 | 参数 | 可扩展性 | 适用任务 |
PCS | 所降维度及其他超参 | 大规模数据 | 信号处理 |
FastlCA | 所降维度及其他超参 | 超大规模数据 | 图形图像特征提取 |
NMF | 所降维度及其他超参 | 大规模数据 | 图形图像特征提取 |
LDA | 所降维度及其他超参 | 大规模数据 | 文本数据,主题挖掘 |
主成分分析(Principal Component Analysis,PCA)是常用的一种降维方法。具有相关性的高维变量合成为线性无关的低维变量,能尽可能保留原始数据信息。
方差:各样本和样本均值差的平方和的均值,用于度量一组数据的分散程度。
协方差:用于度量两个变量之间的线性相关程度,若两个变量的协方差为0,则二者线性无关。协方差矩阵是由变量的协方差值构成的矩阵(对称阵)。
特征向量:描述数据集结构的非零向量,并满足,A是方阵,是特征向量,是特征值。
原理:矩阵的主成分就是其协方差矩阵对应的特征向量,最大特征值是第一主成分,以此类推。
sklearn中主成分分析:在sklearn库中,可以使用sklearn.decomposition.PCA加载PCA进行降维,主要参数有:
n_components:指定主成分的个数,即降维后数据的维度。
svd_solver:设置特征值分解的方法,默认为'auto',其他可选有'full' ,'arpack' ,'randomized'。