Изменения

Перейти к: навигация, поиск

Байесовская классификация

5872 байта добавлено, 01:59, 29 ноября 2020
Пример на языке R
|definition =
'''Функционал среднего риска''' {{---}} ожидаемая величина потери при классификации объектов алгоритмом $a$:
:<tex>R(a) = \displaystyle\sum_{y \in Y}\sum_{s \in Y}\lambda_{ys}P_yP(A_s|y)</tex>
}}
Если известны априорные вероятности $P_y$ и функции правдоподобия $p_y(x)$,
то минимум среднего риска $R(a)$ достигается алгоритмом
:<tex>a(x) = \displaystyle\arg\min_{s \in Y}\sum_{y \in Y}\lambda_{ys}P_yp_y(x)</tex>
|proof=
Для произвольного $t \in Y$ запишем функционал среднего риска:
:<tex>R(a)=\displaystyle\sum_{y \in Y}\sum_{s \in Y}\lambda_{ys}P_yP(A_s|y) = \sum_{y \in Y}\lambda_{yt}P_yP(A_t|y) + \sum_{s \in Y\setminus\{t\} }\sum_{y \in Y}\lambda_{ys}P_yP(A_s|y).</tex>
Применив формулу полной вероятности, $P(A_t \mid y) = 1 −\displaystyle\sum_{ s \in Y \setminus \{t\} }P(A_s \mid y)$, получим:
:<tex>R(a) = \displaystyle\sum_{y \in Y}\lambda_{yt}P_y + \sum_{ s \in Y \setminus \{t\} } \sum_{y \in Y} (\lambda_{ys} - \lambda_{yt})P_yP(A_s|y) = </tex>
:<tex>= const(a) + \displaystyle\sum_{ s \in Y \setminus \{t\} }\int_{A_s}\sum_{y \in Y} (\lambda_{ys}−\lambda_{yt})P_yp_y(x)dx. </tex>
Введём для сокращения записи обозначение
$R(a) = const(a) + \displaystyle\sum_{ s \in Y \setminus \{t\} }\int_{A_s}(g_s(x)−g_t(x))dx$.
Минимум интегрла интеграла достигается, когда $A_s$ совпадает с областью неположительности подынтегрального выражения. :<tex>A_s=\{x \in X \mid g_s(x) \leq g_t(x), \forall t \in Y, t \leq s\}. </tex>
С другой стороны, $A_s=\{x \in X \mid a(x) = s\}$. Значит, $a(x) = s$ тогда и только тогда, когда
:$s= \displaystyle\arg\min_{t \in Y}g_t(x)$.
}}
Следовательно, функции правдоподобия классов представимы в виде:
:<tex>p_y(x) = \displaystyle\prod^n_{i=1}p_{yi}(\xi_i)</tex>
где $p_{yj}(\xi_j)$ плотность распределения значений $j$-го признака для класса $y$.
Подставим эмпирические оценки одномерных плотностей в байесовский классификатор. Получим алгоритм:
:<tex>a(x) = \displaystyle\arg\max_{y \in Y}(\ln\lambda_yP'_y + \sum^n_{j=1}\ln p'_{yj}(\xi_j)). </tex>
Основные его преимущества {{---}} простота реализации и низкие вычислительные затраты при обучении и классификации.
Основной его недостаток {{---}} низкое качество классификации в общем случае.
== Применение == Из-за своего низкого качества классификации наивный байесовскими классификатор в основном он используется либо как эталон при экспериментальном сравнении алгоритмов, либо как элементарный строительный блок в алгоритмических композициях. Рассмотрим частое применение байесовского классификатора к задаче классификации документов по их содержимому, а именно к классификации электронных писем на два класса {{---}} спам ($S$) и не-спам ($\displaystyle \neg S$),предполагая что вероятность слов в тексте не зависит друг от друга: Программные спам-фильтры, построенные на принципах наивного байесовского классификатора, делают «наивное» предположение о том, что события, соответствующие наличию того или иного слова в электронном письме или сообщении, являются независимыми по отношению друг к другу. Это упрощение в общем случае является неверным для естественных языков: :<tex> P(a\ very\ close\ game) = P(a) \times P(very) \times P(close) \times P(game) </tex> Исходя из такого предположения, для решения задачи классификации сообщений лишь на 2 класса: $S$ (спам) и $H = \neg S$ («хэм», то есть не спам) из теоремы Байеса можно вывести следующую формулу оценки вероятности «спамовости» всего сообщения $D$, содержащего слова $W_1, W_2, ... W_N$: :<tex>\displaystyle p(S\mid D) = p(S\mid W_1, W_2, ... W_N) = \frac{p(W_1, W_2, ... W_N\mid S) \cdot p(S)}{p(W_1, W_2, ... W_N)} = </tex> [так как $W_i$ предполагаются независимыми] <tex>=</tex> :<tex>= \displaystyle\frac{\prod_{i} p(W_i\mid S) \cdot p(S)}{p(W_1, W_2, ... W_N)} = \frac{\prod_{i}p(S\mid W_i)}{\prod_i(p(S\mid W_i)) + \left(\frac{p(\neg S)}{p(S)}\right)^{1-N} \cdot \prod_i p(\neg S\mid W_i)} </tex> Результат $p$ обычно сравнивают с некоторым порогом (например, $0.5$), чтобы решить, является ли сообщение спамом или нет. Если $p$ ниже, чем порог, сообщение рассматривают как вероятный «ham», иначе его рассматривают как вероятный спам. :<tex>\displaystyle\ln{p(S\mid D)\over p(\neg S\mid D)} > h</tex>. ==Примеры кода===== Пример кода scikit-learn ===
Классификатор [https://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.GaussianNB.html#sklearn.naive_bayes.GaussianNB GaussianNB] реализует наивный байесовский классификатор в предположении что изначальное распределение было гауссовым:
:<tex>P(x_i \mid y) = \displaystyle\frac{1}{\sqrt{2\pi\sigma^2_y}}\exp(-\frac{(x_i - \mu_y)^2}{2\sigma^2_y})</tex>
'''from''' sklearn '''import''' datasets
'''from''' sklearn.metrics '''import''' f1_score, accuracy_score
'''from''' sklearn.naive_bayes '''import''' GaussianNB
iris = datasets.load_iris()
'''from''' sklearn.naive_bayes '''import''' GaussianNB
gnb = GaussianNB()
y_pred pred = gnb.fit(iris.data, iris.target).predict(iris.data) accuracy = accuracy_score(iris.target, pred) f1 = f1_score(iris.target, pred, average="micro") '''print'''(''"Number of mislabeled points out of a total %d points accruracy:"'', accuracy, ''"f1: %d"'' % (iris.data.shape[0],(iris.target != y_pred).sum())f1)
Вывод:
Number of mislabeled points accruracy: 0.96 f1: 0.96 ===Пример на языке Java===Пример классификации с применением <code>weka.classifiers.bayes.NaiveBayes</code><ref>[http://weka.sourceforge.net/doc.dev/weka/classifiers/bayes/NaiveBayes.html/ Weka, Naive Bayes]</ref> <code>Maven</code> зависимость: <dependency> <groupId>nz.ac.waikato.cms.weka</groupId> <artifactId>weka-stable</artifactId> <version>3.8.0</version> </dependency>  '''import''' weka.classifiers.bayes.NaiveBayes; '''import''' weka.classifiers.evaluation.Evaluation; '''import''' weka.core.converters.ConverterUtils; '''import''' java.util.Random;  <font color="green">// load dataset</font> '''var''' source = new DataSource("/iris.arff"); '''var''' dataset = source.getDataSet(); <font color="green">// set class index to the last attribute</font> dataset.setClassIndex(dataset.numAttributes() - 1); <font color="green">// create and build the classifier</font> '''var''' nb = new NaiveBayes(); nb.buildClassifier(dataset); <font color="green">// cross validate model</font> var eval = new Evaluation(dataset); eval.crossValidateModel(nb, dataset, 10, new Random(41)); System.out of a total 150 points .println("Estimated Accuracy: 6"+ Double.toString(eval.pctCorrect())); === Пример на языке R ==={{Main|Примеры кода на R}}  <font color="gray"># importing package and it's dependencies</font> library(e1071) <font color="gray"># reading data</font> data <- read.csv(<font color="green">"input.csv"</font>, <font color="#660099">sep</font> = <font color="green">','</font>, <font color="#660099">header</font> = FALSE) <font color="gray"># splitting data into training and test data sets</font> index <- createDataPartition(<font color="#660099">y</font> = data$<strong><font color="#660E7A">target</font></strong>, <font color="#660099">p</font> = <font color="blue">0.8</font>, <font color="#660099">list</font> = FALSE) training <- data[index,] testing <- data[-index,] <font color="gray"># create objects x and y for predictor and response variables</font> x <- training[, -<font color="blue">9</font>] y <- training$<strong><font color="#660E7A">target</font></strong> <font color="gray"># training model</font> model <- train(x, y, <font color="green">'nb'</font>, <font color="#660099">trControl</font> = trainControl(<font color="#660099">method</font> = <font color="green">'cv'</font>, <font color="#660099">number</font> = <font color="blue">10</font>)) <font color="gray"># predicting results</font> predictions <- predict(model, <font color="#660099">newdata</font> = testing)
==См. также==
286
правок

Навигация