কার্নেলের ঘনত্বের প্রাক্কলন থেকে আমি এলোমেলোভাবে কোনও মান কীভাবে আঁকতে পারি?


10

আমার কিছু পর্যবেক্ষণ রয়েছে এবং আমি এই পর্যবেক্ষণগুলির উপর ভিত্তি করে স্যাম্পলিং নকল করতে চাই। এখানে আমি একটি প্যারামিটারিক নন মডেল বিবেচনা করি, বিশেষত, আমি সীমিত পর্যবেক্ষণগুলি থেকে একটি সিডিএফ অনুমান করার জন্য কর্নেল স্মুথিং ব্যবহার করি hen তখন আমি প্রাপ্ত সিডিএফ থেকে এলোমেলোভাবে মানগুলি আঁকি following নীচে আমার কোডটি দেওয়া হয়েছে, সম্ভাব্যতা অভিন্ন বিতরণ ব্যবহার করে, এবং সম্ভাব্যতার মান সম্মানের সাথে সিডিএফের বিপরীতমুখী হন)

x = [randn(100, 1); rand(100, 1)+4; rand(100, 1)+8];
[f, xi] = ksdensity(x, 'Function', 'cdf', 'NUmPoints', 300);
cdf = [xi', f'];
nbsamp = 100;
rndval = zeros(nbsamp, 1);
for i = 1:nbsamp
    p = rand;
   [~, idx] = sort(abs(cdf(:, 2) - p));
   rndval(i, 1) = cdf(idx(1), 1);
end
figure(1);
hist(x, 40)
figure(2);
hist(rndval, 40)

কোডটিতে প্রদর্শিত হিসাবে, আমি আমার পদ্ধতি পরীক্ষা করার জন্য একটি সিনথেটিক উদাহরণ ব্যবহার করেছি, তবে ফলাফলটি অসন্তুষ্টিজনক, নীচের দুটি চিত্র দ্বারা চিত্রিত হয়েছে (প্রথমটি সিমুলেটেড পর্যবেক্ষণের জন্য, এবং দ্বিতীয় চিত্রটি আনুমানিক সিডিএফ থেকে আঁকা হিস্টগ্রাম দেখায়) :

চিত্র 1 চিত্র ২

সমস্যা আছে কোথায় এমন কেহ কে আছে? তুমাকে অগ্রিম ধন্যবাদ.


বিপরীত ব্যবহার করে স্যাম্পলিং বিশৃঙ্খল রুপান্তর বিপরীত সিডিএফ। en.wikedia.org/wiki/Inverse_transform_sampling
সাইকোরাক্স মনিকাকে

1
আপনার কার্নেলের ঘনত্বের অনুমানকটি এমন একটি বিতরণ তৈরি করে যা কার্নেল বিতরণের একটি অবস্থান মিশ্রণ, সুতরাং কার্নেলের ঘনত্বের প্রাক্কলন থেকে আপনাকে কোনও মান আঁকতে হবে তা হ'ল (1) কার্নেলের ঘনত্ব থেকে একটি মান আঁকুন এবং তারপরে (2) স্বতন্ত্রভাবে একটি নির্বাচন করুন ডেটা এলোমেলোভাবে পয়েন্ট করে এবং এর মানটিকে (1) এর ফলাফলের সাথে যুক্ত করে। সরাসরি কে-ডি-ই উল্টানোর চেষ্টা করা অনেক কম দক্ষ হবে।
whuber

@ সাইকোরাক্স তবে উইকিতে বর্ণিত হিসাবে আমি প্রকৃতপক্ষে বিপরীত রূপান্তর নমুনা পদ্ধতি অনুসরণ করি। দয়া করে কোডটি দেখুন: পি = র্যান্ড; [~, আইডিএক্স] = সাজান (অ্যাবস (সিডিএফ (:, 2) - পি)); rndval (i, 1) = সিডিএফ (আইডিএক্স (1), 1);
এমবারবিলো

@ যাইহোক আপনার ধারণা সম্পর্কে আমার বোঝাপড়াটি সঠিক কিনা তা আমি নিশ্চিত নই। দয়া করে চেক করতে সহায়তা করুন: প্রথমে পর্যবেক্ষণগুলি থেকে একটি মান পুনরায় নমুনা করুন; এবং তারপরে কার্নেল থেকে একটি মান আঁকুন, স্ট্যান্ডার্ড সাধারণ বিতরণ বলুন; অবশেষে, তাদের একসাথে যুক্ত?
এমবারবিলো

উত্তর:


12

