Q:无监督学习和有监督学习定义和区别
A:有监督学习:提供数据并提供数据对应结果的机器学习过程。追要包括分类和回归。
无监督学习:提供数据但是不提供数据对应结果的机器学习过程。主要应用在统计学中的密度估计和聚类分析。
Q:K-means的聚类过程
A:
step1:首先选择k个类别的中心点
step2:对任意一个样本,求其到各类中心的距离,将该样本归到距离最短的中心所在的类
step3:聚好类后,重新计算每个聚类的中心点位置
step4:重复2,3步骤迭代,直到k个类中心点的位置不变,或者达到一定的迭代次数,则迭代结束,否则继续迭代
Q:K-means的弊端以及改进方式
A:初始聚类中心是随机选择,因此可能会让结果陷入局部最优,而且随机选择的K值点距离相近的话可能会导致收敛慢的问题。优化方法比较多,例如 K-means++、Kernel K-means等
//读取csv文件并去掉header
val publicDwdDF = spark.read.schema(userBookSchema).option("timestampFormat", "yyyy/MM/dd HH:mm:ss ZZ").csv("/Users/admin/Downloads/user-book-130M.csv")
val row1 = publicDwdDF.first()
publicDwdDF.filter(row => row != row1).createTempView("user_book_tmp")
val userFeature = spark.sql(sql2)
/**
* StringIndexer转换器可以把一列类别型的特征(或标签)进行编码,使其数值化,索引的范围从0开始,该过程可以使得相应的特征索引化,使得某些无法接受类别型特征的算法可以使用,并提高诸如决策树等机器学习算法的效率
*/
val count = userFeature.count()
//"category_name1", "category_name2", "title", "author", "is_break", "is_lock", "is_over", "words_num"
val catalog_features = Array("book_id", "read_duration", "click_count")
var train_test = userFeature
//循环遍历为每一个特征做编码索引
for (catalog_feature <- catalog_features) {
val indexer = new StringIndexer()
.setInputCol(catalog_feature)
.setOutputCol(catalog_feature.concat("_index"))
val train_index_model = indexer.fit(train_test)
val train_indexed = train_index_model.transform(train_test)
train_test = train_indexed
}
val train_test_rdd = train_test.rdd.map(row => {
Vectors.dense(Array(
row.getDouble(4),
row.getDouble(5)
))
}).cache()
/**
*
* Kmeans聚类
* numClusters 表示期望的聚类的个数
* numIterations 表示方法单次运行最大的迭代次数
* initializationMode 表示初始聚类中心点的选择方式, 目前支持随机选择或者 K-means||方式。默认是 K-means||。
*/
val numClusters = 4 //聚类的类数
val numIterations = 20 //迭代次数
//对比不同K值下的均方误差
for (i <- Array(2,3,4,5,6,7,8,9)){
val kMeansModel = KMeans.train(train_test_rdd, i, numIterations)
kMeansModel.clusterCenters.map(_.toArray.mkString(" ")).foreach(println)
val measure = kMeansModel.distanceMeasure
println("measure: "+ measure)
//使用误差平方和来评估数据模型
val ssd = kMeansModel.computeCost(train_test_rdd)
println("sum of squared distances of points to their nearest center when k=" + i + " -> "+ ssd)
}