溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的

發(fā)布時間:2021-11-15 15:12:28 來源:億速云 閱讀:148 作者:柒染 欄目:大數(shù)據(jù)

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

1.文本挖掘模塊設(shè)計(jì)

 

1.1文本挖掘流程

文本分析是機(jī)器學(xué)習(xí)中的一個很寬泛的領(lǐng)域,并且在情感分析、聊天機(jī)器人、垃圾郵件檢測、推薦系統(tǒng)以及自然語言處理等方面得到了廣泛應(yīng)用。

文本聚類是信息檢索領(lǐng)域的一個重要概念,在文本挖掘領(lǐng)域有著廣泛的應(yīng)用。文本聚類能夠自動地將文本數(shù)據(jù)集劃分為不同的類簇,從而更好地組織文本信息,可以實(shí)現(xiàn)高效的知識導(dǎo)航與瀏覽。

本文選擇主題模型LDA(Latent Dirichlet Allocation)算法對文檔進(jìn)行分類處理,選擇在Spark平臺上通過Spark MLlib實(shí)現(xiàn)LDA算法,其中Spark Mllib是Spark提供的機(jī)器學(xué)習(xí)庫,該庫提供了常用的機(jī)器學(xué)習(xí)算法。    

 

1.2文本挖掘流程分析

首先是數(shù)據(jù)源部分,主要的數(shù)據(jù)包括文檔數(shù)據(jù)和互聯(lián)網(wǎng)爬蟲數(shù)據(jù)。然后是數(shù)據(jù)抽取部分,將已經(jīng)收集好的數(shù)據(jù)通過同步工具上傳至分布式文件系統(tǒng)HDFS,作為模型訓(xùn)練的數(shù)據(jù)源。其次是數(shù)據(jù)探索與預(yù)處理部分,該部分主要是對原始數(shù)據(jù)集進(jìn)行預(yù)處理,包括分詞、停用詞過濾、特征向量提取等。再次是模型訓(xùn)練部分,主要包括訓(xùn)練與測試,從而得到一個模型。最后是模型評估,對學(xué)得模型進(jìn)行評估之后,進(jìn)行線上部署。

 

2.文本挖掘模塊算法研究

 

2.1LDA主題模型算法

LDA(Latent Dirichlet allocation)由David M. Blei,Andrew Y. Ng,Michael I. Jordan于2003年提出的基于概率模型的主題模型算法,即隱含狄利克雷分布,它可以將文檔集中每篇文檔的主題以概率分布的形式給出,將文本向量投射到更容易分析處理的主題空間當(dāng)中,去除文本中存在的噪聲,是一種常用的文本分析技術(shù),可以用來識別大規(guī)模文檔集或語料庫中潛在的主題信息,通常被用來對大規(guī)模文檔數(shù)據(jù)進(jìn)行建模。通過主題模型和設(shè)定的主題數(shù),可以訓(xùn)練出文檔集合中不同的主題所占的比例以及每個主題下的關(guān)鍵詞語出現(xiàn)的概率。從文檔集合中學(xué)習(xí)得到主題分布和主題比例,可以進(jìn)一步在數(shù)據(jù)挖掘任務(wù)中使用。

LDA借用詞袋的思想,以某一概率選取某個主題,再以某一概率選出主題中的每個單詞,通過不斷重復(fù)該步驟產(chǎn)生文檔中的所有語詞。該方法對詞匯進(jìn)行了模糊聚類,聚集到一類的詞可以間接地表示一個隱含的主題。LDA對文本信息進(jìn)行了挖掘,能用來衡量不同文檔之間的潛在關(guān)系,也能通過某一類詞來表達(dá)文檔中隱藏的主題。

 

2.2K均值算法