একটি কার্নেল ঘনত্ব অনুমানকারী (কেডিএ) এমন একটি বিতরণ তৈরি করে যা কার্নেল বিতরণের একটি অবস্থান মিশ্রণ, সুতরাং কার্নেলের ঘনত্বের প্রাক্কলন থেকে আপনার প্রয়োজনীয় সমস্ত কিছু (1) কার্নেলের ঘনত্ব থেকে একটি মান আঁকুন এবং তারপরে (2) স্বাধীনভাবে এলোমেলোভাবে ডেটা পয়েন্টগুলির একটি নির্বাচন করুন এবং এর ফলাফলটি (1) এর সাথে যুক্ত করুন।

প্রশ্নটির মতো একটি ডেটাসেটে প্রয়োগ করা এই পদ্ধতির ফলাফল এখানে।

ব্যক্তিত্ব

বামদিকে হিস্টোগ্রামে নমুনা চিত্রিত হয়েছে। রেফারেন্সের জন্য, কালো বক্ররেখা ঘনত্বকে প্লট করে যা থেকে নমুনাটি আঁকানো হয়েছিল। লাল বক্ররেখা নমুনার কে.ডি. প্লট করে (সংকীর্ণ ব্যান্ডউইথ ব্যবহার করে)। (এটি কোনও সমস্যা নয় এমনকি অপ্রত্যাশিতও নয় যে, লাল শিখরগুলি কালো শৃঙ্গগুলির চেয়ে সংক্ষিপ্ত: কে-ডি-কে জিনিসগুলি ছড়িয়ে দেয়, তাই শিখরগুলি ক্ষতিপূরণ দিতে কম হবে))

ডান দিকের হিস্টোগোমে কেডিএর থেকে একটি নমুনা (একই আকারের) চিত্রিত করা হয়েছে কালো এবং লাল বক্ররেখা আগের মতই।

স্পষ্টতই, ঘনত্ব থেকে নমুনার জন্য ব্যবহৃত পদ্ধতিটি কাজ করে। এটি অত্যন্ত চূড়ান্ত: Rনীচের প্রয়োগটি যে কোনও কেডি থেকে প্রতি সেকেন্ডে কয়েক মিলিয়ন মান উৎপন্ন করে। পাইথন বা অন্যান্য ভাষায় পোর্টিংয়ে সহায়তা করার জন্য আমি এটির পক্ষে প্রচুর মন্তব্য করেছি mented স্যাম্পলিং অ্যালগরিদম নিজেই rdensলাইনগুলি সহ ফাংশনে প্রয়োগ করা হয়

rkernel <- function(n) rnorm(n, sd=width) 
sample(x, n, replace=TRUE) + rkernel(n)  

rkernelস্বপক্ষে nকার্নেল ফাংশন থেকে IID নমুনা যখন sampleস্বপক্ষে nতথ্য থেকে প্রতিস্থাপন সঙ্গে নমুনা x। "+" অপারেটর উপাদান দ্বারা নমুনা উপাদানগুলির দুটি অ্যারে যুক্ত করে।


KFKx=(x1,x2,,xn)

Fx^;K(x)=1ni=1nFK(xxi).

Xxi1/niYX+YxX

FX+Y(x)=Pr(X+Yx)=i=1nPr(X+YxX=xi)Pr(X=xi)=i=1nPr(xi+Yx)1n=1ni=1nPr(Yxxi)=1ni=1nFK(xxi)=Fx^;K(x),

যেমন দাবি করা হয়েছে


#
# Define a function to sample from the density.
# This one implements only a Gaussian kernel.
#
rdens <- function(n, density=z, data=x, kernel="gaussian") {
  width <- z$bw                              # Kernel width
  rkernel <- function(n) rnorm(n, sd=width)  # Kernel sampler
  sample(x, n, replace=TRUE) + rkernel(n)    # Here's the entire algorithm
}
#
# Create data.
# `dx` is the density function, used later for plotting.
#
n <- 100
set.seed(17)
x <- c(rnorm(n), rnorm(n, 4, 1/4), rnorm(n, 8, 1/4))
dx <- function(x) (dnorm(x) + dnorm(x, 4, 1/4) + dnorm(x, 8, 1/4))/3
#
# Compute a kernel density estimate.
# It returns a kernel width in $bw as well as $x and $y vectors for plotting.
#
z <- density(x, bw=0.15, kernel="gaussian")
#
# Sample from the KDE.
#
system.time(y <- rdens(3*n, z, x)) # Millions per second
#
# Plot the sample.
#
h.density <- hist(y, breaks=60, plot=FALSE)
#
# Plot the KDE for comparison.
#
h.sample <- hist(x, breaks=h.density$breaks, plot=FALSE)
#
# Display the plots side by side.
#
histograms <- list(Sample=h.sample, Density=h.density)
y.max <- max(h.density$density) * 1.25
par(mfrow=c(1,2))
for (s in names(histograms)) {
  h <- histograms[[s]]
  plot(h, freq=FALSE, ylim=c(0, y.max), col="#f0f0f0", border="Gray",
       main=paste("Histogram of", s))
  curve(dx(x), add=TRUE, col="Black", lwd=2, n=501) # Underlying distribution
  lines(z$x, z$y, col="Red", lwd=2)                 # KDE of data

}
par(mfrow=c(1,1))

