在上一章博客中我们学习到了一些基本的机器学习的分类计算模型,接下来我们将进行更加深入的学习。
无监督学习:机器学习的一种方法,训练数据中不带标签,让机器自动寻找数据规律并完成任务。
特点:
- 数据不需要标签。
- 算法不受监督信息约束。
优点:
- 降低数据采集难度,极大程度扩充样本量。
- 可能发现新的数据规律、被忽略的重要信息。
聚类分析:把数据样本按照一定的方法分成不同的组别,这样让在同一个组别中的成员对象都有相似的一些属性。
K均值聚类:在样本数据空间中选取K个点作为中心,计算每个样本到各中心的距离,根据距离确定数据类别,是聚类算法中最为基础但也最为重要的算法。
核心流程:
- 基于要求,观察或经验确定聚类的个数K.
- 确定K个中心。
- 计算样本到各中心点距离。
- 根据距离确定各个样本点所属类别。
- 计算同类别样本的中心点,并将其设定为新的中心。
- 重复步骤3-5直到收敛(中心点不再变化)。
通过K均值聚类可以实现图像分割,图像分割就是把图像分成若干个特定的、具有独特性质的区域的技术,是由图像处理到图像分析的关键步骤。
KMeans实现数据聚类:
1 2 3 4 5
| import pandas as pd import numpy as np data=pd.read_csv('task1_data1.csv') data_result=pd.read_csv('task1_data2.csv') data.head()
|
1 2 3
| x_labeled=data.iloc[0,:] print(x_labeled)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| x=data.drop['y',axis=1]
y=data_result.loc[;,'y']
from matplotlib import pyplot as plt fig1=plt.figure() plt.scatter(x.loc[:,'x1'],x.loc[:'x2'],label='unlabeled') plt.scatter(x_labeled['x1'],x_labeled['x2'],label='labeled') plt.title('unlabeled data') plt.xlabel('x1') plt.ylabel('x2') plt.legend(loc='upper left') plt.show()
|
1 2 3 4 5
| from sklearn.cluster import KMeans KM=KMeans(n_clusters=2,init='random',random_state=0)
KM.fit(x)
|
1 2 3 4 5
| centers=KM.cluster_centers_
plt.scatter(centers[:,0],centers[:,1],100,marker='x',label='centers')
|
1 2 3 4
| y_predict=KM.predict(x) print(pd.value_counts(y_predict) print(pd.value_counts(y))
|
由测试数集可以看出,聚类预测的结果由较大的偏差,但也不难看出,可能在分析时,将1和0的分类有可能分反了,因此:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| y_corrected=[] for i in y_predict: if i==0: y_corrected.append(1) elif i==1: y_corrected.append(0)
y_corrected=np.array(y_corrected) fig2=plt.figure(figsize=(16,8)
fig3=plt.subplot(121) plt.scatter(x.loc[:,'x1'][y_corrected==0],x.loc[:'x2'][y_corrected==0],label='label0') plt.scatter(x_labeled['x1'][y_corrected==1],x_labeled['x2'][y_corrected==1],label='label1') plt.scatter(x_labeled['x1'],x_labeled['x2'],label='labeled') plt.title('unlabeled data(corrected result)') plt.xlabel('x1') plt.ylabel('x2') plt.legend(loc='upper left')
fig4=plt.subplot(122) plt.scatter(x.loc[:,'x1'][y==0],x.loc[:'x2'][y==0],label='label0') plt.scatter(x_labeled['x1'][y==1],x_labeled['x2'][y==1],label='label1') plt.scatter(x_labeled['x1'],x_labeled['x2'],label='labeled') plt.title('labeled data') plt.xlabel('x1') plt.ylabel('x2') plt.legend(loc='upper left') plt.show()
|
接下来,我们运用KNN算法进行建模并于之前的方法进行比较:
1 2 3 4 5 6 7 8
| from sklearn.neighbors import KNeighborsClassifier knn=KNeighborsClassifier(n_neighbors=3) knn.fit(x,y)
y_predict_knn=knn.predict(x)
|
1 2 3 4 5
| KM2=KMeans(n_clusters=2,init='random',random_state=1,n_init=1,max_iter=1) KM2.fix(x) centers=KM2.clusters_centers y_predict2=KM2.predict(x)
|
KMeans实现图像分割:
1 2 3 4 5 6
| import numpy as np import matplotlib.pyplot as plt from skimage import io as io img=io.read('1.jpg') plt.show(img.)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| img_height=img.shape[0] img_width=img.shape[1]
img_data=img.reshape(-1,3)
x=img_data
from sklearn.cluster import KMeans model=KMeans(n_clusters=3,random_state=0) model.fit(x)
|
1 2 3 4 5 6 7 8 9 10 11
| label=model.predict(x)
label=label.reshape([img_height,img_width])
label=1/(label+1)
plt.imshow(label)
|
1 2 3 4 5 6
| io.imsave('result_k3.png',label)
model1=KMeans(n_clusters=4,random_state=0) model1.fit(x)
|
1 2 3
| model2=KMeans(n_clusters=8,random_state=0) model2.fit(x)
|
由观察可知,k越小的时候,从一个层级到另一个层级过度的较快,轮廓较为清晰,k越大的时候,层级之间的过度较慢,轮廓较为模糊。
异常检测:根据输入数据,对不匹配预期模式的数据进行识别。
监督式异常检测:提前使用带“正常”与“异常”标签的数据对模型进行训练,机器基于训练好的模型判断新数据是否为异常数据。
无监督式异常检测:通过寻找与其他数据最不匹配的实例来检测出未标记测试数据的异常。
数据降维:在一定的限定条件下,按照一定的规则,尽可能的保留原始数据集重要信息的同时,降低数据集特征的个数。
随着特征数量越来越多,为了避免过拟合,对样本数量的需求会以指数速度增长。
数据降维最常用的方法:主成分分析(PCA),
也称主分量分析,按照一定规则把数据变换到一个新的坐标系统中,使得任何数据投影后尽可能可以分开(新数据尽可能不相关,分布方差最大化)。
计算过程:
- 数据预处理(数据分布标准化:u=0,o=1)。
- 计算协方差矩阵特征向量、及数据在各特征向量投影后的方差。
- 根据需求(任务指定或方差比例)确定降维维度k。
- 选取k维特征向量,计算数据在其形成空间的投影。
异常消费行为检测:
1 2 3 4 5
| import pandas as pd import numpy as np data=pd.read_csv('task1_data.csv') data.head()
|
1 2 3 4 5 6 7 8
| from matplotlib import pyplot as plt fig1=plt.figure() plt.scatter(data.loc[:,'frequency'],data.loc[:,'payment'],marker='x') plt.title('raw data') plt.xlabel('frequency') plt.ylabel('payment') plt.show()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| x=data x1=data.loc[:,'frequence'] x2=data.loc[:,'payment']
fig2=plt.figure(figsize=(20,5))
fig2_1=plt.subplot(121) plt.hist(x1,bins=100) plt.title('frequency data') plt.xlabel('frequency') plt.ylabel('counts')
fig2_2=plt.subplot(122) plt.hist(x2bins=100) plt.title('payment data') plt.xlabel('payment') plt.ylabel('counts')
|
1 2 3 4 5 6 7 8 9 10 11
| x1_mean=x1.mean() x1_sigma=x1.std()
from scipy.stats import norm x1_range=np.linspace(0,10,300) x1_normal=norm.pdf(x1_ramge,x1_mean,x1_sigma) x2_range=np.linspace(0,400,300) x2_normal=norm.pdf(x2_range,x2_mean,x2_sigma)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| fig3=plt.figure(figsize(20,15))
fig3_1=plt.subplot(121) plt.plot(x1_range,x1_normal) plt.title('x1(frequency) Gaussian Distribution') plt.xlabel('x1(frequency)') plt.ylabel('p(x1)')
fig3_2=plt.subplot(122) plt.plot(x2_range,x2_normal) plt.title('x2(payment) Gaussian Distribution') plt.xlabel('x2(payment)') plt.ylabel('p(x2)') plt.show()
|
1 2 3 4 5 6 7 8 9 10
| from sklearn.covariance import EllipticEnvelope model=EllipticEnvelope(contamination=0.03) model.fit(x)
y_predict=model.predict(x)
plt.scatter(data.loc[:,'frequency'][y_predict==1],data.loc[:,'payment'][y_predict==1],marker='o',facecolor='none',edgecolor='red',s=150,label='anomaly_data') plt.legend()
|
当contamination=0.2时:
由此可见,当阈值增大时,检测出的异常数据的比例也因此增大。
PCA+逻辑回归预测检查者是否患糖尿病
1 2 3 4 5
| import pandas as pd import numpy as np data=pd.read_csv('task2_data.csv') data.head()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| x=data.drop(['label'],axis=1) y=data.loc[:,'label']
from sklearn.linear_model import LogisticRegression model1=LogisticRegression(max_iter=1000) model1.fit(x,y)
y_predict=model1.predict(x)
from sklearn.metrics import accuracy_score accuracy=accutacy_score(y,y_predict)
|
1 2 3 4 5 6 7 8 9
| from sklearn.precessing import StandardScaler x_norm=StandardScaler().fit_transform(x)
x1_mean=x.loc[:,'glucise'].mean() x1_norm_mean=x_norm[:,1].mean() x1_sigma=x.loc[:,'glucose'].std() x1_norm_sigma=x_norm[:,1].std()
|
1 2 3 4 5 6 7 8 9 10
| from matplotlib import pyplot as plt fig1=plt.figure(figsize=(12,5))
fig1_1=plt.subplot(121) plt.hist(x.loc[:,'glucose'],bins=100)
fig1_2=plt.subplot(122) plt.hist(x_norm[:,1],bins=100) plt.show()
|
1 2 3 4 5 6 7
| from sklearn.decomposition import PCA pca=PCA(n_components=8) x_pca=pca.fit_transform(x_form)
var=pca.explained_variance_ var_ratio=pca.explained_variance_ratio_
|
1 2 3 4
| fig2=plt.figure(figsize=(10,5)) plt.bar([1,2,3,4,5,6,7,8],var_ratio) plt.show()
|
1 2 3 4
| pca=PCA(n_components=2) x_pca=pca.fit_transform(x_norm) print(x_pca.shape,x_norm.shape)
|
由此可见,通过pca将原本八维的数据降维成了二维。
1 2 3 4 5 6
| fig3=plt.figure() plt.scatter(x_pca[:,1][y==0],x_pca[:,1][y==0],marker='x',label='negative') plt.scatter(x_pca[:,1][y==1],x_pca[:,1][y==1],marker='*',label='positive') plt.legend() plt.show()
|
1 2 3 4 5 6 7
| model2=LogisticRegression() model2.fit(x_pca,y)
y_predict_pca=model2.predict(x_pca) accuracy_pca=accuracy_score(y,y_predict_pca)
|