聚類(Clustering)是一種將數(shù)據(jù)集劃分為若干組或類的方法。通過聚類過程將一群抽象的對象分為若干組,每一組由相似的對象構(gòu)成,稱之為一個類別。與分類不同(將數(shù)據(jù)按照事先定義好的分類標(biāo)準(zhǔn)進(jìn)行劃分),聚類是一種無監(jiān)督學(xué)習(xí)(unsupervised learning),訓(xùn)練數(shù)據(jù)集的標(biāo)簽信息是未知的,目標(biāo)是通過對無標(biāo)記訓(xùn)練樣本按照特定的測度的形似性程度進(jìn)行聚合,為進(jìn)一步數(shù)據(jù)分析提供基礎(chǔ)。

K均值(k-means)算法的基本思想是初始隨機(jī)給定K 個簇中心,即從n個數(shù)據(jù)對象中選擇k個任意對象作為初始的簇中心,按照最鄰近原則把待分類樣本點(diǎn)分到各個簇。然后按平均法重新計(jì)算各個簇的中心(該類別中的所有數(shù)據(jù)對象的均值),從而確定新的簇心。一直迭代,直到簇心的移動距離小于某個給定的值。

K均值算法采用了貪心策略,通過迭代優(yōu)化來近似求解上式E值,算法流程如下圖所示

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的  
 

2.3文本挖掘算法優(yōu)化

LDA主題模型算法應(yīng)用于文檔聚類,計(jì)算得出的主題可以看做是文檔的聚類中心,利用主題模型進(jìn)行文檔聚類,可以有效地組織文檔數(shù)據(jù)集。同時,由于LDA主題模型可以計(jì)算出每篇文檔在不同主題下的概率分布,因此可以將此主題的概率分布作為文檔的特征向量,從而將高維的文檔向量投影到低維的特征空間中。

計(jì)算文本之間的距離是傳統(tǒng)的K-means算法在進(jìn)行文本聚類時的關(guān)鍵步驟,而文本通常是非結(jié)構(gòu)化數(shù)據(jù),構(gòu)建的文本向量具有稀疏性和維度高的特點(diǎn),同時,構(gòu)建文本特征向量并未考慮到文字之間的語義關(guān)系,因此可能會造成位于同一類簇的文本之間具有非相似性。

因此本文基于LDA主題模型改進(jìn)K-means算法,首先通過LDA主題模型對文檔數(shù)據(jù)集進(jìn)行建模,挖掘出每篇文檔的主題概率分布,既能夠達(dá)到文檔降維和去除噪聲的效果,又能彌補(bǔ)通過關(guān)鍵詞構(gòu)建文檔特征向量容易造成丟失信息的缺陷。最后每篇文檔的主題概率分布作為K-means算法的輸入數(shù)據(jù)集。

 

3.實(shí)驗(yàn)分析

 

3.1基于Spark的LDA主題模型算法實(shí)現(xiàn)

 
數(shù)據(jù)集介紹

選擇Newsgroups數(shù)據(jù)集作為該實(shí)驗(yàn)的訓(xùn)練集和測試集。Newgroups是一個新聞數(shù)據(jù)集,該數(shù)據(jù)集包括大約20000篇新聞文檔,總共分為6個大類別,每個大類別又分不同的小類別,小類別共計(jì)20個,如下表所示。該新聞數(shù)據(jù)集已經(jīng)成為了學(xué)界和業(yè)界在機(jī)器學(xué)習(xí)的文本挖掘?qū)嶒?yàn)中常用的數(shù)據(jù)集,比如文本分類和文本聚類。

該數(shù)據(jù)集共包含7個文件,其中3個文件為訓(xùn)練數(shù)據(jù)(train.data、train.label、train.map),共計(jì)11269篇,另外3個文件為測試數(shù)據(jù)(test.data、test.label、test.map),共計(jì)7505篇,另外一個文件為詞匯表(vocabulary.txt),其第i行表示編號為i的單詞的名稱。文件擴(kuò)展名為.data的文件格式為[docIdx wordIdx count],其中docIdx表示文檔編號,wordIdx表示詞語的編號,count表示該詞語的詞頻統(tǒng)計(jì)。文件擴(kuò)展名為.label的文件表示文檔的主題分類,每行數(shù)據(jù)代表某篇文檔的類別。文件擴(kuò)展名為.map的文表示類別編號與類別名稱的映射關(guān)系,其具體格式為[labelName labelId]。

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的  
 
