• mickey
    2019-03-08
    # encoding=utf-8
    from sklearn.feature_extraction.text import CountVectorizer

    #模拟文档集合
    corpus = ['I like great basketball game',
              'This video game is the best action game I have ever played',
              'I really really like basketball',
              'How about this movie? Is the plot great?',
              'Do you like RPG game?',
              'You can try this FPS game',
              'The movie is really great, so great! I enjoy the plot']

    #把文本中的词语转换为词典和相应的向量
    vectorizer = CountVectorizer()
    vectors = vectorizer.fit_transform(corpus)

    from sklearn.feature_extraction.text import TfidfTransformer

    #构建tfidf的值
    transformer = TfidfTransformer()
    tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))

    # 输出每个文档的向量
    tfidf_array = tfidf.toarray()
    words = vectorizer.get_feature_names()

    from Bio.Cluster import kcluster

    #进行聚类,使用向量间的夹角余弦作为相似度的度量
    clusterid, error, nfound = kcluster(tfidf_array, nclusters=3, dist='u')
    print(clusterid)
    '''
    Kmeans 的欧式距离:[0 2 0 1 2 2 1]
    Bio 的夹角余弦:[2 0 0 2 0 2 1]
    '''
    展开

    作者回复: 尝试了不同的方法👍

    
     3
  • 余泽锋
    2019-04-09
    请问一下老师,余弦夹角本质上可以说是归一化的欧式距离么?

    作者回复: 可以这么认为

    
     2
  • Joe
    2019-03-15
    def customKmeans(vec_array, n_clusters=3, epochs=50):
        '''
        @description: 手动实现kmeans,以向量间的夹角余弦作为相似度
                     根据上述tf-idf得到的7条文本向量tfidf_array,进行聚类算法
        @param {type} vec_array- 向量组, n_clusters-聚类数目, epochs- 训练次数
        @return: cluster_labels- 分类标签
        '''

        # 初始化质心的位置
        cluster_centers = []
        cluster_centers_indx = []
        while (len(cluster_centers_indx) < n_clusters):
            indx = random.randint(0, len(vec_array)-1)
            if indx not in cluster_centers_indx:
                cluster_centers_indx.append(indx)
                cluster_centers.append(vec_array[indx])

        # 初始化向量类别
        cluster_labels = [0] * len(vec_array)
        max_similarity = [-1] * len(vec_array)
        epoch = 0
        while(epoch < epochs):
            # 计算每个向量与质心的相似性,并将其归纳到最近的质心集群中
            for i in range(0, len(vec_array)):
                max_similarity[i] = computeCosine(vec_array[i], cluster_centers[0])
                for j in range(1, n_clusters):
                    temp = computeCosine(vec_array[i], cluster_centers[j])
                    if (temp > max_similarity[i]):
                        max_similarity[i] = temp
                        cluster_labels[i] = j

            # 更新质心位置
            for i in range(0, n_clusters):
                # 找到集群对应原向量的下标
                indxs = [indx for indx, cluster in enumerate(
                    cluster_labels) if cluster == i]
                # 根据集群向量的平均值更新质点位置
                cluster_centers[i] = np.average(
                    [vec_array[indx] for indx in indxs], axis=0)

            # 当满足迭代次数或平均最大相似性时退出算法
            epoch += 1
            if (np.average(max_similarity) > 0.9):
                break
        return cluster_labels


    def computeCosine(vec1, vec2):
        # 计算向量间的余弦值
        vecCosine = np.dot(vec1, vec2) / \
            (np.linalg.norm(vec1) * np.linalg.norm(vec2))
        return vecCosine


    # 应用customkmeans
    labels = customKmeans(tfidf_array, n_clusters=3, epochs=1000)
    print(labels)

    输出结果:
    [0 2 0 1 2 2 1]
    展开
    
     2
  • Paul Shan
    2019-09-26
    kmeans方法用的是利用几何信息将空间点归类的方法,最终的结果是归好类的点集质心之间的距离远,但是集合内点之间距离近的效果,可以类比于软件开发中的高内聚低耦合原则来记忆。

    作者回复: 嗯,这个比喻好👍

    
    
  • Aaron(健廷)
    2019-04-10
    请问一下老师,“如果这个 K 值取得太小,群组可能切分太细,每个之间区别不大。如果 K 值取得太大,群组的粒度又太粗,造成群组内差异明显。”,這段話是不是寫反了?

    作者回复: 是的,笔误写反了。。。感谢指正

    
    
  • Bindy🌲
    2019-04-10
    老师,这里如果是中文,是不是要做分词呢

    作者回复: 是的,如果是中文,肯定要做分词的。

    
    
  • Joe
    2019-03-14
    老师,现在很多机器学习的算法都有现成的库了,如sklearn等。但是直接调库,总觉得停留在表面。请问有没有必要自己手动去实现一些经典的机器学习算法呢?

    作者回复: 这是一个好问题,可以参照专栏中的一些介绍,尝试实现某些算法,加强印象,甚至于将来可以根据具体的应用,对算法实现进行优化。

    
    
我们在线,来聊聊吧