【问题标题】:Text labeling with machine learning使用机器学习进行文本标注
【发布时间】:2017-12-18 16:31:52
【问题描述】:

我想根据一组预定义的类标记一堆银行交易(下面的示例,它是clojure 中的一个映射)。我尝试了一种朴素的贝叶斯方法,但有时它完全给了我错误的标签。

根据我的研究,我应该使用有监督的 ML 算法,类似于为多类分类调整的线性 SVM。问题是我真的对机器学习一无所知。第二个问题是大多数 clojure 库已经过时了。

{:label "5339134-17-CPR-FARMODISSEIA LD", :value -13271 :class :health}
{:label "PAG.SERV. 10297 779747511", :value -2889 :class :utilities}
{:label "5339134-14-CPR-GREEN PEPER", :value -1785 :class :restaurants}
{:label "5339134-03-LEV-Av Alm Kings", :value -4000 :class :atm}
{:label "5339134-02-LEV-Big Field, 1", :value -7000 :class :atm}
{:label "IMPOSTO DE SELO", :value -17 :class :banking}

所以大多数类似的交易都有 90% 的类似文本(例如::atm),我相信这应该是一个简单的问题。

我的问题:

  • 我可以使用哪些算法?
  • 我应该如何准备数据?我相信我只有两个特征,tx label 和 tx value。我看到的一些教程有一堆向量,但我不知道是否/如何将字符串数据转换为正确的 ML 格式。

clj 或 java 中的任何示例都将不胜感激。

【问题讨论】:

  • 你能给出一个更大的示例数据集吗?

标签: java machine-learning clojure text-classification


【解决方案1】:

既然你在问题中说

大多数类似的交易都有 90% 的相似文本

我认为首先找出哪些交易标签彼此相似并将它们组合在一起是有意义的。然后你有有限数量的组,每个标签所属的组可以用作名义属性来代替文本本身。如果同一类中的事务具有相似的标签文本,那么希望这应该允许分类算法轻松绘制标签和类之间的相关性。

我尝试使用这些依赖项实现解决方案:

[[org.clojure/clojure "1.8.0"]
 [clj-fuzzy "0.4.0"]
 [cc.artifice/clj-ml "0.8.5"]
 [rm-hull/clustering "0.1.3"]]

对标签进行聚类后,朴素贝叶斯方法似乎对我很有效:

(require '[clj-fuzzy.metrics :as fm]
         '[clj-ml.classifiers :as classify]
         '[clj-ml.data :as data]
         '[clustering.core.qt :as qt])

(def data
  [{:label "5339134-17-CPR-FARMODISSEIA LD", :value -13271 :class :health}
   {:label "PAG.SERV. 10297 779747511", :value -2889 :class :utilities}
   {:label "5339134-14-CPR-GREEN PEPER", :value -1785 :class :restaurants}
   {:label "5339134-03-LEV-Av Alm Kings", :value -4000 :class :atm}
   {:label "5339134-02-LEV-Big Field, 1", :value -7000 :class :atm}
   {:label "IMPOSTO DE SELO", :value -17 :class :banking}])

(def clusters
  (into {}
        (for [cluster (qt/cluster fm/levenshtein (map :label data) 13 1)
              s cluster]
          [s (keyword (str "cluster" (hash cluster)))])))

(def dataset
  (-> (data/make-dataset "my-data"
                         [:value
                          {:label (seq (set (vals clusters)))}
                          {:class [:health :utilities :restaurants :atm :banking]}]
                         (map (juxt :value (comp clusters :label) :class) data))
      (data/dataset-set-class :class)))

(def data-map
  (let [m (into {} (map (juxt data/instance-to-map identity)
                        (data/dataset-seq dataset)))]
    (into {} (for [x data]
               [x (-> x (update :label clusters) (update :value double) m)]))))

(def classifier
  (-> (classify/make-classifier :bayes :naive)
      (classify/classifier-train dataset)))

(defn foo []
  (for [x data]
     (->> x
          data-map
          data/instance-set-class-missing
          (classify/classifier-classify classifier)
          (assoc x :predicted))))

(run! prn (foo))
;; {:label "5339134-17-CPR-FARMODISSEIA LD", :value -13271, :class :health, :predicted :health}
;; {:label "PAG.SERV. 10297 779747511", :value -2889, :class :utilities, :predicted :utilities}
;; {:label "5339134-14-CPR-GREEN PEPER", :value -1785, :class :restaurants, :predicted :restaurants}
;; {:label "5339134-03-LEV-Av Alm Kings", :value -4000, :class :atm, :predicted :atm}
;; {:label "5339134-02-LEV-Big Field, 1", :value -7000, :class :atm, :predicted :atm}
;; {:label "IMPOSTO DE SELO", :value -17, :class :banking, :predicted :banking}

不过,我对 ML 还很陌生,所以如果有什么我忽略了,请告诉我。

另外,在我的实现中,我使用 QT 聚类对输入数据集中的标签进行一次性分区,但如果目标是随着时间的推移继续合并新数据,则可能需要使用流式聚类算法代替。看起来这可能使用 k-means 实现,但这需要实现“Levenshtein 平均”函数。此外,我不确定我使用的聚类库是否支持在其初始结果上进行迭代,因此可能需要进一步实施。

【讨论】:

  • 它看起来很棒。你能解释一下原理吗?为什么必须进行聚类?谢谢!
  • @MiguelPing 我已经在我的答案中添加了我的基本原理和其他一些内容。让我知道您是否还有其他想要我添加的内容!
  • 当然,我正在运行代码,但我不知道如何对新实例进行分类,如果我提供例如; {:label "xxxx" :value -123} 我怎样才能得到预测的课程?另外,我把 levensthein 换成了 jaccard,我相信它会快得多。
  • @MiguelPing 你可以构建一个BK-tree 的标签,并使用它来实现find-cluster 函数将标签映射到集群,然后调用(classify/classifier-classify classifier (data/make-instance dataset (update {:label "xxxx" :value -123} :label find-cluster))) 对你的标签进行分类实例。如果您愿意,我可以尝试编写 find-cluster 函数的实现。
  • @PetrusTheron 我没有忘记这一点(我的待办事项清单上有它),但我想确保当我修改我的答案时,我可以做得令人满意。我意识到您不是最初的提问者,但是您是否有可能将一个更大的数据集放在一起,然后我可以用来测试我的工作?事实上,我无法知道我的解决方案是否有效。
猜你喜欢
  • 1970-01-01
  • 2018-08-15
  • 2020-05-29
  • 2012-11-16
  • 1970-01-01
  • 2012-07-07
  • 1970-01-01
  • 2013-06-07
  • 2014-11-15
相关资源
最近更新 更多