原始數(shù)據(jù)集處理

原始的數(shù)據(jù)集格式為[docIdx wordIdx count],例如[1,20,2]表示在編號為1的文檔中,編號為20的詞語的詞頻是2。LDA接受的參數(shù)格式為:

[label,(vector_ size, [wiIdx,wjIdx,···wnIdx ],[tfi,tfj,···tfn])]
 

上述格式的數(shù)據(jù)代表一個帶有標(biāo)簽的稀疏向量,其中l(wèi)abel表示文檔編號,vector_ size表示向量的維度,wnIdx表示詞n的索引編號,tfn表示詞n的詞頻。需要將原始數(shù)據(jù)轉(zhuǎn)換成上述的格式,具體步驟如下:

  • Step1:將原始數(shù)據(jù)集上傳至HDFS
[kms@kms-1 ~]$ hdfs dfs -put /opt/modules/train_data/lda/train.data  /train/lda/
 
  • Step2:初始化SparkSession并加載數(shù)據(jù)
val spark = SparkSession           
                       .builder           
                       .appName(s"${this.getClass.getSimpleName}")                                          .getOrCreate()         
//設(shè)置日志級別         
Logger.getLogger("org.apache.spark").setLevel(Level.OFF)         Logger.getLogger("org.apache.hadoop").setLevel(Level.OFF) 
//加載原始數(shù)據(jù)集
val rowDS = spark.read.textFile("/train/lda/train.data")     
 
  • Step3:數(shù)據(jù)集矩陣變換處理
//創(chuàng)建形如MatrixEntry(row_index, column_index, value)的MatrixEntry
val matrixEntry:RDD[MatrixEntry] = rowDS.rdd.map(_.split(" "))
                           .map(rowdata => MatrixEntry(rowdata(0).toLong,rowdata(1).toLong,rowdata(2).toDouble))
//創(chuàng)建稀疏矩陣
val sparseMatrix: CoordinateMatrix = new  CoordinateMatrix(matrixEntry)
//創(chuàng)建LabeledPoint數(shù)據(jù)集
val labelPointData = sparseMatrix.toIndexedRowMatrix.rows.map(r => (r.index, r.vector.asML))
val corpusDF = spark.createDataFrame(labelPointData).toDF("label","features")
corpusDF.saveAsTextFile("/tarin/lda/labelPointData")

 

處理之后的部分?jǐn)?shù)據(jù)集如下所示,其中一行代表一篇文檔的特征向量

[4551,(53976,[23,27,29,30,44,45,48,314,425,748,767,825,930,969,995,1345,7033,13872,16798,19139,26846,26847,27081,29607,30801,31200,31201,31202],[2.0,1.0,3.0,3.0,1.0,1.0,1.0,1.0,2.0,3.0,1.0,2.0,1.0,1.0,2.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0])]
[2493,(53976,[80,133,754,3699,4066,5190,6138,7327,7361,10267,10344,10949,11390,11683,11759,16206,22708,22709],[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,2.0,1.0,1.0,2.0,1.0,1.0,1.0,1.0,2.0,1.0])]

   
k折交叉驗(yàn)證確定訓(xùn)練參數(shù)

