---KMEANS的优缺点 密度等的脚本--
优点
- k-平均算法是解决聚类问题的一种经典算法,算法简单、快速。
- 对处理大数据集,该算法是相对可伸缩的和高效率的,因为它的复杂度大约是O(nkt),其中n是所有对象的数目,k是簇的数目,t是迭代的次数。通常k<<n。这个算法经常以局部最优结束。
- 算法尝试找出使平方误差函数值最小的k个划分。当簇是密集的、球状或团状的,而簇与簇之间区别明显时,它的聚类效果很好。
缺点
- K 是事先给定的,这个 K 值的选定是非常难以估计的;
- 对初值敏感,对于不同的初始值,可能会导致不同的聚类结果。一旦初始值选择的不好,可能无法得到有效的聚类结果;
- 该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的。
- 不适合于发现非凸面形状的簇,或者大小差别很大的簇;
- 对于”噪声”和孤立点数据敏感,少量的该类数据能够对平均值产生极大影响。
- # -*- coding:utf8 -*-
import numpy as np
import pylab as pl
import pandas as pd
import pymysql
import scipy
from sklearn.model_selection import train_test_split#以前的cross validation已停用
from sklearn.ensemble import RandomForestClassifier
from sklearn import tree#简单决策树
from sklearn.tree import DecisionTreeClassifier
from sklearn.cluster import KMeans
from sklearn.cluster import DBSCAN
from sklearn.externals import joblib
dbconn = pymysql.connect(
host="127.0.0.1",
database="test",
user="root",
password="111111",
port=3306,
charset='utf8')
sqlcmd = "select * from forkmeans"
data = pd.DataFrame(pd.read_sql(sqlcmd, dbconn))
#print data.shape
x = data.iloc[:,1:5]#前27个字段是特征字段
clf = KMeans(n_clusters=8,init='k-means++',max_iter=300,tol=0.0001,algorithm='full',random_state=1,verbose=0)
#algorithm可以选EMS算法,就是full算法,还可以auto,还可以elkan三角变化
clf = clf.fit(x)
print clf.labels_#给出类
[0 0 0 ... 0 0 0]
r1 = pd.Series(clf.labels_).value_counts()#各个类的样本数目
r2 = pd.DataFrame(clf.cluster_centers_)#聚类中心点的向量
r = pd.concat([r2,r1],axis=1)#横向连接起来
print r
0 1 2 3 0
0 1.140934 58.339642 18.140445 3.115462 2988
1 0.310000 999.000000 60493.550000 1.620000 1
2 0.645000 999.000000 22994.925000 36.545000 2
3 1.109350 984.150956 43.940707 9.491262 523
4 1.310000 11088.000000 11.620000 3.130000 1
5 1.150000 999.000000 13043.750000 10.160000 1
6 1.156250 783.610000 2241.325000 8.651250 8
7 0.897273 2698.112727 37.353636 16.827273 11
e = pd.concat([data,pd.Series(clf.labels_, index= data.index)], axis=1)
#每个样本对应的类别
e.columns = list(data.columns)+[u'聚类类别']#重命名表头
print e.head(3)
et = e.loc[(e[u'聚类类别'] == 3) , [u'贝塔系数',u'市盈(动)',u'市销率',u'市净率',u'资产负债率']]
print et.head(3)
#概率密度图
def density_plot(data): #自定义作图函数
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
p = data.plot(kind='kde', linewidth = 2, subplots = True, sharex = False)
[p[i].set_ylabel(u'密度') for i in range(k)]
plt.legend()
return plt.show()
density_plot(et)#按条件提取,来绘制密度图