kotlin可以调用python算法吗?用朴素贝叶斯文本分类器对Kotlin中的文本进行分类
kotlin可以调用python算法吗?用朴素贝叶斯文本分类器对Kotlin中的文本进行分类贝叶斯定理朴素贝叶斯文本分类利用贝叶斯定理的力量将文档(文本)分类为特定的类。有时候,在平台中本地编码的分类器可以比TensorFlow或其API执行得更好。此外,我们可以对它的工作和推理有更多的控制流。我们将使用朴素贝叶斯文本分类器对Kotlin中的文本进行分类,该文本最终将在Android设备上运行。说到朴素贝叶斯文本分类,Naive Bayes Classifiers - GeeksforGeeks
点击上方关注,All in AI中国
探索没有TensorFlow API的纯Kotlin语言中的贝叶斯文本分类。
文本分类是自然语言处理中的一项重要任务,具有广泛的应用前景。我们将学习如何以非深度学习的方式使用该技术,而无需使用TensorFlow和神经网络。因为这个分类器将在Android应用程序中工作,所以需要用Kotlin或Java编写。
为什么不是我们的TensorFlow或者Python呢?TensorFlow和TensorFlow Lite可以在Android上高效地工作(有时也能让人神往)。如果可以用Kotlin (Android原生语言)创建类似的算法,那么可以用任何编程语言(如C、c 甚至Swift (iOS原生语言))创建类似的算法。
有时候,在平台中本地编码的分类器可以比TensorFlow或其API执行得更好。此外,我们可以对它的工作和推理有更多的控制流。
我们要用哪种机器学习算法?我们到底在创造什么?我们将使用朴素贝叶斯文本分类器对Kotlin中的文本进行分类,该文本最终将在Android设备上运行。
说到朴素贝叶斯文本分类,Naive Bayes Classifiers - GeeksforGeeks
朴素贝叶斯文本分类利用贝叶斯定理的力量将文档(文本)分类为特定的类。
贝叶斯定理
如果我们根据文本分类的需要来计算这个等式,
我们代表我们的文档作为令牌x₁ x₂……xₙ和C是我们将计算的概率的类。分母被省略 并在这里看到它的解释(因为在两类(C₁和C₂)、P (x₁ x₂……xₙ)将保持不变,并充当一个正常化常数)
我们将计算两类的概率,即SPAM(C 1)和HAM(C 2)。具有较高概率的那个将是我们的输出。
对于每个类,我们都有一个词汇表或一组出现在spam或ham单词中的单词,它们将代表我们的类语料库。
让我们从Kotlin开始吧。
如果您以前喜欢Python !
首先,我们将分别定义包含 spam和ham单词的语料库positiveBagOfWords 和negativeBagOfWords。
class Vocabulary { companion object { val positiveBagOfWords = arrayOf( ... ) // Some words here val negativeBagOfWords = arrayOf( ... ) // Some words here } }
现在,我们创建一个名为Classifier的新类来处理分类任务。我们需要定义两个常量和一个方法,该方法从给定的文本片段中提取标记(通过删除不必要的单词、标点等)。
companion object { val CLASS_POSITIVE = 0 // Spam val CLASS_NEGATIVE = 1 // Ham private val englishStopWords = arrayOf( "i" "me" "my" "myself" "we" "our" "ours" "ourselves" "you" "your" "yours" "yourself" "yourselves" "he" "him" "his" "himself" "she" "her" "hers" "herself" "it" "its" "itself" "they" "them" "their" "theirs" "themselves" "what" "which" "who" "whom" "this" "that" "these" "those" "am" "is" "are" "was" "were" "be" "been" "being" "have" "has" "had" "having" "do" "does" "did" "doing" "a" "an" "the" "and" "but" "if" "or" "because" "as" "until" "while" "of" "at" "by" "for" "with" "about" "against" "between" "into" "through" "during" "before" "after" "above" "below" "to" "from" "up" "down" "in" "out" "on" "off" "over" "under" "again" "further" "then" "once" "here" "there" "when" "where" "why" "how" "all" "any" "both" "each" "few" "more" "most" "other" "some" "such" "no" "nor" "not" "only" "own" "same" "so" "than" "too" "very" "s" "t" "can" "will" "just" "don" "should" "now" "hello" "hi" "dear" "respected" "thank" ) fun getTokens( text : String ) : Array<String> { val tokens = text.toLowerCase().split( " " ) val filteredTokens = ArrayList<String>() for ( i in 0 until tokens.count() ) { if ( !tokens[i].trim().isBlank() ) { filteredTokens.add( tokens[ i ] ) } } val stopWordRemovedTokens = tokens.map { Regex("[^a-zA-Z]").replace( it "") } as ArrayList<String> stopWordRemovedTokens.removeAll { englishStopWords.contains( it ) or it.trim().isBlank() } return stopWordRemovedTokens.distinct().toTypedArray() } }
gettoken (document) =令牌。因此我们可以将一个文档D等一系列令牌x₁ x xₙ₂……。
找到的概率
首先,我们需要找到P(C)或类概率。 这只不过是两个语料库中有多少单词属于C类的概率。
private fun findClassProbability(classVocab1 : Array<String> classVocab2 : Array<String> classVocab : Array<String>) : Float{ val total_words = (classVocab1.count() classVocab2.count()).toFloat() val class_count = (classVocab.count()).toFloat() return ( class_count / total_words ) }
接下来,我们需要找到P(X | C)也就是X属于C类的概率。
在此之前,我们需要一种方法来找到给定 xᵢ 的P( xᵢ | C ),它是给定文档中的一个标记。 我们可以使用这种方法。
private fun findProbabilityGivenClass( x : String classVocab : Array<String> ) : Float { val x_count = classVocab.count { it.contains(x) or x.contains(it) }.toFloat() val class_count = classVocab.count().toFloat() return (( x_count / class_count ) 1) }
其中class_vocab是一个语料库。它代表P中的C(xᵢ| C)。想知道1是从哪里来的吗?这是拉普拉斯平滑处理。如果在我们的语料库中不存在xᵢ时P(xᵢ| C)为0,那么我们所有的P(X | C)都可以变为0。添加1可以解决此问题。
现在,我们需要将所有P(xᵢ| C)相乘,最后将它乘以P(C),这是我们在下面方法中的类概率。
private fun findProbabilityGivenSample( document : String classVocab : Array<String> ) : Float { val tokens = getTokens( document ) var probability_given_class = 1.0f for ( token in tokens ) { probability_given_class *= findProbabilityGivenClass( token classVocab ) } return probability_given_class * findClassProbability( positiveBagOfWords negativeBagOfWords classVocab ) }
这是所有。现在我们需要检查哪个类有更高的可能性。
fun classifyText( text : String ) : Int { val class_1_probability = findProbabilityGivenSample( text positiveBagOfWords ) val class_2_probability = findProbabilityGivenSample( text negativeBagOfWords ) if ( class_1_probability > class_2_probability ) { return CLASS_POSITIVE } else if ( class_1_probability < class_2_probability ) { return CLASS_NEGATIVE } }
可以在此一眼看到完整的代码。https://gist.github.com/shubham0204/c19eb5694bf2c7be3901772726ac5c5e