交叉驗(yàn)證法(cross validation)是將數(shù)據(jù)集D劃分為k個大小相似的互斥子集的一種方法,其中每個子集都盡可能地保持?jǐn)?shù)據(jù)分布的一致性,即從數(shù)據(jù)集D中通過分層采樣的方式得到。然后,每次再用k-1個子集的并集作為訓(xùn)練集,剩下的那個子集作為測試集;通過這樣的處理,可以得到k組訓(xùn)練集和測試集,進(jìn)而可以進(jìn)行k次訓(xùn)練和測試,最終返回的是這k個測試結(jié)果的均值。交叉驗(yàn)證法評估結(jié)果的穩(wěn)定性和保真性在很大程度上依賴于k的取值,為突出這一點(diǎn),通常把交叉驗(yàn)證法稱為k折交叉驗(yàn)證(k-fold cross validation)。K通常取值為10,稱之為10折交叉驗(yàn)證,下圖給出了10折交叉驗(yàn)證的示意圖。

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的  

困惑度(perplexity)指標(biāo)是LDA 模型的原作者Blei 等提出的一種反應(yīng)模型泛化能力的指標(biāo), 在評價模型的優(yōu)劣上具有一定的代表性和普遍性。所謂困惑度就是文檔在劃分主題時確定性的評判, 反映的是模型對新樣本的適用性。困惑度越小表示該模型的泛化能力越好。

十折交叉驗(yàn)證處理過程如下所示

//將數(shù)據(jù)集分割為10份,每份占10%
    val splitData = labelPointData.randomSplit(Array.fill(10)(0.1))
   //設(shè)定主題的個數(shù)為15-25
    val rangTopic = 15 to 25
    rangTopic.foreach { k =>
      var perplexity = 0.0
      for (i <- 0 to 9) {
        //選擇其中9份做訓(xùn)練集
        val trainIdx = (0 to 9).toArray.filter(_ != i)
        var trainData = spark.sparkContext.union(
          splitData(trainIdx(0)),
          splitData(trainIdx(1)),
          splitData(trainIdx(2)),
          splitData(trainIdx(3)),
          splitData(trainIdx(4)),
          splitData(trainIdx(5)),
          splitData(trainIdx(6)),
          splitData(trainIdx(7)),
          splitData(trainIdx(8)))
        //創(chuàng)建DataFrame
        val trainDF = spark.createDataFrame(trainData).toDF("label","features")
        val testDF = spark.createDataFrame(splitData(i)).toDF("label","features")
        //訓(xùn)練主題個數(shù)為k時的模型
        val lda = new LDA().setK(k).setMaxIter(50)
        val ldaModel = lda.fit(trainDF)
       perplexity = perplexity + ldaModel.logPerplexity(testDF)
      }
      val avePerplexity = perplexity / 10
      System.out.println("當(dāng)主題個數(shù)為 " + k + "時," + "交叉驗(yàn)證的平均困惑度為 " + avePerplexity)
    }

 

經(jīng)過十折交叉驗(yàn)證,驗(yàn)證在不同主題下(取值15-25)訓(xùn)練模型的平均困惑度,測試發(fā)現(xiàn)在主題k=20時,困惑度的值最小。由于困惑度值越小, 表示該模型具有較好的泛化能力,所以選擇k=20作為主題個數(shù)。

 
實(shí)驗(yàn)結(jié)果

將主題個數(shù)設(shè)置為20,迭代次數(shù)設(shè)置為50,使用上述數(shù)據(jù)集訓(xùn)練LDA模型,具體步驟如下

//訓(xùn)練LDA模型
      val lda = new LDA().setK(20).setMaxIter(50)
      val model = lda.fit(corpusDF)
      val ll = model.logLikelihood(corpusDF)
      val lp = model.logPerplexity(corpusDF)
      println("當(dāng)主題個數(shù)為20時對數(shù)似然為: " + ll)
      println("當(dāng)主題個數(shù)為20時困惑度為: " + lp)
      //描述主題
      val topics = model.describeTopics(5)
      println("The topics described by their top-weighted terms:")
      topics.show(false)
      topics.rdd.saveAsTextFile("/tarin/lda/topics")
      // 測試結(jié)果
    val transformed = model.transform(corpusDF)
transformed.select("label","topicDistribution").rdd.saveAsTextFile("/tarin/lda /testtopic")

 