হাই @ শুভ্র, আমি আমার কাগজে এই ধারণাটি উদ্ধৃত করতে চাই। আপনার কি কিছু কাগজপত্র রয়েছে যা এর জন্য প্রকাশিত হয়েছে? ধন্যবাদ.
এমবারবিলো

2

আপনি প্রথমে সিডিএফ থেকে উল্টিয়ে নমুনা করেছেন। বিপরীত সিডিএফকে কোয়ান্টাইল ফাংশন বলা হয়; এটি [0,1] থেকে আরভি ডোমেনে ম্যাপিং। তারপরে আপনি শতভাগ হিসাবে র্যান্ডম ইউনিফর্ম আরভিগুলিকে নমুনা দিন এবং সেই বিতরণ থেকে এলোমেলো নমুনা পেতে কোয়ান্টাইল ফাংশনে এগুলি দিন।


2
এটি কঠিন উপায়: প্রশ্নের আমার মন্তব্য দেখুন।
whuber

2
@ ভাল পয়েন্ট। প্রোগ্রামেটিক দিকগুলিতে খুব বেশি শৃঙ্খলাবদ্ধ না হয়ে, আমি ধরেই নিয়েছিলাম যে এই পরিস্থিতিতে আমাদের অবশ্যই একটি সিডিএফের সাথে কাজ করা উচিত। সন্দেহ নেই যে এই জাতীয় ফাংশনটির অভ্যন্তরীণগুলি একটি কার্নেলটি স্মুটেড ঘনত্ব গ্রহণ করে এবং তারপরে এটি একটি সিডিএফ পাওয়ার জন্য সংহত করে। সেই সময়ে বিপরীত রূপান্তর নমুনা ব্যবহার করা সম্ভবত এটি আরও ভাল এবং দ্রুত। তবে, মিশ্রণটি থেকে কেবল ঘনত্ব এবং নমুনা ব্যবহার করার পরামর্শটি আরও ভাল is
অ্যাডমো

@ অ্যাডামো আপনার উত্তরের জন্য আপনাকে ধন্যবাদ। কিন্তু আমার কোডটি সত্যই একই ধারণা অনুসরণ করে আপনি এখানে বলেছিলেন। আমি জানি না কেন ত্রি-মডেল নিদর্শনগুলি পুনরুত্পাদন করা যায় না।
এমবারবিলো

@ অ্যাডামো এখানে আপনার মন্তব্যে "ইন্টার্নাল" শব্দটি "অন্তর" হওয়া উচিত? ধন্যবাদ.
এমবারবিলো

আম্বর, "ইন্টার্নাল" আমার কাছে সঠিক ধারণা দেয়। এই জাতীয় ফাংশনটির জন্য মিশ্রণের ঘনত্বকে সংহত করতে হবে এবং একটি বিপরীতমুখী গঠন করতে হবে: এটি অ্যাডমো ইঙ্গিত হিসাবে একটি অগোছালো, সংখ্যাগত জটিল প্রক্রিয়া, এবং তাই ফাংশনটির মধ্যেই সমাধিস্থ করা হবে - এর "অভ্যন্তরীণ"।
শুক্র

1

এখানে, যারা আর এর চেয়ে মতলবের সাথে বেশি পরিচিত তাদের সহায়তা করতে, আমি whuber দ্বারা বর্ণিত ধারণার অনুসরণ করে মতলব কোডও পোস্ট করতে চাই Here

x = exprnd(3, [300, 1]);
[~, ~, bw] = ksdensity(x, 'kernel', 'normal', 'NUmPoints', 800);

k = 0.25; % control the uncertainty of generated values, the larger the k the greater the uncertainty
mstd = bw*k;
rkernel = mstd*randn(300, 1);
sampleobs = randsample(x, 300, true);
simobs = sampleobs(:) + rkernel(:);

figure(1);
subplot(1,2,1);
hist(x, 50);title('Original sample');
subplot(1,2,2);
hist(simobs, 50);title('Simulated sample');
axis tight;

