আমরা এই উত্তরটি থেকে দেখতে পাচ্ছি যে পাইথনের ক্ষুদ্রতম সংখ্যাটি (উদাহরণস্বরূপ এটি গ্রহণ করুন) আইইইই 7575৫ এর5e-324
কারণে , এবং হার্ডওয়্যার কারণ অন্যান্য ভাষার ক্ষেত্রেও প্রযোজ্য।
In [2]: np.nextafter(0, 1)
Out[2]: 5e-324
এবং এর চেয়ে ছোট কোনও ভাসমান 0 বাড়ে।
In [3]: np.nextafter(0, 1)/2
Out[3]: 0.0
এবং আসুন with discrete features and two classes
আপনার প্রয়োজন অনুসারে নাইভ বেয়েসের কাজটি দেখুন :
p(S=1|w1,...wn)=p(S=1)∏ni=1p(wi|S=1) ∑s={0,1}p(S=s)∏ni=1p(wi|S=s)
আমাকে একটি সাধারণ এনএলপি টাস্ক বেলো দ্বারা সেই ফাংশনটি ইনস্ট্যান্ট করতে দিন।
আমরা আগত ইমেলটি স্প্যাম ( ) না স্প্যাম ( ) কিনা তা সনাক্ত করার সিদ্ধান্ত নিয়েছি এবং আমাদের কাছে 5000 শব্দ আকারের শব্দভাণ্ডার রয়েছে ( ) এবং কেবলমাত্র উদ্বেগটি যদি কোনও শব্দ ( ) হয় তবে ( ) সরলতার জন্য ইমেলটিতে বা ( ) নয় বায়েস )।S=1S=0n=5,000wip(wi|S=1)1−p(wi|S=1)
In [1]: import numpy as np
In [2]: from sklearn.naive_bayes import BernoulliNB
# let's train our model with 200 samples
In [3]: X = np.random.randint(2, size=(200, 5000))
In [4]: y = np.random.randint(2, size=(200, 1)).ravel()
In [5]: clf = BernoulliNB()
In [6]: model = clf.fit(X, y)
আমরা দেখতে পাচ্ছি যে সম্ভাবনার কারণে খুব ছোট হবে (উভয় এবং 0 এবং 1 এর মধ্যে in এর মধ্যে হবে , এবং তাই আমরা নিশ্চিত যে পণ্যটি than এর চেয়ে ছোট হবে এবং আমরা কেবল পাব ।p(S=s)∏ni=1p(wi|S=s)p(wi|S=1)1−p(wi|S=1)∏5000i5e−3240/0
In [7]: (np.nextafter(0, 1)*2) / (np.nextafter(0, 1)*2)
Out[7]: 1.0
In [8]: (np.nextafter(0, 1)/2) / (np.nextafter(0, 1)/2)
/home/lerner/anaconda3/bin/ipython3:1: RuntimeWarning: invalid value encountered in double_scalars
#!/home/lerner/anaconda3/bin/python
Out[8]: nan
In [9]: l_cpt = model.feature_log_prob_
In [10]: x = np.random.randint(2, size=(1, 5000))
In [11]: cls_lp = model.class_log_prior_
In [12]: probs = np.where(x, np.exp(l_cpt[1]), 1-np.exp(l_cpt[1]))
In [13]: np.exp(cls_lp[1]) * np.prod(probs)
Out[14]: 0.0
তারপরে সমস্যা দেখা দেয়: ইমেলের সম্ভাব্যতা আমরা কীভাবে স্প্যাম গণনা করতে পারি ? বা কীভাবে আমরা অঙ্ক এবং ডিনোমিনেটর গণনা করতে পারি?p(S=1|w1,...wn)
আমরা স্কলারনে অফিসিয়াল বাস্তবায়ন দেখতে পাচ্ছি :
jll = self._joint_log_likelihood(X)
# normalize by P(x) = P(f_1, ..., f_n)
log_prob_x = logsumexp(jll, axis=1)
return jll - np.atleast_2d(log_prob_x).T
সংখ্যার জন্য এটি সম্ভাবনার পণ্যগুলিকে লগ সম্ভাবনার যোগফলে রূপান্তর করে এবং ডিনোমিনেটরের জন্য এটি স্কিপিতে লগসুমপ এক্সপেক্ট ব্যবহার করে যা:
out = log(sum(exp(a - a_max), axis=0))
out += a_max
কারণ আমরা এর যৌথ লগ সম্ভাবনা যুক্ত করে দুটি যৌথ সম্ভাবনা যুক্ত করতে পারি না এবং আমাদের লগ স্পেস থেকে সম্ভাব্যতার জায়গায় যেতে হবে। তবে আমরা দুটি সত্য সম্ভাব্যতা যুক্ত করতে পারি না কারণ সেগুলি খুব ছোট এবং আমাদের এগুলি স্কেল করা উচিত এবং সংযোজন করা উচিত: এবং ফলাফলটি ফিরে দেওয়া লগ স্পেসে তারপরে এটি পুনরুদ্ধার করুন: লগ স্থান যোগ করে ।∑s={0,1}ejlls−max_jlllog∑s={0,1}ejlls−max_jllmax_jll+log∑s={0,1}ejlls−max_jllmax_jll
এবং এখানে উদ্ভূত:
log∑s={0,1}ejlls=log∑s={0,1}ejllsemax_jll−max_jll=logemax_jll+log∑s={0,1}ejlls−max_jll=max_jll+log∑s={0,1}ejlls−max_jll
যেখানে হয় কোডে।max_jlla_max
একবার আমরা লগ স্পেসে এবং ডিনোমিনেটর উভয়ই পেয়ে গেলে আমরা সংখ্যার থেকে ডিনোমিনিটারকে বিয়োগ করে লগের শর্তসাপেক্ষ সম্ভাবনা ( ) পেতে পারি : logp(S=1|w1,...wn)
return jll - np.atleast_2d(log_prob_x).T
আশা করি এইটি কাজ করবে.
তথ্যসূত্র:
1. বার্নোল্লি নাইভ বেইস ক্লাসিফায়ার
2. নাইভ বেয়েসের সাথে স্প্যাম ফিল্টারিং - কোন নাইভ বেয়েস?