探索:用朴素贝叶斯文本分类器对Kotlin中的文本进行分类
原标题:探索:用朴素贝叶斯文本分类器对Kotlin中的文本进行分类
来源:今日头条 链接:https://www.toutiao.com/a6704177050153910795/
探索没有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
一THE END一
免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。
合作及投稿邮箱:E-mail:editor@tusaishared.com
热门资源
应用笔画宽度变换...
应用背景:是盲人辅助系统,城市环境中的机器导航...
端到端语音识别时...
从上世纪 50 年代诞生到 2012 年引入 DNN 后识别效...
人体姿态估计的过...
人体姿态估计是计算机视觉中一个很基础的问题。从...
GAN之根据文本描述...
一些比较好玩的任务也就应运而生,比如图像修复、...
谷歌发布TyDi QA语...
为了鼓励对多语言问答技术的研究,谷歌发布了 TyDi...
智能在线
400-630-6780
聆听.建议反馈
E-mail: support@tusaishared.com