是否可以绘制Kmeans的成本值?我想根据Kmeans的迭代绘制成本值,如下图所示
您能否推荐一些相关的主题?谢谢
回答:
Kmeans中的惯性
我猜你想绘制Kmeans运行中每次迭代的惯性值。
K-means算法旨在选择使惯性最小化的中心点,惯性也称为簇内平方和标准。惯性可以被视为簇内部一致性的度量。
这是KMeans在每次迭代中试图最小化的内容。
更多详情请点击这里。
打印每次迭代的惯性值
通过使用kmeans.inertia_
,你可以在拟合KMeans()
后获取最终的惯性值,但如果你想获取每次迭代的惯性值,一种方法是设置verbose=2
。
def train_kmeans(X): kmeans = KMeans(n_clusters=5, verbose=2, n_init=1) kmeans.fit(X) return kmeansX = np.random.random((1000,7))train_kmeans(X)
Initialization completeIteration 0, inertia 545.5728914456803Iteration 1, inertia 440.5225419317938Iteration 2, inertia 431.87478970379755Iteration 3, inertia 427.52125502838504Iteration 4, inertia 425.75105209622967Iteration 5, inertia 424.7788124997543Iteration 6, inertia 424.2111904252263Iteration 7, inertia 423.7217490965455Iteration 8, inertia 423.29439165408354Iteration 9, inertia 422.9243615021072Iteration 10, inertia 422.54144662407566Iteration 11, inertia 422.2677910840504Iteration 12, inertia 421.98686844470336Iteration 13, inertia 421.76289612029376Iteration 14, inertia 421.59241427498324Iteration 15, inertia 421.36516415785724Iteration 16, inertia 421.23801796298704Iteration 17, inertia 421.1065220191125Iteration 18, inertia 420.85788031236586Iteration 19, inertia 420.6053961581343Iteration 20, inertia 420.4998816171483Iteration 21, inertia 420.4436034595902Iteration 22, inertia 420.39833211852346Iteration 23, inertia 420.3583721574586Iteration 24, inertia 420.32684273674226Iteration 25, inertia 420.2786269304449Iteration 26, inertia 420.24149714604516Iteration 27, inertia 420.22255866139835Iteration 28, inertia 420.2075247585145Iteration 29, inertia 420.19985517233584Iteration 30, inertia 420.18983415887305Iteration 31, inertia 420.18584733421886Converged at iteration 31: center shift 8.716337631121295e-33 within tolerance 8.370287188573764e-06
注意: KMeans会多次重新初始化其中心点,并且每次初始化都会运行到max_iters
。为了得到一组惯性值的列表,你需要设置n_iter=1
以确保在拟合模型时只进行一次初始化。如果你将n_iter设置为更高的值,你会在打印输出中看到多个初始化和迭代的列表。
绘制每次迭代的惯性值
问题在于,(据我所知)在sklearn中没有办法通过参数将这些惯性值存储到变量中。因此,你可能需要编写一个包装器来将详细的标准输出重定向到一个输出变量作为文本,然后提取每次迭代的惯性值。
你可以使用StringIO
来捕获verbose=2
的打印输出,提取并绘制。
这是完整的代码 –
import ioimport sysimport numpy as npfrom sklearn.cluster import KMeansimport matplotlib.pyplot as plt#Dummy dataX = np.random.random((1000,7)) def train_kmeans(X): kmeans = KMeans(n_clusters=5, verbose=2, n_init=1) #<-- init=1, verbose=2 kmeans.fit(X) return kmeans#HELPER FUNCTION#Takes the returned and printed output of a function and returns it as variables#In this case, the returned output is the model and printed is the verbose intertia at each iterationdef redirect_wrapper(f, inp): old_stdout = sys.stdout new_stdout = io.StringIO() sys.stdout = new_stdout returned = f(inp) #<- Call function printed = new_stdout.getvalue() #<- store printed output sys.stdout = old_stdout return returned, printedreturned, printed = redirect_wrapper(train_kmeans, X)#Extract inertia valuesinertia = [float(i[i.find('inertia')+len('inertia')+1:]) for i in printed.split('\n')[1:-2]]#Plot!plt.plot(inertia)
编辑: 我已经更新了我的答案,编写了一个通用的辅助函数,该函数调用给定的函数(该函数返回并打印某些内容)并分别返回其打印的数据和返回的数据。在这种情况下,模型被返回,打印的内容作为文本存储在一个变量中。