নিম্নলিখিত ফলাফল: ফলাফল

আমার বোধগম্যতা এবং কোডটিতে যদি কারও কোনও সমস্যা হয় তবে দয়া করে আমাকে বলুন। ধন্যবাদ.


1
সংক্ষেপে, আমি খুঁজে পেয়েছি যে প্রশ্নে আমার কোডটি সঠিক। নিদর্শনটি পুনরুত্পাদন করা যায় না যে পর্যবেক্ষণটি ব্যান্ডউইথের পছন্দের কারণে বেশিরভাগ ক্ষেত্রে।
এমবারবিলো

0

আপনার বাস্তবায়নের খুব কাছাকাছি না দেখে, আমি আইসিডিএফ থেকে আঁকার জন্য আপনার সূচীকরণ পদ্ধতিটি পুরোপুরি পাই না। আমি মনে করি আপনি সিডিএফ থেকে আঁকেন, এটি বিপরীত নয়। আমার বাস্তবায়ন এখানে:

import sys
sys.path.insert(0, './../../../Python/helpers')
import numpy as np
import scipy.stats as stats
from sklearn.neighbors import KernelDensity

def rugplot(axis,x,color='b',label='draws',shape='+',alpha=1):
    axis.plot(x,np.ones(x.shape)*0,'b'+shape,ms=20,label=label,c=color,alpha=alpha);
    #axis.set_ylim([0,max(axis.get_ylim())])

def PDF(x):
    return 0.5*(stats.norm.pdf(x,loc=6,scale=1)+ stats.norm.pdf(x,loc=18,scale=1));

def CDF(x,PDF):
    temp = np.linspace(-10,x,100)
    pdf = PDF(temp);
    return np.trapz(pdf,temp);

def iCDF(p,x,cdf):
    return np.interp(p,cdf,x);

res = 1000;
X = np.linspace(0,24,res);
P = np.linspace(0,1,res)
pdf  = np.array([PDF(x) for x in X]);#attention dont do [ for x in x] because it overrides original x value
cdf  = np.array([CDF(x,PDF) for x in X]);
icdf = [iCDF(p,X,cdf) for p in P];

#draw pdf and cdf
f,(ax1,ax2) = plt.subplots(1,2,figsize=(18,4.5));
ax1.plot(X,pdf, '.-',label = 'pdf');
ax1.plot(X,cdf, '.-',label = 'cdf');
ax1.legend();
ax1.set_title('PDF & CDF')

#draw inverse cdf
ax2.plot(cdf,X,'.-',label  = 'inverse by swapping axis');
ax2.plot(P,icdf,'.-',label = 'inverse computed');
ax2.legend();
ax2.set_title('inverse CDF');

#draw from custom distribution
N = 100;
p_uniform = np.random.uniform(size=N)
x_data  = np.array([iCDF(p,X,cdf) for p in p_uniform]);

#visualize draws
a = plt.figure(figsize=(20,8)).gca();
rugplot(a,x_data);

#histogram
h = np.histogram(x_data,bins=24);
a.hist(x_data,bins=h[1],alpha=0.5,normed=True);

2
আপনার যদি সিডিএফ এফ থাকে তবে এফটি (এক্স) অভিন্ন কিনা তা ttrue হয়। সুতরাং আপনি অভিন্ন বিতরণ থেকে এলোমেলো সংখ্যার বিপরীত সিডিএফ নিয়ে এক্স পাবেন। আমি মনে করি সমস্যাটি হ'ল আপনি যখন কার্নেলের ঘনত্ব তৈরি করছেন তখন বিপরীতটি কীভাবে নির্ধারণ করা যায়।
মাইকেল আর। চেরনিক

আপনার উত্তর করার জন্য আপনাকে ধন্যবাদ। আমি সরাসরি সিডিএফ থেকে নমুনা করিনি। কোডটি দেখায় যে আমি প্রকৃতপক্ষে বিপরীত রূপান্তর নমুনা হিসাবে একই জিনিসটি করেছিলেন did পি = র‌্যান্ড; % এই লাইনটি সংখ্যার সম্ভাব্যতার হিসাবে অভিন্ন র্যান্ডম নম্বর পায় gets [~, আইডিএক্স] = সাজান (অ্যাবস (সিডিএফ (:, 2) - পি)); rndval (i, 1) = cdf (idx (1), 1);% এই দুটি লাইনই ক্রমবর্ধমান সম্ভাবনার সাথে মিলিত পরিমাণ নির্ধারণ করতে হবে
এমবারবিলো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.