数据聚类

K均值算法

In [3]:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# 分割训练集和测试集
digits_train = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tra',header=None)
digits_test = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tes',header=None)
In [4]:
x_train = digits_train[np.arange(64)]
y_train = digits_train[64]
x_test = digits_test[np.arange(64)]
y_test = digits_test[64]
In [24]:
# 训练集中存在空值,去除
#np.isnan(x_train).any()
#np.isnan(y_train).any()
x_train.dropna(inplace=True)
y_train.dropna(inplace=True)
x_train.shape, y_train.shape
C:\Users\spark\Anaconda2\lib\site-packages\ipykernel_launcher.py:4: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  after removing the cwd from sys.path.
Out[24]:
((1398, 64), (1398L,))
In [17]:
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=10)
kmeans.fit(x_train)
y_pred = kmeans.predict(x_test)
In [26]:
# 性能测评
# 1.使用ARI
from sklearn import metrics
print metrics.adjusted_rand_score(y_test,y_pred)
0.668009225712
In [53]:
# 2.使用轮廓系数SC。以下代码重新定义了数据集,包括2个数据特征,无标签
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
In [77]:
# 把窗口分成3*2个子图,并在第1个子图作图
plt.subplot(3,2,1)
# 初始化原始数据点
x1 = np.array([1,2,3,1,5,6,5,5,6,7,8,9,7,9])
x2 = np.array([1,3,2,2,8,6,7,6,7,1,2,1,1,3])
x = np.array(zip(x1,x2)).reshape(len(x1),2)
# 在1号子图做出原始数据点阵的分布
plt.xlim([0,10])
plt.ylim([0,10])
plt.title('Instances')
plt.scatter(x1,x2)

colors = ['b','g','r','c','m','y','k','b']
markers = ['o','s','D','v','^','p','*','+']

clusters = [2,3,4,5,8]
subplot_counter = 1
sc_scores = []
for t in clusters:
    subplot_counter += 1
    plt.subplot(3,2,subplot_counter)
    kmeans_model = KMeans(n_clusters=t).fit(x)
    
    for i, l in enumerate(kmeans_model.labels_):
        plt.plot(x1[i],x2[i],color=colors[l],marker=markers[l],ls='None')
        
    plt.xlim([0,10])
    plt.ylim([0,10])
    plt.subplots_adjust(top=1.5,wspace=0.5,hspace=0.5)
    sc_score = silhouette_score(x,kmeans_model.labels_,metric='euclidean') ## 计算轮廓系数SC
    sc_scores.append(sc_score)
    plt.title('K=%s, sc=%0.03f' %(t,sc_score))
# 绘制sc与n的折线图
plt.figure()
plt.plot(clusters, sc_scores,'*-')
plt.xlabel('Number of Clusters')
plt.ylabel('Silhouette Coefficient Score')

plt.show()

特征降维

PCA主成分分析方法

In [2]:
# 计算2*2线性相关矩阵的秩
import numpy as np
M = np.array([[1,2],[2,4]])
np.linalg.matrix_rank(M,tol=None)
Out[2]:
1
In [31]:
# 以手写数字案例为例
x_digits = x_train
y_digits = y_train
# 降维
from sklearn.decomposition import PCA
estimator = PCA(n_components=2)
x_pca = estimator.fit_transform(x_digits)
# 显示降维后的分布
from matplotlib import pyplot as plt
def plot_pca_scatter():
    #subplot_counter = 0
    colors = ['black','blue','purple','yellow','deeppink','red','lime','cyan','orange','gray']
    for i in xrange(len(colors)):
        #subplot_counter += 1
        #plt.subplot(5,2,subplot_counter)
        px = x_pca[:,0][y_digits.as_matrix()==i]
        py = x_pca[:,1][y_digits.as_matrix()==i]
        plt.scatter(px,py,c=colors[i],s=3)
    plt.legend(np.arange(0,10).astype(str))
    plt.xlabel('First Principal Component')
    plt.ylabel('Second Principal Component')
    plt.show()
    
plot_pca_scatter()
In [33]:
# 比较降维前后的图像识别效果
# 使用相同配置的支持向量机
from sklearn.svm import LinearSVC
svc = LinearSVC()
svc.fit(x_train,y_train)
y_predict = svc.predict(x_test)

estimator = PCA(n_components=20)
pca_x_train = estimator.fit_transform(x_train)
pca_x_test = estimator.transform(x_test)

pca_svc = LinearSVC()
pca_svc.fit(pca_x_train,y_train)
pca_y_predict = pca_svc.predict(pca_x_test)
In [39]:
# 性能测评
from sklearn.metrics import classification_report
print svc.score(x_test,y_test)
print classification_report(y_test,y_predict,target_names=np.arange(10).astype(str))

print pca_svc.score(pca_x_test,y_test)
print classification_report(y_test,pca_y_predict,target_names=np.arange(10).astype(str))
0.93489148581
              precision    recall  f1-score   support

           0       0.99      0.98      0.98       178
           1       0.95      0.89      0.92       182
           2       0.99      0.97      0.98       177
           3       0.97      0.89      0.93       183
           4       0.95      0.98      0.96       181
           5       0.90      0.97      0.93       182
           6       0.99      0.97      0.98       181
           7       0.99      0.91      0.95       179
           8       0.78      0.91      0.84       174
           9       0.88      0.89      0.88       180

   micro avg       0.93      0.93      0.93      1797
   macro avg       0.94      0.93      0.94      1797
weighted avg       0.94      0.93      0.94      1797

0.918753478019
              precision    recall  f1-score   support

           0       0.97      0.96      0.96       178
           1       0.92      0.80      0.85       182
           2       0.98      0.98      0.98       177
           3       0.93      0.92      0.93       183
           4       0.92      0.98      0.95       181
           5       0.88      0.96      0.92       182
           6       0.97      0.98      0.97       181
           7       0.96      0.90      0.93       179
           8       0.84      0.89      0.86       174
           9       0.83      0.84      0.83       180

   micro avg       0.92      0.92      0.92      1797
   macro avg       0.92      0.92      0.92      1797
weighted avg       0.92      0.92      0.92      1797