通過訓(xùn)練得到LDA模型,其中訓(xùn)練數(shù)據(jù)的主題-單詞概率分布如下表所示,選擇權(quán)重排名在前5的單詞,其中topic表示主題編號,termIndices表示詞語編號組成的集合,termWeights表示詞語編號對應(yīng)的權(quán)重的集合。

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的  

每個主題對應(yīng)的單詞列表如下表所示,其中topic表示主題,termIndices表示詞語編號組成的集合,vocabulary表示詞匯。

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的  

該模型的文檔-主題分布如下表所示,由于文檔較多,這里僅列出部分文檔,其中l(wèi)abel表示文檔編號,topicDistribution表示文檔的主題分布。

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的  

通過上面的分析,得到了文本的主題分布。每篇文檔將對應(yīng)一個主題的特征空間,從而達(dá)到降維的目的。主題-單詞單詞概率分布描述了主題的特征空間,其中主題表示聚類中心。

結(jié)合詞匯表與訓(xùn)練集,將其處理成[word,count]的形式,其中word表示單詞,count表示該次出現(xiàn)的頻次,具體的處理過程如下。

package com.apache.ml
import org.apache.spark.{SparkConf, SparkContext}

object WordCount {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
      .setMaster("local")
      .setAppName("wordcount")
    val sc = new SparkContext(conf)

    val rawRDD = sc.textFile("e:///lda/train.data")
    val vocabulary = sc.textFile("e:///lda/vocabulary.txt")
    val word_nums = rawRDD.map(_.split(" ")).map(row => (row(1).toLong, row(2).toInt))
    val word_count = word_nums.reduceByKey(_ + _)
    val sort_wcnt = word_count.sortByKey(false)
    //處理詞匯表
    val num_vocabulary = vocabulary.zipWithIndex().map(row => (row._2, row._1))
    val sort_combination = sort_wcnt.join(num_vocabulary)
      .map(row => (row._2._1, row._2._2))
      .sortByKey(false)
      .map(row => (row._2, row._1))
    sort_combination.saveAsTextFile("e:///combination")
  }
}

 

通過使用R語言的wordcloud2包,進(jìn)行可視化文檔詞云圖展示,見下圖

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的  
 

3.2Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)

 
數(shù)據(jù)預(yù)處理

將通過LDA主題模型計(jì)算的文檔-主題分布作為k-means的輸入,文檔-主題分布的形式為[label, features,topicDistribution],其中features代表文檔的特征向量,每一行數(shù)據(jù)代表一篇文檔。由于k-means接受的特征向量輸入的形式為[label,features],所以需要將原始的數(shù)據(jù)集schema轉(zhuǎn)化為[label,features]的形式,即將topicDistribution列名轉(zhuǎn)為features。處理步驟為:

   Val trainDF =   transformed.select("label","topicDistribution").toDF("label",   "features")       
   
模型訓(xùn)練

Spark ML的K-means算法提供了如下的參數(shù)配置:

  • setFeaturesCol(value: String):設(shè)置輸入的特征向量列,默認(rèn)值為features
  • setK(value: Int):設(shè)置類簇的個數(shù)
  • setMaxIter(value: Int):設(shè)置最大迭代次數(shù)
  • setPredictionCol(value: String):設(shè)置輸出列名稱,默認(rèn)為prediction
  • setSeed(value: Long):設(shè)置隨機(jī)數(shù)種子
  • setTol(value: Double):設(shè)置收斂閾值

設(shè)置最大迭代次數(shù)為200,隨機(jī)數(shù)種子為123,類簇個數(shù)為2、4、6、8、10、12、14、16、18、20,其余選擇默認(rèn)值,分別觀察評估指標(biāo)的變化情況。具體代碼如下:

(2 to 20 by 2).toList.map {k =>
      val kmeans = new KMeans().setK(k).setSeed(123).setMaxIter(200)
      val kmeansModel = kmeans.fit(kMeansTrain)
      // 預(yù)測結(jié)果
      val predictions = kmeansModel.transform(kMeansTrain)
      //計(jì)算誤差平方和
      val wssse = kmeansModel.computeCost(kMeansTrain)
      println(s"Within set sum of squared errors = $wssse")
      // 計(jì)算輪廓系數(shù)
      val evaluator = new ClusteringEvaluator()
      val silhouette = evaluator.evaluate(predictions)
      println(s"Silhouette with squared euclidean distance = $silhouette")
      //顯示聚類結(jié)果
      println("Cluster Centers: ")
      kmeansModel.clusterCenters.foreach(println)
        }
 

經(jīng)過訓(xùn)練,得到當(dāng)K為6時聚類效果最好,此時的聚類結(jié)果如下表所示:

Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的

 
模型評估
  • 輪廓系數(shù)

輪廓系數(shù)(Silhouette Coefficient)是評價聚類效果好壞的一種方法,用來衡量簇的密集與分散程度。它結(jié)合內(nèi)聚度和分離度兩種因素,可以用來在相同原始數(shù)據(jù)的基礎(chǔ)上用來評價不同算法、或者算法不同運(yùn)行方式對聚類結(jié)果所產(chǎn)生的影響。輪廓系數(shù)取值為[-1,1],其值越大表示同類中樣本距離最近,不同類中樣本距離最遠(yuǎn),即該值越接近于1,簇越緊湊,聚類效果越好。

使用K-means算法,將待分類數(shù)據(jù)集分為了 k 個類簇,對于其中的一個點(diǎn) i 來說,a(i)表示該向量到它所屬類簇中其他點(diǎn)的平均距離,b(i)表示該向量到其他類簇中點(diǎn)的平均距離。對于一個樣本集合,所有樣本的輪廓系數(shù)的平均值即為該聚類結(jié)果總的輪廓系數(shù)。

  • 誤差平方和

誤差平方和又稱殘差平方和、組內(nèi)平方和等。根據(jù)n個觀察值擬合適當(dāng)?shù)哪P秃?,余下未能擬合部份(ei=yi-y平均)稱為殘差,其中y平均表示n個觀察值的平均值,所有n個殘差平方之和稱誤差平方和。

當(dāng)K取不同值時,計(jì)算所得誤差平方

計(jì)算所得的輪廓系數(shù)如下圖所示,結(jié)合誤差平方和和輪廓系數(shù),當(dāng)k=6時,有著較好的聚類效果。

3.3結(jié)果分析

首先,通過LDA主題模型,可以計(jì)算出文檔數(shù)據(jù)集的文檔-主題分布情況和主題-單詞的分布情況,訓(xùn)練得出的主題數(shù)即為類簇?cái)?shù)。

對LDA訓(xùn)練的文檔-主題分布結(jié)果,即將文檔表示成在不同主題上的分布所組成的向量,由于LDA考慮到了詞之間的語義關(guān)系,所以該特征向量能夠更好地反應(yīng)文檔的信息,因此可以將其作為K-means聚類算法的輸入,從而彌補(bǔ)基于空間向量模型的K-means算法的缺點(diǎn)。經(jīng)過實(shí)驗(yàn)發(fā)現(xiàn),在類簇K為6時,輪廓系數(shù)為65.9661577458792,誤差平方和為0.8266340036962969,聚類效果良好。

 

主要介紹Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)。對文本挖掘進(jìn)行了詳細(xì)設(shè)計(jì),在公開數(shù)據(jù)集上訓(xùn)練LDA模型,并對文檔-主題分布和主題-詞語分布進(jìn)行了詳細(xì)說明。最后實(shí)現(xiàn)了基于LDA的K-means聚類算法,克服了傳統(tǒng)K-means算法的缺陷。關(guān)于Spark平臺下基于LDA的k-means算法實(shí)現(xiàn)是怎樣的問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI