রিয়েলটাইম টাইমসারিজ ডেটাতে পিক সিগন্যাল সনাক্তকরণ


242

আপডেট: এখন পর্যন্ত সেরা পারফর্মিং অ্যালগরিদম এটি


এই প্রশ্নটি রিয়েল-টাইম টাইমরিজ ডেটাগুলিতে হঠাৎ শৃঙ্গগুলি সনাক্ত করার জন্য দৃ al় অ্যালগরিদমগুলি অন্বেষণ করে।

নিম্নলিখিত ডেটাসেট বিবেচনা করুন:

p = [1 1 1.1 1 0.9 1 1 1.1 1 0.9 1 1.1 1 1 0.9 1 1 1.1 1 1 1 1 1.1 0.9 1 1.1 1 1 0.9 1, ...
     1.1 1 1 1.1 1 0.8 0.9 1 1.2 0.9 1 1 1.1 1.2 1 1.5 1 3 2 5 3 2 1 1 1 0.9 1 1 3, ... 
     2.6 4 3 3.2 2 1 1 0.8 4 4 2 2.5 1 1 1];

(মতলব ফর্ম্যাট তবে এটি ভাষা সম্পর্কে নয় তবে অ্যালগরিদম সম্পর্কে)

ডেটা প্লট

আপনি পরিষ্কারভাবে দেখতে পাচ্ছেন যে এখানে তিনটি বড় শৃঙ্গ এবং কয়েকটি ছোট শৃঙ্গ রয়েছে। এই ডেটাসেটটি টাইমসারি বিভাগের ডেটাসেটগুলির শ্রেণীর একটি নির্দিষ্ট উদাহরণ যা নিয়ে প্রশ্ন রয়েছে। এই শ্রেণীর ডেটাসেটের দুটি সাধারণ বৈশিষ্ট্য রয়েছে:

  1. একটি সাধারণ গড় সঙ্গে প্রাথমিক শব্দ আছে
  2. বড় বড় ' পিক ' বা ' উচ্চতর ডেটা পয়েন্টস ' রয়েছে যা গোলমাল থেকে উল্লেখযোগ্যভাবে বিচ্যুত হয়।

আসুন নিম্নলিখিতগুলিও ধরে নিই:

  • শিখরের প্রস্থ আগে নির্ধারণ করা যায় না
  • শিখরের উচ্চতা স্পষ্টভাবে এবং উল্লেখযোগ্যভাবে অন্যান্য মান থেকে বিচ্যুত হয়
  • ব্যবহৃত অ্যালগরিদম অবশ্যই রিয়েলটাইম গণনা করতে হবে (সুতরাং প্রতিটি নতুন ডেটাপয়েন্টের সাথে পরিবর্তন করুন)

এইরকম পরিস্থিতির জন্য একটি সীমানা মান তৈরি করা দরকার যা সংকেতকে ট্রিগার করে। তবে সীমানা মান স্থির হতে পারে না এবং একটি অ্যালগরিদমের উপর ভিত্তি করে রিয়েলটাইম নির্ধারণ করতে হবে।


আমার প্রশ্ন: রিয়েলটাইমে এমন থ্রেশহোল্ডগুলি গণনা করার জন্য একটি ভাল অ্যালগরিদম কী? এই ধরনের পরিস্থিতিতে জন্য নির্দিষ্ট অ্যালগরিদম আছে? সর্বাধিক সুপরিচিত অ্যালগরিদম কি?


শক্তিশালী অ্যালগরিদম বা দরকারী অন্তর্দৃষ্টি সমস্ত প্রশংসা করা হয়। (যে কোনও ভাষায় উত্তর দিতে পারে: এটি অ্যালগরিদম সম্পর্কে)


5
সেখানে আবশ্যক প্রয়োজনীয়তা আপনি ইতিমধ্যে দিয়েছি ছাড়াও একটি শিখর হওয়ার জন্য কিছু পরম উচ্চতা প্রয়োজন হবে। অন্যথায়, 13 সময়ে পিকটিকে একটি শীর্ষ হিসাবে বিবেচনা করা উচিত। (সমানভাবে: ভবিষ্যতে যদি শিখরগুলি 1000 বা আরও বেশি হয়ে যায় তবে 25 এবং 35 এ দুটি শিখর শৃঙ্গ হিসাবে বিবেচনা করা উচিত নয় ))
j_random_hacker

আমি রাজী. ধরা যাক এই শিখাগুলি কেবল আমাদের বিবেচনা করা উচিত।
জিন-পল

আপনি ভুল প্রশ্ন জিজ্ঞাসা করা হতে পারে। দেরি না করে আপনি কীভাবে সনাক্ত করতে পারবেন তা জিজ্ঞাসা করার পরিবর্তে, আপনি জিজ্ঞাসা করতে পারেন যে কেবল সময়ের আগে নির্দিষ্ট কিছু দেওয়া না হলে নির্দিষ্ট প্রকারের সিগন্যাল সনাক্ত করা সম্ভব, অথবা প্রদত্ত কিছু দিয়ে কিছু সনাক্ত করার জন্য সিগন্যাল সম্পর্কে কী জানা দরকার বিলম্ব।
হটপাউ 2

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

1
আহ আমি দেখি. আমি কোড ফর্ম এটি আশা করছিলাম না। আমি যদি এই প্রশ্নটি আগে দেখে থাকি তবে সম্ভবত আপনি উত্তরটি খুব দ্রুত পেয়ে যাবেন = ডি। যাইহোক, সেই সময় আমার অ্যাপ্লিকেশনটি হ'ল ফোটোসেন্সরটি পরিবেষ্টিত আলোক উত্স থেকে বাধা আছে কিনা তা সনাক্ত করা (এটি আমাদের চলন্ত গড়ের প্রয়োজন, যেহেতু পরিবেষ্টিত আলোক উত্স সময়ের সাথে ধীরে ধীরে পরিবর্তিত হতে পারে)। আমরা এটিকে এমন একটি গেম হিসাবে তৈরি করেছি যেখানে নির্দিষ্ট প্যাটার্ন অনুসরণ করে আপনার সেন্সরগুলির উপর হাত রাখা উচিত। = ডি
জাস্টহেল্ফ

উত্তর:


334

শক্তিশালী শিখর সনাক্তকরণ অ্যালগরিদম (জেড-স্কোর ব্যবহার করে)

আমি একটি অ্যালগরিদম নিয়ে এসেছি যা এই ধরণের ডেটাসেটের জন্য খুব ভাল কাজ করে। এটি ছড়িয়ে পড়ার মূলনীতির উপর ভিত্তি করে : একটি নতুন ডেটাপয়েন্ট যদি কিছু চলমান গড় থেকে দূরে কোনও নির্দিষ্ট মান সংখ্যার বিচ্যুতি হয় তবে অ্যালগরিদম সংকেত (যাকে জেড-স্কোরও বলা হয় )। অ্যালগরিদম খুব মজবুত কারণ এটি পৃথক চলমান গড় এবং বিচ্যুতি তৈরি করে, যেমন সংকেতগুলি প্রান্তিকিকে দূষিত করে না। ভবিষ্যতের সিগন্যালগুলি পূর্বের সংকেতের পরিমাণ নির্বিশেষে প্রায় একই নির্ভুলতার সাথে চিহ্নিত করা হয়। অ্যালগরিদম 3 ইনপুট নেয়: lag = the lag of the moving window, threshold = the z-score at which the algorithm signalsএবং influence = the influence (between 0 and 1) of new signals on the mean and standard deviation। উদাহরণস্বরূপ, lag5 এর মধ্যে একটি ডেটা মসৃণ করতে শেষ 5 টি পর্যবেক্ষণ ব্যবহার করবে। একজনthreshold৩.৫ এর সংকেত দিবে যদি কোনও ডেটাপয়েন্ট 3.5.৫ স্ট্যান্ডার্ড বিচ্যুতি চলমান থেকে দূরে থাকে। এবং influence0.5 এর একটি সিগন্যাল দেয় যে স্বাভাবিক ডাটাপয়েন্টগুলির প্রভাবের অর্ধেক থাকে। তেমনি, influence0 টির মধ্যে একটি নতুন থ্রোসোল্ড পুনরায় গণনার জন্য সিগন্যালগুলিকে সম্পূর্ণ উপেক্ষা করে। 0 একটি প্রভাব সেইজন্য সবচেয়ে জোরালো বিকল্প (কিন্তু অনুমান stationarity ); প্রভাব বিকল্পটি 1 এ রাখাই কমপক্ষে শক্ত। অ-স্থির তথ্যের জন্য, প্রভাব বিকল্পটি 0 এবং 1 এর মধ্যে কোথাও রাখা উচিত।

এটি নিম্নলিখিত হিসাবে কাজ করে:

সুডোকোড

# Let y be a vector of timeseries data of at least length lag+2
# Let mean() be a function that calculates the mean
# Let std() be a function that calculates the standard deviaton
# Let absolute() be the absolute value function

# Settings (the ones below are examples: choose what is best for your data)
set lag to 5;          # lag 5 for the smoothing functions
set threshold to 3.5;  # 3.5 standard deviations for signal
set influence to 0.5;  # between 0 and 1, where 1 is normal influence, 0.5 is half

# Initialize variables
set signals to vector 0,...,0 of length of y;   # Initialize signal results
set filteredY to y(1),...,y(lag)                # Initialize filtered series
set avgFilter to null;                          # Initialize average filter
set stdFilter to null;                          # Initialize std. filter
set avgFilter(lag) to mean(y(1),...,y(lag));    # Initialize first value
set stdFilter(lag) to std(y(1),...,y(lag));     # Initialize first value

for i=lag+1,...,t do
  if absolute(y(i) - avgFilter(i-1)) > threshold*stdFilter(i-1) then
    if y(i) > avgFilter(i-1) then
      set signals(i) to +1;                     # Positive signal
    else
      set signals(i) to -1;                     # Negative signal
    end
    # Reduce influence of signal
    set filteredY(i) to influence*y(i) + (1-influence)*filteredY(i-1);
  else
    set signals(i) to 0;                        # No signal
    set filteredY(i) to y(i);
  end
  # Adjust the filters
  set avgFilter(i) to mean(filteredY(i-lag),...,filteredY(i));
  set stdFilter(i) to std(filteredY(i-lag),...,filteredY(i));
end

আপনার ডেটার জন্য ভাল পরামিতি নির্বাচন করার জন্য থাম্বের নিয়মগুলি নীচে পাওয়া যাবে।


ডেমো

মজবুত থ্রোহোল্ডিং অ্যালগরিদমের বিক্ষোভ

এই ডেমোর জন্য মতলব কোডটি এখানে পাওয়া যাবে । ডেমোটি ব্যবহার করতে, কেবল এটি চালান এবং উপরের চার্টটিতে ক্লিক করে একটি সময় সিরিজ নিজে তৈরি করুন। অ্যালগোরিদম lagপর্যবেক্ষণের সংখ্যা অঙ্কনের পরে কাজ শুরু করে ।


ফলাফল

মূল প্রশ্নের জন্য, এই অ্যালগরিদম নিম্নলিখিত সেটিংস ব্যবহার করার সময় নিম্নলিখিত আউটপুট দেবে lag = 30, threshold = 5, influence = 0:

থ্রোসোল্ডিং অ্যালগরিদমের উদাহরণ


বিভিন্ন প্রোগ্রামিং ভাষায় বাস্তবায়ন:


অ্যালগরিদমটি কনফিগার করার জন্য থাম্বের বিধি

lag: ল্যাগ প্যারামিটারটি নির্ধারণ করে যে আপনার ডেটা কতটা মসৃণ হবে এবং ডেটাটির দীর্ঘমেয়াদী গড়ের পরিবর্তনে অ্যালগরিদমটি কতটা অভিযোজিত। আপনার ডেটা যত স্থিতিশীল , আপনার তত বেশি ল্যাগ অন্তর্ভুক্ত করা উচিত (এটি অ্যালগোরিদমের দৃust়তা উন্নত করতে হবে)। যদি আপনার ডেটাতে সময়-পরিবর্তিত প্রবণতা থাকে, আপনি অ্যালগরিদমকে এই ট্রেন্ডগুলির সাথে খাপ খাইয়ে নিতে চান তা বিবেচনা করা উচিত। অর্থাৎ, আপনি যদি lag10 এ রাখেন, দীর্ঘমেয়াদী গড়ের কোনও নিয়মতান্ত্রিক পরিবর্তনের সাথে অ্যালগরিদমের ট্রেডহোল্ড সামঞ্জস্য হওয়ার আগে এটি 10 ​​'পিরিয়ডস' নেয়। সুতরাং lagআপনার ডেটাগুলির ট্রেন্ডিং আচরণ এবং আপনি কীভাবে অ্যালগরিদম হতে চান তা অভিযোজিত তার উপর ভিত্তি করে প্যারামিটারটি চয়ন করুন ।

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

threshold: থ্রোসোল্ড প্যারামিটারটি হ'ল উপরের চলমান গড় থেকে স্ট্যান্ডার্ড বিচ্যুতির সংখ্যা যা অ্যালগরিদম একটি নতুন ডেটাপয়েন্টকে সিগন্যাল হিসাবে শ্রেণিবদ্ধ করবে। উদাহরণস্বরূপ, যদি কোনও নতুন ডেটাপয়েন্টটি চলমান গড়ের উপরে above.০ স্ট্যান্ডার্ড বিচ্যুতি হয় এবং থ্রোসোল্ড প্যারামিটারটি 3.5 হিসাবে সেট করা হয় তবে অ্যালগরিদমটি ডেটাপয়েন্টকে সংকেত হিসাবে চিহ্নিত করবে। এই প্যারামিটারটি আপনার প্রত্যাশার কতগুলি সংকেতের ভিত্তিতে সেট করা উচিত। উদাহরণস্বরূপ, যদি আপনার ডেটাটি সাধারণত বিতরণ করা হয় তবে 3.5 এর একটি প্রান্তিক (বা: জেড-স্কোর) 0.00047 ( এই টেবিল থেকে) এর সংকেত সম্ভাবনার সাথে মিলে যায়), যা বোঝায় যে আপনি প্রতি 2128 ডেটাপয়েন্টগুলি (1 / 0.00047) একবার সংকেত আশা করেন। প্রান্তিকরূপে সরাসরি অ্যালগরিদম সংবেদনশীল এবং এর ফলে অ্যালগোরিদম সংকেতগুলি কতবার সংবেদনশীল তা সরাসরি প্রভাবিত করে। আপনার নিজের ডেটা পরীক্ষা করুন এবং একটি বুদ্ধিমান প্রান্তিক স্থিতি নির্ধারণ করুন যা আপনি যখন চাইবেন অ্যালগরিদম সিগন্যাল তৈরি করে (আপনার উদ্দেশ্যটির জন্য একটি ভাল প্রান্তিকের জন্য এখানে কিছু ট্রায়াল-এন্ড-ত্রুটির প্রয়োজন হতে পারে)।


সতর্কতা: উপরের কোডটি সর্বদা এটি চলাকালীন সমস্ত ডেটাপয়েন্টগুলিতে লুপ করে। এই কোডটি প্রয়োগ করার সময়, সিগন্যালের গণনাটিকে আলাদা ফাংশনে (লুপ ছাড়াই) বিভক্ত করার বিষয়টি নিশ্চিত করুন। তারপর যখন একটি নতুন datapoint আসে, আপডেট filteredY, avgFilterএবং stdFilterএকবার। প্রত্যেকবার নতুন ডেটাপয়েন্ট (যেমন উপরের উদাহরণের মতো) থাকলে সমস্ত ডেটার জন্য সংকেতগুলি পুনরায় গণনা করবেন না, এটি চূড়ান্তভাবে অদক্ষ এবং ধীর হয়ে উঠবে!

অ্যালগরিদম সংশোধন করার অন্যান্য উপায় (সম্ভাব্য উন্নতির জন্য) হ'ল:

  1. গড়ের পরিবর্তে মিডিয়ান ব্যবহার করুন
  2. মানক বিচ্যুতির পরিবর্তে এমএডি এর মতো শক্তিশালী মাপকাঠি ব্যবহার করুন
  3. সিগন্যালিং মার্জিন ব্যবহার করুন, যাতে সংকেত খুব বেশি সময় স্যুইচ হয় না
  4. প্রভাব পরামিতিগুলি যেভাবে কাজ করে তা পরিবর্তন করুন
  5. আচরণ আপ এবং নিচে সংকেত ভিন্নভাবে (সামঁজস্যহীন চিকিত্সা)
  6. influenceগড় এবং স্টাডির জন্য পৃথক প্যারামিটার তৈরি করুন ( এই সুইফ্ট অনুবাদে যেমন হয়েছে )

(জানা) এই স্ট্যাক ওভারফ্লো উত্তরের একাডেমিক উদ্ধৃতি:

অ্যালগরিদম ব্যবহার করে অন্যান্য কাজ

এই অ্যালগরিদমের অন্যান্য অ্যাপ্লিকেশন

অন্যান্য শিখর সনাক্তকরণ অ্যালগরিদমের লিঙ্কগুলি


আপনি যদি এই ফাংশনটি কোথাও ব্যবহার করেন তবে দয়া করে আমাকে বা এই উত্তরটি জমা দিন। আপনি এই অ্যালগরিদম সংক্রান্ত কোন প্রশ্ন থাকে, তাহলে নিচের মন্তব্য পোষ্ট বা আমার কাছে পৌঁছান লিঙ্কডইন



মুভিংস্টেডের লিঙ্কটি নষ্ট হয়ে গেছে, তবে আপনি এখানে এর
ফিলিইডা

@ রিসরা ফাংশনটি সক্রিয় করে পুনর্লিখনের পরে চলমান মান বিচ্যুতির দরকার নেই। এটি এখন সরল অন্তর্নির্মিত মতলব ফাংশনগুলির সাথে ব্যবহার করা যেতে পারে :)
জিন-পল

1
আমি কিছু অ্যাক্সিলোমিটার ডেটার জন্য ম্যাটলব কোডটি চেষ্টা করছি তবে কোনও কারণে thresholdগ্রাফটি ডেটাতে 20 অবধি বড় স্পাইকের পরে কেবল একটি সমতল সবুজ রেখায় পরিণত হয়, এবং এটি গ্রাফের বাকি অংশের মতো থাকে ... যদি আমি সাইক সরিয়েছি, এটি ঘটে না তাই এটি ডেটা স্পাইকের কারণে বলে মনে হচ্ছে। কি হতে পারে কোন ধারণা? আমি মতলব এ একজন নবাগত, তাই আমি এটা বুঝতে পারি না ...
ম্যাগনাস ডব্লিউ

@ ব্যাডক্যাশ আপনি কি উদাহরণ (ডেটা সহ) সরবরাহ করতে পারেন? সম্ভবত এখানে নিজের প্রশ্ন জিজ্ঞাসা করুন এবং আমাকে লিঙ্কটি বলুন?
জিন-পল

2
এই আলগো উন্নত করার বিভিন্ন উপায় আছে, তাই সৃজনশীল হোন (বিভিন্ন চিকিত্সা আপ / ডাউন; গড়ের পরিবর্তে মিডিয়ান; মজবুত স্ট্যান্ড; মেমরি-দক্ষ ফাংশন হিসাবে কোডটি লিখুন; প্রান্তিকের মার্জিন তাই সংকেত খুব বেশি পরিবর্তন হয় না ইত্যাদি ইত্যাদি) ।)।
জিন পল

41

এখানে স্মুটেড জেড-স্কোর অ্যালগরিদমের Python/ numpyবাস্তবায়ন ( উপরে উত্তর দেখুন )। আপনি এখানে সংক্ষেপে খুঁজে পেতে পারেন ।

#!/usr/bin/env python
# Implementation of algorithm from https://stackoverflow.com/a/22640362/6029703
import numpy as np
import pylab

def thresholding_algo(y, lag, threshold, influence):
    signals = np.zeros(len(y))
    filteredY = np.array(y)
    avgFilter = [0]*len(y)
    stdFilter = [0]*len(y)
    avgFilter[lag - 1] = np.mean(y[0:lag])
    stdFilter[lag - 1] = np.std(y[0:lag])
    for i in range(lag, len(y)):
        if abs(y[i] - avgFilter[i-1]) > threshold * stdFilter [i-1]:
            if y[i] > avgFilter[i-1]:
                signals[i] = 1
            else:
                signals[i] = -1

            filteredY[i] = influence * y[i] + (1 - influence) * filteredY[i-1]
            avgFilter[i] = np.mean(filteredY[(i-lag+1):i+1])
            stdFilter[i] = np.std(filteredY[(i-lag+1):i+1])
        else:
            signals[i] = 0
            filteredY[i] = y[i]
            avgFilter[i] = np.mean(filteredY[(i-lag+1):i+1])
            stdFilter[i] = np.std(filteredY[(i-lag+1):i+1])

    return dict(signals = np.asarray(signals),
                avgFilter = np.asarray(avgFilter),
                stdFilter = np.asarray(stdFilter))

নীচে একই ডেটাसेटের পরীক্ষা দেওয়া যা R/ এর মূল উত্তরের মতো একই প্লট দেয়Matlab

# Data
y = np.array([1,1,1.1,1,0.9,1,1,1.1,1,0.9,1,1.1,1,1,0.9,1,1,1.1,1,1,1,1,1.1,0.9,1,1.1,1,1,0.9,
       1,1.1,1,1,1.1,1,0.8,0.9,1,1.2,0.9,1,1,1.1,1.2,1,1.5,1,3,2,5,3,2,1,1,1,0.9,1,1,3,
       2.6,4,3,3.2,2,1,1,0.8,4,4,2,2.5,1,1,1])

# Settings: lag = 30, threshold = 5, influence = 0
lag = 30
threshold = 5
influence = 0

# Run algo with settings from above
result = thresholding_algo(y, lag=lag, threshold=threshold, influence=influence)

# Plot result
pylab.subplot(211)
pylab.plot(np.arange(1, len(y)+1), y)

pylab.plot(np.arange(1, len(y)+1),
           result["avgFilter"], color="cyan", lw=2)

pylab.plot(np.arange(1, len(y)+1),
           result["avgFilter"] + threshold * result["stdFilter"], color="green", lw=2)

pylab.plot(np.arange(1, len(y)+1),
           result["avgFilter"] - threshold * result["stdFilter"], color="green", lw=2)

pylab.subplot(212)
pylab.step(np.arange(1, len(y)+1), result["signals"], color="red", lw=2)
pylab.ylim(-1.5, 1.5)
pylab.show()

এখানে 'y' আসলে সংকেত এবং 'সিগন্যাল' হ'ল ডেটা পয়েন্টের সেট, আমি কি বুঝতে পারছি?
TheTank

1
@ yদ্য ট্যাঙ্ক হ'ল ডেটা অ্যারে যা আপনি পাস করেন signalsতা হ'ল +1বা -1আউটপুট অ্যারে যা প্রতিটি ডেটাপয়েন্টের জন্য নির্দেশ করে y[i]যে সেই ডেটাপয়েন্ট আপনি যে সেটিংস ব্যবহার করছেন সেটিকে দেওয়া "উল্লেখযোগ্য শীর্ষ" কিনা।
জিন-পল

23

একটি পদ্ধতি হ'ল নিম্নলিখিত পর্যবেক্ষণের ভিত্তিতে শৃঙ্গগুলি সনাক্ত করা:

  • টাইম টি শীর্ষস্থানীয় হয় যদি (y (t)> y (t-1)) && (y (t)> y (t + 1))

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

  • শিখর যদি (y (t) - y (t-dt)> m) && (y (t) - y (t + dt)> মি)

যেখানে dt এবং m সময় এবং বিলম্বের বিরুদ্ধে সংবেদনশীলতা নিয়ন্ত্রণ করার জন্য প্যারামিটার

আপনি উল্লিখিত অ্যালগরিদমের সাথে এটি পান: এখানে চিত্র বর্ণনা লিখুন

পাইথনে প্লটটি পুনরুত্পাদন করার কোড এখানে:

import numpy as np
import matplotlib.pyplot as plt
input = np.array([ 1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1. ,  1.1,  1. ,  0.8,  0.9,
    1. ,  1.2,  0.9,  1. ,  1. ,  1.1,  1.2,  1. ,  1.5,  1. ,  3. ,
    2. ,  5. ,  3. ,  2. ,  1. ,  1. ,  1. ,  0.9,  1. ,  1. ,  3. ,
    2.6,  4. ,  3. ,  3.2,  2. ,  1. ,  1. ,  1. ,  1. ,  1. ])
signal = (input > np.roll(input,1)) & (input > np.roll(input,-1))
plt.plot(input)
plt.plot(signal.nonzero()[0], input[signal], 'ro')
plt.show()

সেট করে m = 0.5, আপনি কেবল একটি মিথ্যা পজিটিভ সহ একটি ক্লিনার সংকেত পেতে পারেন: এখানে চিত্র বর্ণনা লিখুন


পূর্ববর্তী = আরও ভাল তাই সমস্ত শিখর উল্লেখযোগ্য। ধন্যবাদ! খুব ঠান্ডা!
জিন-পল

সংবেদনশীলতা পরিবর্তন করতে আমি কীভাবে যাব?
জিন-পল

আমি দুটি পদ্ধতির কথা ভাবতে পারি: 1: একটি বড় মানকে এম সেট করুন যাতে কেবল বৃহত্তর শৃঙ্গগুলি সনাক্ত হয়। 2: y (t) - y (t-dt) (এবং y (t) - y (t + dt)) গণনার পরিবর্তে আপনি t-dt থেকে t (এবং t + t + dt) তে সংহত হন।
আহা

2
অন্যান্য 7 টি শিখরকে আপনি কোন মানদণ্ডে প্রত্যাখ্যান করছেন?
হটপাউ 2

4
সমতল শৃঙ্গগুলির সাথে সমস্যা আছে, যেহেতু আপনি যা করেন তা মূলত 1-ডি প্রান্ত সনাক্তকরণ ([1 0 -1] দিয়ে সিগন্যালকে বোঝানোর মতো)
বেন ২

18

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


1
আপনার উত্তর আমাকে এই নিবন্ধটিতে এবং এই উত্তরটি দেয় যা আমাকে আমার প্রয়োগের জন্য একটি ভাল অ্যালগরিদম তৈরি করতে সহায়তা করবে। ধন্যবাদ!
জিন-পল

@ ক্লিন আপনি কীভাবে ওয়েবেলেট কফের জিরো-ক্রসিংগুলি গণনা করতে পারবেন তা ব্যাখ্যা করতে পারবেন, যেহেতু তারা মূল সময় সিরিজের একই সময় স্কেলটিতে নেই। এই ব্যবহারের উপর কোন রেফারেন্স?
horaceT

11

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

মূল জেড-স্কোর অ্যালগরিদমের শীর্ষে স্থাপন করে, আমরা বিপরীত ফিল্টারিং দ্বারা এই সমস্যাটি সমাধান করার একটি উপায় নিয়ে এসেছি। পরিবর্তিত অ্যালগরিদম এবং টিভি বাণিজ্যিক ট্র্যাফিক এ্যাট্রিবিউশনে এর প্রয়োগ সম্পর্কিত বিবরণ আমাদের টিম ব্লগে পোস্ট করা হয়েছে ।

এখানে চিত্র বর্ণনা লিখুন


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

10

গণনা টপোলজিতে অবিচ্ছিন্ন হোমোলজির ধারণাটি একটি দক্ষ - দ্রুত বাছাইয়ের সংখ্যা - সমাধান হিসাবে নিয়ে যায়। এটি কেবল শৃঙ্গগুলি সনাক্ত করে না, এটি প্রাকৃতিক উপায়ে শিখরগুলির "তাত্পর্য" পরিমাণে প্রমাণিত করে যা আপনাকে আপনার জন্য তাত্পর্যপূর্ণ শিখরগুলি নির্বাচন করতে দেয়।

অ্যালগরিদমের সারাংশ। একটি 1-মাত্রিক সেটিংয়ে (সময় সিরিজ, বাস্তব-মূল্যবান সংকেত) অ্যালগরিদমটি সহজেই নিম্নলিখিত চিত্র দ্বারা বর্ণনা করা যায়:

সর্বাধিক অবিরাম চূড়া

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

দক্ষতা. লিনিয়ার সময়ে চলমান এমন বাস্তবায়ন খুঁজে পাওয়া খুব কঠিন নয় - কার্যকারিতার মানগুলি সাজানোর পরে বাস্তবে এটি একটি একক, সরল লুপ। সুতরাং এই বাস্তবায়নটি বাস্তবে দ্রুত হওয়া উচিত এবং এটি খুব সহজেই কার্যকর করা উচিত।

তথ্যসূত্র। সম্পূর্ণ গল্পের একটি রচনা আপ এবং ধ্রুবক হোমোলজি থেকে অনুপ্রেরণার উল্লেখ (গণ্য বীজগণিত টপোলজির ক্ষেত্র) এখানে পাওয়া যাবে: https://www.sthu.org/blog/13-perstopology-peakdetection/index.html


এই অ্যালগরিদম উদাহরণস্বরূপ, scipy.signal.find_peaks এর চেয়ে অনেক দ্রুত এবং আরও নির্ভুল। 1053896 ডেটা পয়েন্ট সহ একটি "আসল" টাইম-সিরিজের জন্য, এটি 137516 শিখর (13%) সনাক্ত করেছে। শৃঙ্গগুলির ক্রম (প্রথম উল্লেখযোগ্যভাবে) সর্বাধিক তাৎপর্যপূর্ণ চূড়াগুলি উত্তোলনের অনুমতি দেয়। এটি প্রতিটি শিখরের শুরু, শীর্ষ এবং শেষ সরবরাহ করে। শোরগোলের ডেটা দিয়ে ভাল কাজ করে।
বিন

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

9

টাইম-সিরিজে পিক সনাক্তকরণের জন্য সরল অ্যালগরিদমে জি এইচ পলশিকার আরও একটি অ্যালগরিদম পেয়েছেন ।

অ্যালগরিদম এভাবে চলে:

algorithm peak1 // one peak detection algorithms that uses peak function S1 

input T = x1, x2, …, xN, N // input time-series of N points 
input k // window size around the peak 
input h // typically 1 <= h <= 3 
output O // set of peaks detected in T 

begin 
O = empty set // initially empty 

    for (i = 1; i < n; i++) do
        // compute peak function value for each of the N points in T 
        a[i] = S1(k,i,xi,T); 
    end for 

    Compute the mean m' and standard deviation s' of all positive values in array a; 

    for (i = 1; i < n; i++) do // remove local peaks which are “small” in global context 
        if (a[i] > 0 && (a[i] – m') >( h * s')) then O = O + {xi}; 
        end if 
    end for 

    Order peaks in O in terms of increasing index in T 

    // retain only one peak out of any set of peaks within distance k of each other 

    for every adjacent pair of peaks xi and xj in O do 
        if |j – i| <= k then remove the smaller value of {xi, xj} from O 
        end if 
    end for 
end

সুবিধাদি

  • কাগজটি শিখর সনাক্তকরণের জন্য 5 টি পৃথক অ্যালগোরিদম সরবরাহ করে
  • অ্যালগরিদমগুলি কাঁচা সময়-সিরিজের ডেটাতে কাজ করে (কোনও মসৃণ প্রয়োজন নেই)

অসুবিধেও

  • আগে নির্ধারণ করা kএবং hআগেই নির্ধারণ করা কঠিন
  • পিকগুলি সমতল হতে পারে না (আমার পরীক্ষার ডেটাতে তৃতীয় শীর্ষের মতো)

উদাহরণ:

এখানে চিত্র বর্ণনা লিখুন


আসলে আকর্ষণীয় কাগজ। S4 তার মতামত ব্যবহার করার জন্য একটি ভাল ফাংশন বলে মনে হচ্ছে। তবে আরও গুরুত্বপূর্ণ বিষয়টি স্পষ্ট করা যখন k <i <এন কে সত্য নয়। আই = 0 এর জন্য কীভাবে কোনও এস ফাংশন এস 1 (এস 2, ..) সংজ্ঞায়িত করবে আমি প্রথমটি 2 দ্বারা বিভক্ত হয়নি এবং প্রথম অপারেন্ডকে উপেক্ষা করেছি এবং প্রতিটি অন্যান্য জন্য আমি উভয় অপারেশন অন্তর্ভুক্ত করেছি তবে i <= k এর জন্য বামদিকে কম অপারেশন ছিল তারপরে ডানদিকে
ড্যানিয়েলস_পা

8

এখানে গোলাংয়ে স্মুটেড জেড-স্কোর অ্যালগরিদম (উপরে) প্রয়োগ করা হচ্ছে। এটি এক ধরণের []int16(পিসিএম 16 ​​বিট স্যাম্পল) ধরে umes আপনি এখানে একটি টুকরো খুঁজে পেতে পারেন ।

/*
Settings (the ones below are examples: choose what is best for your data)
set lag to 5;          # lag 5 for the smoothing functions
set threshold to 3.5;  # 3.5 standard deviations for signal
set influence to 0.5;  # between 0 and 1, where 1 is normal influence, 0.5 is half
*/

// ZScore on 16bit WAV samples
func ZScore(samples []int16, lag int, threshold float64, influence float64) (signals []int16) {
    //lag := 20
    //threshold := 3.5
    //influence := 0.5

    signals = make([]int16, len(samples))
    filteredY := make([]int16, len(samples))
    for i, sample := range samples[0:lag] {
        filteredY[i] = sample
    }
    avgFilter := make([]int16, len(samples))
    stdFilter := make([]int16, len(samples))

    avgFilter[lag] = Average(samples[0:lag])
    stdFilter[lag] = Std(samples[0:lag])

    for i := lag + 1; i < len(samples); i++ {

        f := float64(samples[i])

        if float64(Abs(samples[i]-avgFilter[i-1])) > threshold*float64(stdFilter[i-1]) {
            if samples[i] > avgFilter[i-1] {
                signals[i] = 1
            } else {
                signals[i] = -1
            }
            filteredY[i] = int16(influence*f + (1-influence)*float64(filteredY[i-1]))
            avgFilter[i] = Average(filteredY[(i - lag):i])
            stdFilter[i] = Std(filteredY[(i - lag):i])
        } else {
            signals[i] = 0
            filteredY[i] = samples[i]
            avgFilter[i] = Average(filteredY[(i - lag):i])
            stdFilter[i] = Std(filteredY[(i - lag):i])
        }
    }

    return
}

// Average a chunk of values
func Average(chunk []int16) (avg int16) {
    var sum int64
    for _, sample := range chunk {
        if sample < 0 {
            sample *= -1
        }
        sum += int64(sample)
    }
    return int16(sum / int64(len(chunk)))
}

@ জিন-পল আমি পুরোপুরি নিশ্চিত নই যে সবকিছু ঠিক আছে, তাই বাগ থাকতে পারে।
শিওনক্রস

1
আপনি কি মতলব / আর থেকে ডেমো উদাহরণ আউটপুট প্রতিলিপি চেষ্টা করেছেন? এটি মানের একটি ভাল নিশ্চিতকরণ হওয়া উচিত।
জিন পল

7

এই উত্তর থেকে স্মুথড জেড-স্কোর অ্যালগরিদমের সি ++ বাস্তবায়ন এখানে

std::vector<int> smoothedZScore(std::vector<float> input)
{   
    //lag 5 for the smoothing functions
    int lag = 5;
    //3.5 standard deviations for signal
    float threshold = 3.5;
    //between 0 and 1, where 1 is normal influence, 0.5 is half
    float influence = .5;

    if (input.size() <= lag + 2)
    {
        std::vector<int> emptyVec;
        return emptyVec;
    }

    //Initialise variables
    std::vector<int> signals(input.size(), 0.0);
    std::vector<float> filteredY(input.size(), 0.0);
    std::vector<float> avgFilter(input.size(), 0.0);
    std::vector<float> stdFilter(input.size(), 0.0);
    std::vector<float> subVecStart(input.begin(), input.begin() + lag);
    avgFilter[lag] = mean(subVecStart);
    stdFilter[lag] = stdDev(subVecStart);

    for (size_t i = lag + 1; i < input.size(); i++)
    {
        if (std::abs(input[i] - avgFilter[i - 1]) > threshold * stdFilter[i - 1])
        {
            if (input[i] > avgFilter[i - 1])
            {
                signals[i] = 1; //# Positive signal
            }
            else
            {
                signals[i] = -1; //# Negative signal
            }
            //Make influence lower
            filteredY[i] = influence* input[i] + (1 - influence) * filteredY[i - 1];
        }
        else
        {
            signals[i] = 0; //# No signal
            filteredY[i] = input[i];
        }
        //Adjust the filters
        std::vector<float> subVec(filteredY.begin() + i - lag, filteredY.begin() + i);
        avgFilter[i] = mean(subVec);
        stdFilter[i] = stdDev(subVec);
    }
    return signals;
}

2
ক্যাভেট: এই বাস্তবায়নটি গড় এবং মানক বিচ্যুতি গণনা করার জন্য আসলে কোনও পদ্ধতি সরবরাহ করে না। সি ++ 11, একটি সহজ পদ্ধতি এখানে পাওয়া যাবে: stackoverflow.com/a/12405793/3250829
rayryeng

6

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


কলম্যান ফিল্টার আকর্ষণীয়, তবে আমি আমার উদ্দেশ্যটির জন্য একটি প্রযোজ্য অ্যালগরিদম খুঁজে পাচ্ছি না। যদিও আমি উত্তরটির খুব প্রশংসা করি এবং আমি এ্যালগরিদমের কোনওটি থেকে শিখতে পারি কিনা তা দেখার জন্য আমি এটির মতো কয়েকটি শীর্ষ সনাক্তকরণের কাগজগুলি সন্ধান করব । ধন্যবাদ!
জিন-পল 21

6

সি ++ বাস্তবায়ন

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <cmath>
#include <iterator>
#include <numeric>

using namespace std;

typedef long double ld;
typedef unsigned int uint;
typedef std::vector<ld>::iterator vec_iter_ld;

/**
 * Overriding the ostream operator for pretty printing vectors.
 */
template<typename T>
std::ostream &operator<<(std::ostream &os, std::vector<T> vec) {
    os << "[";
    if (vec.size() != 0) {
        std::copy(vec.begin(), vec.end() - 1, std::ostream_iterator<T>(os, " "));
        os << vec.back();
    }
    os << "]";
    return os;
}

/**
 * This class calculates mean and standard deviation of a subvector.
 * This is basically stats computation of a subvector of a window size qual to "lag".
 */
class VectorStats {
public:
    /**
     * Constructor for VectorStats class.
     *
     * @param start - This is the iterator position of the start of the window,
     * @param end   - This is the iterator position of the end of the window,
     */
    VectorStats(vec_iter_ld start, vec_iter_ld end) {
        this->start = start;
        this->end = end;
        this->compute();
    }

    /**
     * This method calculates the mean and standard deviation using STL function.
     * This is the Two-Pass implementation of the Mean & Variance calculation.
     */
    void compute() {
        ld sum = std::accumulate(start, end, 0.0);
        uint slice_size = std::distance(start, end);
        ld mean = sum / slice_size;
        std::vector<ld> diff(slice_size);
        std::transform(start, end, diff.begin(), [mean](ld x) { return x - mean; });
        ld sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
        ld std_dev = std::sqrt(sq_sum / slice_size);

        this->m1 = mean;
        this->m2 = std_dev;
    }

    ld mean() {
        return m1;
    }

    ld standard_deviation() {
        return m2;
    }

private:
    vec_iter_ld start;
    vec_iter_ld end;
    ld m1;
    ld m2;
};

/**
 * This is the implementation of the Smoothed Z-Score Algorithm.
 * This is direction translation of https://stackoverflow.com/a/22640362/1461896.
 *
 * @param input - input signal
 * @param lag - the lag of the moving window
 * @param threshold - the z-score at which the algorithm signals
 * @param influence - the influence (between 0 and 1) of new signals on the mean and standard deviation
 * @return a hashmap containing the filtered signal and corresponding mean and standard deviation.
 */
unordered_map<string, vector<ld>> z_score_thresholding(vector<ld> input, int lag, ld threshold, ld influence) {
    unordered_map<string, vector<ld>> output;

    uint n = (uint) input.size();
    vector<ld> signals(input.size());
    vector<ld> filtered_input(input.begin(), input.end());
    vector<ld> filtered_mean(input.size());
    vector<ld> filtered_stddev(input.size());

    VectorStats lag_subvector_stats(input.begin(), input.begin() + lag);
    filtered_mean[lag - 1] = lag_subvector_stats.mean();
    filtered_stddev[lag - 1] = lag_subvector_stats.standard_deviation();

    for (int i = lag; i < n; i++) {
        if (abs(input[i] - filtered_mean[i - 1]) > threshold * filtered_stddev[i - 1]) {
            signals[i] = (input[i] > filtered_mean[i - 1]) ? 1.0 : -1.0;
            filtered_input[i] = influence * input[i] + (1 - influence) * filtered_input[i - 1];
        } else {
            signals[i] = 0.0;
            filtered_input[i] = input[i];
        }
        VectorStats lag_subvector_stats(filtered_input.begin() + (i - lag), filtered_input.begin() + i);
        filtered_mean[i] = lag_subvector_stats.mean();
        filtered_stddev[i] = lag_subvector_stats.standard_deviation();
    }

    output["signals"] = signals;
    output["filtered_mean"] = filtered_mean;
    output["filtered_stddev"] = filtered_stddev;

    return output;
};

int main() {
    vector<ld> input = {1.0, 1.0, 1.1, 1.0, 0.9, 1.0, 1.0, 1.1, 1.0, 0.9, 1.0, 1.1, 1.0, 1.0, 0.9, 1.0, 1.0, 1.1, 1.0,
                        1.0, 1.0, 1.0, 1.1, 0.9, 1.0, 1.1, 1.0, 1.0, 0.9, 1.0, 1.1, 1.0, 1.0, 1.1, 1.0, 0.8, 0.9, 1.0,
                        1.2, 0.9, 1.0, 1.0, 1.1, 1.2, 1.0, 1.5, 1.0, 3.0, 2.0, 5.0, 3.0, 2.0, 1.0, 1.0, 1.0, 0.9, 1.0,
                        1.0, 3.0, 2.6, 4.0, 3.0, 3.2, 2.0, 1.0, 1.0, 0.8, 4.0, 4.0, 2.0, 2.5, 1.0, 1.0, 1.0};

    int lag = 30;
    ld threshold = 5.0;
    ld influence = 0.0;
    unordered_map<string, vector<ld>> output = z_score_thresholding(input, lag, threshold, influence);
    cout << output["signals"] << endl;
}

6

@ জিন-পলের প্রস্তাবিত সমাধান থেকে অনুসরণ করে, আমি সি # তে তার অ্যালগরিদম প্রয়োগ করেছি

public class ZScoreOutput
{
    public List<double> input;
    public List<int> signals;
    public List<double> avgFilter;
    public List<double> filtered_stddev;
}

public static class ZScore
{
    public static ZScoreOutput StartAlgo(List<double> input, int lag, double threshold, double influence)
    {
        // init variables!
        int[] signals = new int[input.Count];
        double[] filteredY = new List<double>(input).ToArray();
        double[] avgFilter = new double[input.Count];
        double[] stdFilter = new double[input.Count];

        var initialWindow = new List<double>(filteredY).Skip(0).Take(lag).ToList();

        avgFilter[lag - 1] = Mean(initialWindow);
        stdFilter[lag - 1] = StdDev(initialWindow);

        for (int i = lag; i < input.Count; i++)
        {
            if (Math.Abs(input[i] - avgFilter[i - 1]) > threshold * stdFilter[i - 1])
            {
                signals[i] = (input[i] > avgFilter[i - 1]) ? 1 : -1;
                filteredY[i] = influence * input[i] + (1 - influence) * filteredY[i - 1];
            }
            else
            {
                signals[i] = 0;
                filteredY[i] = input[i];
            }

            // Update rolling average and deviation
            var slidingWindow = new List<double>(filteredY).Skip(i - lag).Take(lag+1).ToList();

            var tmpMean = Mean(slidingWindow);
            var tmpStdDev = StdDev(slidingWindow);

            avgFilter[i] = Mean(slidingWindow);
            stdFilter[i] = StdDev(slidingWindow);
        }

        // Copy to convenience class 
        var result = new ZScoreOutput();
        result.input = input;
        result.avgFilter       = new List<double>(avgFilter);
        result.signals         = new List<int>(signals);
        result.filtered_stddev = new List<double>(stdFilter);

        return result;
    }

    private static double Mean(List<double> list)
    {
        // Simple helper function! 
        return list.Average();
    }

    private static double StdDev(List<double> values)
    {
        double ret = 0;
        if (values.Count() > 0)
        {
            double avg = values.Average();
            double sum = values.Sum(d => Math.Pow(d - avg, 2));
            ret = Math.Sqrt((sum) / (values.Count() - 1));
        }
        return ret;
    }
}

ব্যবহারের উদাহরণ:

var input = new List<double> {1.0, 1.0, 1.1, 1.0, 0.9, 1.0, 1.0, 1.1, 1.0, 0.9, 1.0,
    1.1, 1.0, 1.0, 0.9, 1.0, 1.0, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 0.9, 1.0, 1.1, 1.0, 1.0, 0.9,
    1.0, 1.1, 1.0, 1.0, 1.1, 1.0, 0.8, 0.9, 1.0, 1.2, 0.9, 1.0, 1.0, 1.1, 1.2, 1.0, 1.5, 1.0,
    3.0, 2.0, 5.0, 3.0, 2.0, 1.0, 1.0, 1.0, 0.9, 1.0, 1.0, 3.0, 2.6, 4.0, 3.0, 3.2, 2.0, 1.0,
    1.0, 0.8, 4.0, 4.0, 2.0, 2.5, 1.0, 1.0, 1.0};

int lag = 30;
double threshold = 5.0;
double influence = 0.0;

var output = ZScore.StartAlgo(input, lag, threshold, influence);

1
হেই @ জিন পল চিয়ার্স। হ্যাঁ, আমি আপনার আর সংস্করণের বিপরীতে আউটপুটটি মেলে তা নিশ্চিত করার জন্য পরীক্ষা করেছি। এই সমস্যার সমাধানের জন্য আপনাকে আবারও ধন্যবাদ।
ওশেন এয়ারড্রপ

হাই, আমি মনে করি যে কোডটিতে একটি ত্রুটি আছে, স্ট্যান্ডডেভ পদ্ধতিতে আপনি মান গ্রহণ করেন C গণনা () - 1, সেখানে -1 নির্ভর করা উচিত? আমি মনে করি আপনি আইটেমের সংখ্যা চাইবেন এবং এটিই আপনি মানগুলি থেকে পান ount গণনা ()।
ভিক্টর

1
হুম .. ভাল জায়গা। যদিও আমি প্রথমে সি # এ অ্যালগরিদমটি পোর্ট করেছি, তবে আমি কখনই এটি ব্যবহার করে শেষ করি না। আমি সম্ভবত সেই পুরো ফাংশনটির বদলে নুগেট লাইব্রেরি ম্যাথনেটের কল দিয়েছিলাম। "ইনস্টল-প্যাকেজ ম্যাথনেট.নুমারিকস" এটি পপুলেশনস স্ট্যান্ডার্ডডাইভেশন () এবং স্ট্যান্ডার্ডডাইভেশন () এর প্রাক-বিল্ট ফাংশন রয়েছে; যেমন। var জনসংখ্যাসটিডেভ = নতুন তালিকা <ডাবল> (1,2,3,4)। জনসংখ্যা স্ট্যান্ডার্ডডাইভেশন (); var saltStdDev = নতুন তালিকা <ডাবল> (1,2,3,4)। স্ট্যান্ডার্ডডাইভেশন ();
ওশান এয়ারড্রপ

6

অরডুইনো মাইক্রোকন্ট্রোলারের অ্যাকসিলোমিটার রিডিং গ্রহণ করতে এবং কোনও প্রভাবের দিকটি বাম বা ডান দিক থেকে এসেছে কিনা তা নির্ধারণ করার জন্য @ জিন-পলের স্মুটেড জেড স্কোরের সি প্রয়োগকারীটি এখানে রয়েছে । এটি সত্যিই দুর্দান্ত সঞ্চালন করে যেহেতু এই ডিভাইসটি একটি বাউন্সড সিগন্যাল দেয়। ডিভাইস থেকে এই শীর্ষ সনাক্তকরণ অ্যালগরিদমের এই ইনপুটটি এখানে রয়েছে - ডান থেকে একটি প্রভাব এবং বাম দিক থেকে প্রভাব দেখাচ্ছে showing আপনি প্রাথমিক স্পাইকটি দেখতে পাবেন তারপরে সেন্সরের দোলনা।

এখানে চিত্র বর্ণনা লিখুন

#include <stdio.h>
#include <math.h>
#include <string.h>


#define SAMPLE_LENGTH 1000

float stddev(float data[], int len);
float mean(float data[], int len);
void thresholding(float y[], int signals[], int lag, float threshold, float influence);


void thresholding(float y[], int signals[], int lag, float threshold, float influence) {
    memset(signals, 0, sizeof(float) * SAMPLE_LENGTH);
    float filteredY[SAMPLE_LENGTH];
    memcpy(filteredY, y, sizeof(float) * SAMPLE_LENGTH);
    float avgFilter[SAMPLE_LENGTH];
    float stdFilter[SAMPLE_LENGTH];

    avgFilter[lag - 1] = mean(y, lag);
    stdFilter[lag - 1] = stddev(y, lag);

    for (int i = lag; i < SAMPLE_LENGTH; i++) {
        if (fabsf(y[i] - avgFilter[i-1]) > threshold * stdFilter[i-1]) {
            if (y[i] > avgFilter[i-1]) {
                signals[i] = 1;
            } else {
                signals[i] = -1;
            }
            filteredY[i] = influence * y[i] + (1 - influence) * filteredY[i-1];
        } else {
            signals[i] = 0;
        }
        avgFilter[i] = mean(filteredY + i-lag, lag);
        stdFilter[i] = stddev(filteredY + i-lag, lag);
    }
}

float mean(float data[], int len) {
    float sum = 0.0, mean = 0.0;

    int i;
    for(i=0; i<len; ++i) {
        sum += data[i];
    }

    mean = sum/len;
    return mean;


}

float stddev(float data[], int len) {
    float the_mean = mean(data, len);
    float standardDeviation = 0.0;

    int i;
    for(i=0; i<len; ++i) {
        standardDeviation += pow(data[i] - the_mean, 2);
    }

    return sqrt(standardDeviation/len);
}

int main() {
    printf("Hello, World!\n");
    int lag = 100;
    float threshold = 5;
    float influence = 0;
    float y[]=  {1,1,1.1,1,0.9,1,1,1.1,1,0.9,1,1.1,1,1,0.9,1,1,1.1,1,1,1,1,1.1,0.9,1,1.1,1,1,0.9,
  ....
1,1.1,1,1,1.1,1,0.8,0.9,1,1.2,0.9,1,1,1.1,1.2,1,1.5,1,3,2,5,3,2,1,1,1,0.9,1,1,3,       2.6,4,3,3.2,2,1,1,0.8,4,4,2,2.5,1,1,1,1.2,1,1.5,1,3,2,5,3,2,1,1,1,0.9,1,1,3,
       2.6,4,3,3.2,2,1,1,0.8,4,4,2,2.5,1,1,1}

    int signal[SAMPLE_LENGTH];

    thresholding(y, signal,  lag, threshold, influence);

    return 0;
}

তার ফলাফল = 0 এর সাথে ফলাফল

এখানে চিত্র বর্ণনা লিখুন

দুর্দান্ত নয় তবে এখানে প্রভাব সহ = 1

এখানে চিত্র বর্ণনা লিখুন

যা খুব ভাল।


5

গ্রোভির উত্তরের উপর ভিত্তি করে এখানে একটি আসল জাভা বাস্তবায়ন রয়েছে পোস্ট করা(আমি জানি ইতিমধ্যে গ্রোভী এবং কোটলিন বাস্তবায়ন পোস্ট করা হয়েছে, তবে আমার মতো এমন একজনের জন্য যিনি কেবল জাভা করেছেন, অন্যান্য ভাষা এবং জাভার মধ্যে কীভাবে রূপান্তর করা যায় তা নির্ধারণ করার পক্ষে এটি আসল ঝামেলা)।

(অন্যান্য ব্যক্তির গ্রাফের সাথে ফলাফল মেলে)

অ্যালগরিদম বাস্তবায়ন

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.math3.stat.descriptive.SummaryStatistics;

public class SignalDetector {

    public HashMap<String, List> analyzeDataForSignals(List<Double> data, int lag, Double threshold, Double influence) {

        // init stats instance
        SummaryStatistics stats = new SummaryStatistics();

        // the results (peaks, 1 or -1) of our algorithm
        List<Integer> signals = new ArrayList<Integer>(Collections.nCopies(data.size(), 0));

        // filter out the signals (peaks) from our original list (using influence arg)
        List<Double> filteredData = new ArrayList<Double>(data);

        // the current average of the rolling window
        List<Double> avgFilter = new ArrayList<Double>(Collections.nCopies(data.size(), 0.0d));

        // the current standard deviation of the rolling window
        List<Double> stdFilter = new ArrayList<Double>(Collections.nCopies(data.size(), 0.0d));

        // init avgFilter and stdFilter
        for (int i = 0; i < lag; i++) {
            stats.addValue(data.get(i));
        }
        avgFilter.set(lag - 1, stats.getMean());
        stdFilter.set(lag - 1, Math.sqrt(stats.getPopulationVariance())); // getStandardDeviation() uses sample variance
        stats.clear();

        // loop input starting at end of rolling window
        for (int i = lag; i < data.size(); i++) {

            // if the distance between the current value and average is enough standard deviations (threshold) away
            if (Math.abs((data.get(i) - avgFilter.get(i - 1))) > threshold * stdFilter.get(i - 1)) {

                // this is a signal (i.e. peak), determine if it is a positive or negative signal
                if (data.get(i) > avgFilter.get(i - 1)) {
                    signals.set(i, 1);
                } else {
                    signals.set(i, -1);
                }

                // filter this signal out using influence
                filteredData.set(i, (influence * data.get(i)) + ((1 - influence) * filteredData.get(i - 1)));
            } else {
                // ensure this signal remains a zero
                signals.set(i, 0);
                // ensure this value is not filtered
                filteredData.set(i, data.get(i));
            }

            // update rolling average and deviation
            for (int j = i - lag; j < i; j++) {
                stats.addValue(filteredData.get(j));
            }
            avgFilter.set(i, stats.getMean());
            stdFilter.set(i, Math.sqrt(stats.getPopulationVariance()));
            stats.clear();
        }

        HashMap<String, List> returnMap = new HashMap<String, List>();
        returnMap.put("signals", signals);
        returnMap.put("filteredData", filteredData);
        returnMap.put("avgFilter", avgFilter);
        returnMap.put("stdFilter", stdFilter);

        return returnMap;

    } // end
}

প্রধান পদ্ধতি

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class Main {

    public static void main(String[] args) throws Exception {
        DecimalFormat df = new DecimalFormat("#0.000");

        ArrayList<Double> data = new ArrayList<Double>(Arrays.asList(1d, 1d, 1.1d, 1d, 0.9d, 1d, 1d, 1.1d, 1d, 0.9d, 1d,
                1.1d, 1d, 1d, 0.9d, 1d, 1d, 1.1d, 1d, 1d, 1d, 1d, 1.1d, 0.9d, 1d, 1.1d, 1d, 1d, 0.9d, 1d, 1.1d, 1d, 1d,
                1.1d, 1d, 0.8d, 0.9d, 1d, 1.2d, 0.9d, 1d, 1d, 1.1d, 1.2d, 1d, 1.5d, 1d, 3d, 2d, 5d, 3d, 2d, 1d, 1d, 1d,
                0.9d, 1d, 1d, 3d, 2.6d, 4d, 3d, 3.2d, 2d, 1d, 1d, 0.8d, 4d, 4d, 2d, 2.5d, 1d, 1d, 1d));

        SignalDetector signalDetector = new SignalDetector();
        int lag = 30;
        double threshold = 5;
        double influence = 0;

        HashMap<String, List> resultsMap = signalDetector.analyzeDataForSignals(data, lag, threshold, influence);
        // print algorithm params
        System.out.println("lag: " + lag + "\t\tthreshold: " + threshold + "\t\tinfluence: " + influence);

        System.out.println("Data size: " + data.size());
        System.out.println("Signals size: " + resultsMap.get("signals").size());

        // print data
        System.out.print("Data:\t\t");
        for (double d : data) {
            System.out.print(df.format(d) + "\t");
        }
        System.out.println();

        // print signals
        System.out.print("Signals:\t");
        List<Integer> signalsList = resultsMap.get("signals");
        for (int i : signalsList) {
            System.out.print(df.format(i) + "\t");
        }
        System.out.println();

        // print filtered data
        System.out.print("Filtered Data:\t");
        List<Double> filteredDataList = resultsMap.get("filteredData");
        for (double d : filteredDataList) {
            System.out.print(df.format(d) + "\t");
        }
        System.out.println();

        // print running average
        System.out.print("Avg Filter:\t");
        List<Double> avgFilterList = resultsMap.get("avgFilter");
        for (double d : avgFilterList) {
            System.out.print(df.format(d) + "\t");
        }
        System.out.println();

        // print running std
        System.out.print("Std filter:\t");
        List<Double> stdFilterList = resultsMap.get("stdFilter");
        for (double d : stdFilterList) {
            System.out.print(df.format(d) + "\t");
        }
        System.out.println();

        System.out.println();
        for (int i = 0; i < signalsList.size(); i++) {
            if (signalsList.get(i) != 0) {
                System.out.println("Point " + i + " gave signal " + signalsList.get(i));
            }
        }
    }
}

ফলাফল

lag: 30     threshold: 5.0      influence: 0.0
Data size: 74
Signals size: 74
Data:           1.000   1.000   1.100   1.000   0.900   1.000   1.000   1.100   1.000   0.900   1.000   1.100   1.000   1.000   0.900   1.000   1.000   1.100   1.000   1.000   1.000   1.000   1.100   0.900   1.000   1.100   1.000   1.000   0.900   1.000   1.100   1.000   1.000   1.100   1.000   0.800   0.900   1.000   1.200   0.900   1.000   1.000   1.100   1.200   1.000   1.500   1.000   3.000   2.000   5.000   3.000   2.000   1.000   1.000   1.000   0.900   1.000   1.000   3.000   2.600   4.000   3.000   3.200   2.000   1.000   1.000   0.800   4.000   4.000   2.000   2.500   1.000   1.000   1.000   
Signals:        0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   1.000   0.000   1.000   1.000   1.000   1.000   1.000   0.000   0.000   0.000   0.000   0.000   0.000   1.000   1.000   1.000   1.000   1.000   1.000   0.000   0.000   0.000   1.000   1.000   1.000   1.000   0.000   0.000   0.000   
Filtered Data:  1.000   1.000   1.100   1.000   0.900   1.000   1.000   1.100   1.000   0.900   1.000   1.100   1.000   1.000   0.900   1.000   1.000   1.100   1.000   1.000   1.000   1.000   1.100   0.900   1.000   1.100   1.000   1.000   0.900   1.000   1.100   1.000   1.000   1.100   1.000   0.800   0.900   1.000   1.200   0.900   1.000   1.000   1.100   1.200   1.000   1.000   1.000   1.000   1.000   1.000   1.000   1.000   1.000   1.000   1.000   0.900   1.000   1.000   1.000   1.000   1.000   1.000   1.000   1.000   1.000   1.000   0.800   0.800   0.800   0.800   0.800   1.000   1.000   1.000   
Avg Filter:     0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   1.003   1.003   1.007   1.007   1.003   1.007   1.010   1.003   1.000   0.997   1.003   1.003   1.003   1.000   1.003   1.010   1.013   1.013   1.013   1.010   1.010   1.010   1.010   1.010   1.007   1.010   1.010   1.003   1.003   1.003   1.007   1.007   1.003   1.003   1.003   1.000   1.000   1.007   1.003   0.997   0.983   0.980   0.973   0.973   0.970   
Std filter:     0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.000   0.060   0.060   0.063   0.063   0.060   0.063   0.060   0.071   0.073   0.071   0.080   0.080   0.080   0.077   0.080   0.087   0.085   0.085   0.085   0.083   0.083   0.083   0.083   0.083   0.081   0.079   0.079   0.080   0.080   0.080   0.077   0.077   0.075   0.075   0.075   0.073   0.073   0.063   0.071   0.080   0.078   0.083   0.089   0.089   0.086   

Point 45 gave signal 1
Point 47 gave signal 1
Point 48 gave signal 1
Point 49 gave signal 1
Point 50 gave signal 1
Point 51 gave signal 1
Point 58 gave signal 1
Point 59 gave signal 1
Point 60 gave signal 1
Point 61 gave signal 1
Point 62 gave signal 1
Point 63 gave signal 1
Point 67 gave signal 1
Point 68 gave signal 1
Point 69 gave signal 1
Point 70 gave signal 1

জাভা প্রয়োগের ডেটা এবং ফলাফল দেখাচ্ছে গ্রাফগুলি


5

মূল উত্তরের পরিশিষ্ট 1 Matlabএবং Rঅনুবাদগুলি

মতলব কোড

function [signals,avgFilter,stdFilter] = ThresholdingAlgo(y,lag,threshold,influence)
% Initialise signal results
signals = zeros(length(y),1);
% Initialise filtered series
filteredY = y(1:lag+1);
% Initialise filters
avgFilter(lag+1,1) = mean(y(1:lag+1));
stdFilter(lag+1,1) = std(y(1:lag+1));
% Loop over all datapoints y(lag+2),...,y(t)
for i=lag+2:length(y)
    % If new value is a specified number of deviations away
    if abs(y(i)-avgFilter(i-1)) > threshold*stdFilter(i-1)
        if y(i) > avgFilter(i-1)
            % Positive signal
            signals(i) = 1;
        else
            % Negative signal
            signals(i) = -1;
        end
        % Make influence lower
        filteredY(i) = influence*y(i)+(1-influence)*filteredY(i-1);
    else
        % No signal
        signals(i) = 0;
        filteredY(i) = y(i);
    end
    % Adjust the filters
    avgFilter(i) = mean(filteredY(i-lag:i));
    stdFilter(i) = std(filteredY(i-lag:i));
end
% Done, now return results
end

উদাহরণ:

% Data
y = [1 1 1.1 1 0.9 1 1 1.1 1 0.9 1 1.1 1 1 0.9 1 1 1.1 1 1,...
    1 1 1.1 0.9 1 1.1 1 1 0.9 1 1.1 1 1 1.1 1 0.8 0.9 1 1.2 0.9 1,...
    1 1.1 1.2 1 1.5 1 3 2 5 3 2 1 1 1 0.9 1,...
    1 3 2.6 4 3 3.2 2 1 1 0.8 4 4 2 2.5 1 1 1];

% Settings
lag = 30;
threshold = 5;
influence = 0;

% Get results
[signals,avg,dev] = ThresholdingAlgo(y,lag,threshold,influence);

figure; subplot(2,1,1); hold on;
x = 1:length(y); ix = lag+1:length(y);
area(x(ix),avg(ix)+threshold*dev(ix),'FaceColor',[0.9 0.9 0.9],'EdgeColor','none');
area(x(ix),avg(ix)-threshold*dev(ix),'FaceColor',[1 1 1],'EdgeColor','none');
plot(x(ix),avg(ix),'LineWidth',1,'Color','cyan','LineWidth',1.5);
plot(x(ix),avg(ix)+threshold*dev(ix),'LineWidth',1,'Color','green','LineWidth',1.5);
plot(x(ix),avg(ix)-threshold*dev(ix),'LineWidth',1,'Color','green','LineWidth',1.5);
plot(1:length(y),y,'b');
subplot(2,1,2);
stairs(signals,'r','LineWidth',1.5); ylim([-1.5 1.5]);

আর কোড

ThresholdingAlgo <- function(y,lag,threshold,influence) {
  signals <- rep(0,length(y))
  filteredY <- y[0:lag]
  avgFilter <- NULL
  stdFilter <- NULL
  avgFilter[lag] <- mean(y[0:lag], na.rm=TRUE)
  stdFilter[lag] <- sd(y[0:lag], na.rm=TRUE)
  for (i in (lag+1):length(y)){
    if (abs(y[i]-avgFilter[i-1]) > threshold*stdFilter[i-1]) {
      if (y[i] > avgFilter[i-1]) {
        signals[i] <- 1;
      } else {
        signals[i] <- -1;
      }
      filteredY[i] <- influence*y[i]+(1-influence)*filteredY[i-1]
    } else {
      signals[i] <- 0
      filteredY[i] <- y[i]
    }
    avgFilter[i] <- mean(filteredY[(i-lag):i], na.rm=TRUE)
    stdFilter[i] <- sd(filteredY[(i-lag):i], na.rm=TRUE)
  }
  return(list("signals"=signals,"avgFilter"=avgFilter,"stdFilter"=stdFilter))
}

উদাহরণ:

# Data
y <- c(1,1,1.1,1,0.9,1,1,1.1,1,0.9,1,1.1,1,1,0.9,1,1,1.1,1,1,1,1,1.1,0.9,1,1.1,1,1,0.9,
       1,1.1,1,1,1.1,1,0.8,0.9,1,1.2,0.9,1,1,1.1,1.2,1,1.5,1,3,2,5,3,2,1,1,1,0.9,1,1,3,
       2.6,4,3,3.2,2,1,1,0.8,4,4,2,2.5,1,1,1)

lag       <- 30
threshold <- 5
influence <- 0

# Run algo with lag = 30, threshold = 5, influence = 0
result <- ThresholdingAlgo(y,lag,threshold,influence)

# Plot result
par(mfrow = c(2,1),oma = c(2,2,0,0) + 0.1,mar = c(0,0,2,1) + 0.2)
plot(1:length(y),y,type="l",ylab="",xlab="") 
lines(1:length(y),result$avgFilter,type="l",col="cyan",lwd=2)
lines(1:length(y),result$avgFilter+threshold*result$stdFilter,type="l",col="green",lwd=2)
lines(1:length(y),result$avgFilter-threshold*result$stdFilter,type="l",col="green",lwd=2)
plot(result$signals,type="S",col="red",ylab="",xlab="",ylim=c(-1.5,1.5),lwd=2)

এই কোড (উভয় ভাষা) মূল প্রশ্নের ডেটার জন্য নিম্নলিখিত ফলাফলটি প্রদান করবে:

মতলব কোড থেকে থ্রোসোল্ডিংয়ের উদাহরণ


মূল উত্তরের পরিশিষ্ট 2: Matlab প্রদর্শন কোড

(ডেটা তৈরি করতে ক্লিক করুন)

মতলব ডেমো

function [] = RobustThresholdingDemo()

%% SPECIFICATIONS
lag         = 5;       % lag for the smoothing
threshold   = 3.5;     % number of st.dev. away from the mean to signal
influence   = 0.3;     % when signal: how much influence for new data? (between 0 and 1)
                       % 1 is normal influence, 0.5 is half      
%% START DEMO
DemoScreen(30,lag,threshold,influence);

end

function [signals,avgFilter,stdFilter] = ThresholdingAlgo(y,lag,threshold,influence)
signals = zeros(length(y),1);
filteredY = y(1:lag+1);
avgFilter(lag+1,1) = mean(y(1:lag+1));
stdFilter(lag+1,1) = std(y(1:lag+1));
for i=lag+2:length(y)
    if abs(y(i)-avgFilter(i-1)) > threshold*stdFilter(i-1)
        if y(i) > avgFilter(i-1)
            signals(i) = 1;
        else
            signals(i) = -1;
        end
        filteredY(i) = influence*y(i)+(1-influence)*filteredY(i-1);
    else
        signals(i) = 0;
        filteredY(i) = y(i);
    end
    avgFilter(i) = mean(filteredY(i-lag:i));
    stdFilter(i) = std(filteredY(i-lag:i));
end
end

% Demo screen function
function [] = DemoScreen(n,lag,threshold,influence)
figure('Position',[200 100,1000,500]);
subplot(2,1,1);
title(sprintf(['Draw data points (%.0f max)      [settings: lag = %.0f, '...
    'threshold = %.2f, influence = %.2f]'],n,lag,threshold,influence));
ylim([0 5]); xlim([0 50]);
H = gca; subplot(2,1,1);
set(H, 'YLimMode', 'manual'); set(H, 'XLimMode', 'manual');
set(H, 'YLim', get(H,'YLim')); set(H, 'XLim', get(H,'XLim'));
xg = []; yg = [];
for i=1:n
    try
        [xi,yi] = ginput(1);
    catch
        return;
    end
    xg = [xg xi]; yg = [yg yi];
    if i == 1
        subplot(2,1,1); hold on;
        plot(H, xg(i),yg(i),'r.'); 
        text(xg(i),yg(i),num2str(i),'FontSize',7);
    end
    if length(xg) > lag
        [signals,avg,dev] = ...
            ThresholdingAlgo(yg,lag,threshold,influence);
        area(xg(lag+1:end),avg(lag+1:end)+threshold*dev(lag+1:end),...
            'FaceColor',[0.9 0.9 0.9],'EdgeColor','none');
        area(xg(lag+1:end),avg(lag+1:end)-threshold*dev(lag+1:end),...
            'FaceColor',[1 1 1],'EdgeColor','none');
        plot(xg(lag+1:end),avg(lag+1:end),'LineWidth',1,'Color','cyan');
        plot(xg(lag+1:end),avg(lag+1:end)+threshold*dev(lag+1:end),...
            'LineWidth',1,'Color','green');
        plot(xg(lag+1:end),avg(lag+1:end)-threshold*dev(lag+1:end),...
            'LineWidth',1,'Color','green');
        subplot(2,1,2); hold on; title('Signal output');
        stairs(xg(lag+1:end),signals(lag+1:end),'LineWidth',2,'Color','blue');
        ylim([-2 2]); xlim([0 50]); hold off;
    end
    subplot(2,1,1); hold on;
    for j=2:i
        plot(xg([j-1:j]),yg([j-1:j]),'r'); plot(H,xg(j),yg(j),'r.');
        text(xg(j),yg(j),num2str(j),'FontSize',7);
    end
end
end


4

গৃহীত উত্তর থেকে "স্মুথেড জেড-স্কোর আলগো" রবিয়ের সমাধান তৈরি করার আমার চেষ্টা এখানে রয়েছে:

module ThresholdingAlgoMixin
  def mean(array)
    array.reduce(&:+) / array.size.to_f
  end

  def stddev(array)
    array_mean = mean(array)
    Math.sqrt(array.reduce(0.0) { |a, b| a.to_f + ((b.to_f - array_mean) ** 2) } / array.size.to_f)
  end

  def thresholding_algo(lag: 5, threshold: 3.5, influence: 0.5)
    return nil if size < lag * 2
    Array.new(size, 0).tap do |signals|
      filtered = Array.new(self)

      initial_slice = take(lag)
      avg_filter = Array.new(lag - 1, 0.0) + [mean(initial_slice)]
      std_filter = Array.new(lag - 1, 0.0) + [stddev(initial_slice)]
      (lag..size-1).each do |idx|
        prev = idx - 1
        if (fetch(idx) - avg_filter[prev]).abs > threshold * std_filter[prev]
          signals[idx] = fetch(idx) > avg_filter[prev] ? 1 : -1
          filtered[idx] = (influence * fetch(idx)) + ((1-influence) * filtered[prev])
        end

        filtered_slice = filtered[idx-lag..prev]
        avg_filter[idx] = mean(filtered_slice)
        std_filter[idx] = stddev(filtered_slice)
      end
    end
  end
end

এবং ব্যবহারের উদাহরণ:

test_data = [
  1, 1, 1.1, 1, 0.9, 1, 1, 1.1, 1, 0.9, 1, 1.1, 1, 1, 0.9, 1,
  1, 1.1, 1, 1, 1, 1, 1.1, 0.9, 1, 1.1, 1, 1, 0.9, 1, 1.1, 1,
  1, 1.1, 1, 0.8, 0.9, 1, 1.2, 0.9, 1, 1, 1.1, 1.2, 1, 1.5,
  1, 3, 2, 5, 3, 2, 1, 1, 1, 0.9, 1, 1, 3, 2.6, 4, 3, 3.2, 2,
  1, 1, 0.8, 4, 4, 2, 2.5, 1, 1, 1
].extend(ThresholdingAlgoMixin)

puts test_data.thresholding_algo.inspect

# Output: [
#   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0,
#   0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
#   1, 1, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0
# ]

দুর্দান্ত, ভাগ করে নেওয়ার জন্য ধন্যবাদ! আমি আপনাকে তালিকায় যুক্ত করব। নিশ্চিত হয়ে নিন যে রিয়েলটাইম অ্যাপ্লিকেশনগুলির জন্য আপনি যখন কোনও নতুন ডেটাপয়েন্টটি উপস্থিত হন (প্রতিটি সময় সমস্ত ডেটাপয়েন্টগুলি লুপ করার পরিবর্তে) সিগন্যালগুলি আপডেট করার জন্য একটি পৃথক ফাংশন তৈরি করেন।
জিন পল

4

উত্তরের জন্য পাইথন / numpy একটি পুনরাবৃত্ত সংস্করণে https://stackoverflow.com/a/22640362/6029703 এখানে। এই কোডটি বড় ডেটা (100000+) এর জন্য প্রতিটি ল্যাগের গড় এবং স্ট্যান্ডার্ড বিচ্যুতি তুলনায় দ্রুত।

def peak_detection_smoothed_zscore_v2(x, lag, threshold, influence):
    '''
    iterative smoothed z-score algorithm
    Implementation of algorithm from https://stackoverflow.com/a/22640362/6029703
    '''
    import numpy as np
    labels = np.zeros(len(x))
    filtered_y = np.array(x)
    avg_filter = np.zeros(len(x))
    std_filter = np.zeros(len(x))
    var_filter = np.zeros(len(x))

    avg_filter[lag - 1] = np.mean(x[0:lag])
    std_filter[lag - 1] = np.std(x[0:lag])
    var_filter[lag - 1] = np.var(x[0:lag])
    for i in range(lag, len(x)):
        if abs(x[i] - avg_filter[i - 1]) > threshold * std_filter[i - 1]:
            if x[i] > avg_filter[i - 1]:
                labels[i] = 1
            else:
                labels[i] = -1
            filtered_y[i] = influence * x[i] + (1 - influence) * filtered_y[i - 1]
        else:
            labels[i] = 0
            filtered_y[i] = x[i]
        # update avg, var, std
        avg_filter[i] = avg_filter[i - 1] + 1. / lag * (filtered_y[i] - filtered_y[i - lag])
        var_filter[i] = var_filter[i - 1] + 1. / lag * ((filtered_y[i] - avg_filter[i - 1]) ** 2 - (
            filtered_y[i - lag] - avg_filter[i - 1]) ** 2 - (filtered_y[i] - filtered_y[i - lag]) ** 2 / lag)
        std_filter[i] = np.sqrt(var_filter[i])

    return dict(signals=labels,
                avgFilter=avg_filter,
                stdFilter=std_filter)

4

ভেবেছিলাম আমি অন্যের জন্য আমার জুলিয়া প্রয়োগের অ্যালগরিদম সরবরাহ করব। টুকরোটি এখানে পাওয়া যাবে

using Statistics
using Plots
function SmoothedZscoreAlgo(y, lag, threshold, influence)
    # Julia implimentation of http://stackoverflow.com/a/22640362/6029703
    n = length(y)
    signals = zeros(n) # init signal results
    filteredY = copy(y) # init filtered series
    avgFilter = zeros(n) # init average filter
    stdFilter = zeros(n) # init std filter
    avgFilter[lag - 1] = mean(y[1:lag]) # init first value
    stdFilter[lag - 1] = std(y[1:lag]) # init first value

    for i in range(lag, stop=n-1)
        if abs(y[i] - avgFilter[i-1]) > threshold*stdFilter[i-1]
            if y[i] > avgFilter[i-1]
                signals[i] += 1 # postive signal
            else
                signals[i] += -1 # negative signal
            end
            # Make influence lower
            filteredY[i] = influence*y[i] + (1-influence)*filteredY[i-1]
        else
            signals[i] = 0
            filteredY[i] = y[i]
        end
        avgFilter[i] = mean(filteredY[i-lag+1:i])
        stdFilter[i] = std(filteredY[i-lag+1:i])
    end
    return (signals = signals, avgFilter = avgFilter, stdFilter = stdFilter)
end


# Data
y = [1,1,1.1,1,0.9,1,1,1.1,1,0.9,1,1.1,1,1,0.9,1,1,1.1,1,1,1,1,1.1,0.9,1,1.1,1,1,0.9,
       1,1.1,1,1,1.1,1,0.8,0.9,1,1.2,0.9,1,1,1.1,1.2,1,1.5,1,3,2,5,3,2,1,1,1,0.9,1,1,3,
       2.6,4,3,3.2,2,1,1,0.8,4,4,2,2.5,1,1,1]

# Settings: lag = 30, threshold = 5, influence = 0
lag = 30
threshold = 5
influence = 0

results = SmoothedZscoreAlgo(y, lag, threshold, influence)
upper_bound = results[:avgFilter] + threshold * results[:stdFilter]
lower_bound = results[:avgFilter] - threshold * results[:stdFilter]
x = 1:length(y)

yplot = plot(x,y,color="blue", label="Y",legend=:topleft)
yplot = plot!(x,upper_bound, color="green", label="Upper Bound",legend=:topleft)
yplot = plot!(x,results[:avgFilter], color="cyan", label="Average Filter",legend=:topleft)
yplot = plot!(x,lower_bound, color="green", label="Lower Bound",legend=:topleft)
signalplot = plot(x,results[:signals],color="red",label="Signals",legend=:topleft)
plot(yplot,signalplot,layout=(2,1),legend=:topleft)

ফলাফল


3

এখানে স্মুথড জেড-স্কোর অ্যালগরিদমের গ্রোভি (জাভা) বাস্তবায়ন ( উপরে উত্তর দেখুন )।

/**
 * "Smoothed zero-score alogrithm" shamelessly copied from https://stackoverflow.com/a/22640362/6029703
 *  Uses a rolling mean and a rolling deviation (separate) to identify peaks in a vector
 *
 * @param y - The input vector to analyze
 * @param lag - The lag of the moving window (i.e. how big the window is)
 * @param threshold - The z-score at which the algorithm signals (i.e. how many standard deviations away from the moving mean a peak (or signal) is)
 * @param influence - The influence (between 0 and 1) of new signals on the mean and standard deviation (how much a peak (or signal) should affect other values near it)
 * @return - The calculated averages (avgFilter) and deviations (stdFilter), and the signals (signals)
 */

public HashMap<String, List<Object>> thresholdingAlgo(List<Double> y, Long lag, Double threshold, Double influence) {
    //init stats instance
    SummaryStatistics stats = new SummaryStatistics()

    //the results (peaks, 1 or -1) of our algorithm
    List<Integer> signals = new ArrayList<Integer>(Collections.nCopies(y.size(), 0))
    //filter out the signals (peaks) from our original list (using influence arg)
    List<Double> filteredY = new ArrayList<Double>(y)
    //the current average of the rolling window
    List<Double> avgFilter = new ArrayList<Double>(Collections.nCopies(y.size(), 0.0d))
    //the current standard deviation of the rolling window
    List<Double> stdFilter = new ArrayList<Double>(Collections.nCopies(y.size(), 0.0d))
    //init avgFilter and stdFilter
    (0..lag-1).each { stats.addValue(y[it as int]) }
    avgFilter[lag - 1 as int] = stats.getMean()
    stdFilter[lag - 1 as int] = Math.sqrt(stats.getPopulationVariance()) //getStandardDeviation() uses sample variance (not what we want)
    stats.clear()
    //loop input starting at end of rolling window
    (lag..y.size()-1).each { i ->
        //if the distance between the current value and average is enough standard deviations (threshold) away
        if (Math.abs((y[i as int] - avgFilter[i - 1 as int]) as Double) > threshold * stdFilter[i - 1 as int]) {
            //this is a signal (i.e. peak), determine if it is a positive or negative signal
            signals[i as int] = (y[i as int] > avgFilter[i - 1 as int]) ? 1 : -1
            //filter this signal out using influence
            filteredY[i as int] = (influence * y[i as int]) + ((1-influence) * filteredY[i - 1 as int])
        } else {
            //ensure this signal remains a zero
            signals[i as int] = 0
            //ensure this value is not filtered
            filteredY[i as int] = y[i as int]
        }
        //update rolling average and deviation
        (i - lag..i-1).each { stats.addValue(filteredY[it as int] as Double) }
        avgFilter[i as int] = stats.getMean()
        stdFilter[i as int] = Math.sqrt(stats.getPopulationVariance()) //getStandardDeviation() uses sample variance (not what we want)
        stats.clear()
    }

    return [
        signals  : signals,
        avgFilter: avgFilter,
        stdFilter: stdFilter
    ]
}

নীচে একই ডেটাসেটের উপর একটি পরীক্ষা দেওয়া হয়েছে যা উপরের পাইথন / নম্পি বাস্তবায়ন হিসাবে একই ফলাফল দেয় ।

    // Data
    def y = [1d, 1d, 1.1d, 1d, 0.9d, 1d, 1d, 1.1d, 1d, 0.9d, 1d, 1.1d, 1d, 1d, 0.9d, 1d, 1d, 1.1d, 1d, 1d,
         1d, 1d, 1.1d, 0.9d, 1d, 1.1d, 1d, 1d, 0.9d, 1d, 1.1d, 1d, 1d, 1.1d, 1d, 0.8d, 0.9d, 1d, 1.2d, 0.9d, 1d,
         1d, 1.1d, 1.2d, 1d, 1.5d, 1d, 3d, 2d, 5d, 3d, 2d, 1d, 1d, 1d, 0.9d, 1d,
         1d, 3d, 2.6d, 4d, 3d, 3.2d, 2d, 1d, 1d, 0.8d, 4d, 4d, 2d, 2.5d, 1d, 1d, 1d]

    // Settings
    def lag = 30
    def threshold = 5
    def influence = 0


    def thresholdingResults = thresholdingAlgo((List<Double>) y, (Long) lag, (Double) threshold, (Double) influence)

    println y.size()
    println thresholdingResults.signals.size()
    println thresholdingResults.signals

    thresholdingResults.signals.eachWithIndex { x, idx ->
        if (x) {
            println y[idx]
        }
    }

3

এখানে স্মুথড জেড-স্কোর অ্যালগোরিদমের একটি (অ-পরিচয়যুক্ত) স্কাল সংস্করণ রয়েছে :

/**
  * Smoothed zero-score alogrithm shamelessly copied from https://stackoverflow.com/a/22640362/6029703
  * Uses a rolling mean and a rolling deviation (separate) to identify peaks in a vector
  *
  * @param y - The input vector to analyze
  * @param lag - The lag of the moving window (i.e. how big the window is)
  * @param threshold - The z-score at which the algorithm signals (i.e. how many standard deviations away from the moving mean a peak (or signal) is)
  * @param influence - The influence (between 0 and 1) of new signals on the mean and standard deviation (how much a peak (or signal) should affect other values near it)
  * @return - The calculated averages (avgFilter) and deviations (stdFilter), and the signals (signals)
  */
private def smoothedZScore(y: Seq[Double], lag: Int, threshold: Double, influence: Double): Seq[Int] = {
  val stats = new SummaryStatistics()

  // the results (peaks, 1 or -1) of our algorithm
  val signals = mutable.ArrayBuffer.fill(y.length)(0)

  // filter out the signals (peaks) from our original list (using influence arg)
  val filteredY = y.to[mutable.ArrayBuffer]

  // the current average of the rolling window
  val avgFilter = mutable.ArrayBuffer.fill(y.length)(0d)

  // the current standard deviation of the rolling window
  val stdFilter = mutable.ArrayBuffer.fill(y.length)(0d)

  // init avgFilter and stdFilter
  y.take(lag).foreach(s => stats.addValue(s))

  avgFilter(lag - 1) = stats.getMean
  stdFilter(lag - 1) = Math.sqrt(stats.getPopulationVariance) // getStandardDeviation() uses sample variance (not what we want)

  // loop input starting at end of rolling window
  y.zipWithIndex.slice(lag, y.length - 1).foreach {
    case (s: Double, i: Int) =>
      // if the distance between the current value and average is enough standard deviations (threshold) away
      if (Math.abs(s - avgFilter(i - 1)) > threshold * stdFilter(i - 1)) {
        // this is a signal (i.e. peak), determine if it is a positive or negative signal
        signals(i) = if (s > avgFilter(i - 1)) 1 else -1
        // filter this signal out using influence
        filteredY(i) = (influence * s) + ((1 - influence) * filteredY(i - 1))
      } else {
        // ensure this signal remains a zero
        signals(i) = 0
        // ensure this value is not filtered
        filteredY(i) = s
      }

      // update rolling average and deviation
      stats.clear()
      filteredY.slice(i - lag, i).foreach(s => stats.addValue(s))
      avgFilter(i) = stats.getMean
      stdFilter(i) = Math.sqrt(stats.getPopulationVariance) // getStandardDeviation() uses sample variance (not what we want)
  }

  println(y.length)
  println(signals.length)
  println(signals)

  signals.zipWithIndex.foreach {
    case(x: Int, idx: Int) =>
      if (x == 1) {
        println(idx + " " + y(idx))
      }
  }

  val data =
    y.zipWithIndex.map { case (s: Double, i: Int) => Map("x" -> i, "y" -> s, "name" -> "y", "row" -> "data") } ++
    avgFilter.zipWithIndex.map { case (s: Double, i: Int) => Map("x" -> i, "y" -> s, "name" -> "avgFilter", "row" -> "data") } ++
    avgFilter.zipWithIndex.map { case (s: Double, i: Int) => Map("x" -> i, "y" -> (s - threshold * stdFilter(i)), "name" -> "lower", "row" -> "data") } ++
    avgFilter.zipWithIndex.map { case (s: Double, i: Int) => Map("x" -> i, "y" -> (s + threshold * stdFilter(i)), "name" -> "upper", "row" -> "data") } ++
    signals.zipWithIndex.map { case (s: Int, i: Int) => Map("x" -> i, "y" -> s, "name" -> "signal", "row" -> "signal") }

  Vegas("Smoothed Z")
    .withData(data)
    .mark(Line)
    .encodeX("x", Quant)
    .encodeY("y", Quant)
    .encodeColor(
      field="name",
      dataType=Nominal
    )
    .encodeRow("row", Ordinal)
    .show

  return signals
}

এখানে একটি পরীক্ষা যা পাইথন এবং গ্রোভির সংস্করণগুলির মতো একই ফলাফল দেয়:

val y = List(1d, 1d, 1.1d, 1d, 0.9d, 1d, 1d, 1.1d, 1d, 0.9d, 1d, 1.1d, 1d, 1d, 0.9d, 1d, 1d, 1.1d, 1d, 1d,
  1d, 1d, 1.1d, 0.9d, 1d, 1.1d, 1d, 1d, 0.9d, 1d, 1.1d, 1d, 1d, 1.1d, 1d, 0.8d, 0.9d, 1d, 1.2d, 0.9d, 1d,
  1d, 1.1d, 1.2d, 1d, 1.5d, 1d, 3d, 2d, 5d, 3d, 2d, 1d, 1d, 1d, 0.9d, 1d,
  1d, 3d, 2.6d, 4d, 3d, 3.2d, 2d, 1d, 1d, 0.8d, 4d, 4d, 2d, 2.5d, 1d, 1d, 1d)

val lag = 30
val threshold = 5d
val influence = 0d

smoothedZScore(y, lag, threshold, influence)

রেজাল্ট ভেজাস চার্ট

এখানে বলুন


1 শৃঙ্গ উপস্থাপন করে, -1 উপত্যকার প্রতিনিধিত্ব করে।
মাইক রবার্টস

3

আমার অ্যান্ড্রয়েড প্রকল্পে আমার এর মতো কিছু দরকার ছিল। ভেবেছিলাম আমি কোটলিন বাস্তবায়ন ফিরিয়ে দেব ।

/**
* Smoothed zero-score alogrithm shamelessly copied from https://stackoverflow.com/a/22640362/6029703
* Uses a rolling mean and a rolling deviation (separate) to identify peaks in a vector
*
* @param y - The input vector to analyze
* @param lag - The lag of the moving window (i.e. how big the window is)
* @param threshold - The z-score at which the algorithm signals (i.e. how many standard deviations away from the moving mean a peak (or signal) is)
* @param influence - The influence (between 0 and 1) of new signals on the mean and standard deviation (how much a peak (or signal) should affect other values near it)
* @return - The calculated averages (avgFilter) and deviations (stdFilter), and the signals (signals)
*/
fun smoothedZScore(y: List<Double>, lag: Int, threshold: Double, influence: Double): Triple<List<Int>, List<Double>, List<Double>> {
    val stats = SummaryStatistics()
    // the results (peaks, 1 or -1) of our algorithm
    val signals = MutableList<Int>(y.size, { 0 })
    // filter out the signals (peaks) from our original list (using influence arg)
    val filteredY = ArrayList<Double>(y)
    // the current average of the rolling window
    val avgFilter = MutableList<Double>(y.size, { 0.0 })
    // the current standard deviation of the rolling window
    val stdFilter = MutableList<Double>(y.size, { 0.0 })
    // init avgFilter and stdFilter
    y.take(lag).forEach { s -> stats.addValue(s) }
    avgFilter[lag - 1] = stats.mean
    stdFilter[lag - 1] = Math.sqrt(stats.populationVariance) // getStandardDeviation() uses sample variance (not what we want)
    stats.clear()
    //loop input starting at end of rolling window
    (lag..y.size - 1).forEach { i ->
        //if the distance between the current value and average is enough standard deviations (threshold) away
        if (Math.abs(y[i] - avgFilter[i - 1]) > threshold * stdFilter[i - 1]) {
            //this is a signal (i.e. peak), determine if it is a positive or negative signal
            signals[i] = if (y[i] > avgFilter[i - 1]) 1 else -1
            //filter this signal out using influence
            filteredY[i] = (influence * y[i]) + ((1 - influence) * filteredY[i - 1])
        } else {
            //ensure this signal remains a zero
            signals[i] = 0
            //ensure this value is not filtered
            filteredY[i] = y[i]
        }
        //update rolling average and deviation
        (i - lag..i - 1).forEach { stats.addValue(filteredY[it]) }
        avgFilter[i] = stats.getMean()
        stdFilter[i] = Math.sqrt(stats.getPopulationVariance()) //getStandardDeviation() uses sample variance (not what we want)
        stats.clear()
    }
    return Triple(signals, avgFilter, stdFilter)
}

ভেরিফিকেশন গ্রাফ সহ নমুনা প্রকল্পটি গিথুবে পাওয়া যাবে ।

এখানে চিত্র বর্ণনা লিখুন


অসাধারণ! ভাগ করে নেওয়ার জন্য ধন্যবাদ. রিয়েলটাইম অ্যাপ্লিকেশনগুলির জন্য, একটি পৃথক ফাংশন তৈরি করতে ভুলবেন না যা প্রতিটি আগত ডেটাপয়েন্টের সাহায্যে নতুন সংকেত গণনা করে। প্রতিবার নতুন ডেটাপয়েন্ট এলে পুরো ডেটা লুপ করবেন না, এটি চূড়ান্তভাবে অদক্ষ হয়ে যাবে :)
জিন-পল

1
ভাল কথা, এটি সম্পর্কে ভাবেন না, কারণ আমি যে উইন্ডোজগুলি ব্যবহার করি সেগুলি ওভারল্যাপ হয় না।
লিওনার্ডক্রাইমার

3

এখানে জেড-স্কোর অ্যালগোরিদমের পরিবর্তিত ফোর্টরান সংস্করণ রয়েছে । এটি ফ্রিকোয়েন্সি স্পেসে স্থানান্তর ফাংশনগুলিতে শীর্ষ (অনুরণন) সনাক্তকরণের জন্য বিশেষভাবে পরিবর্তিত হয় (প্রতিটি পরিবর্তনের কোডে একটি ছোট মন্তব্য থাকে)।

ইনপুট ভেক্টরের নীচের সীমানার কাছে কোনও অনুরণন থাকলে নির্দিষ্ট চৌম্বক (এই ক্ষেত্রে 10%) এর চেয়ে বেশি স্ট্যান্ডার্ড বিচ্যুতি দ্বারা নির্দেশিত হলে প্রথম পরিবর্তনটি ব্যবহারকারীকে একটি সতর্কতা দেয়। এর সহজ অর্থ হ'ল ফিল্টারগুলি সঠিকভাবে শুরু করার জন্য সনাক্তকরণের জন্য সিগন্যাল যথেষ্ট সমতল নয়।

দ্বিতীয় সংশোধনটি হ'ল কেবল একটি শীর্ষের সর্বোচ্চ মান সন্ধান করা শিখরে যোগ করা হয়। এটি প্রতিটি পাওয়া শিখর মানটিকে তার (ল্যাগ) পূর্ববর্তীদের এবং এর (উত্তর) উত্তরসূরিদের পরিমাণের সাথে তুলনা করে পৌঁছেছে।

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

পরিবর্তনগুলির প্রভাব রয়েছে যে পুরো সিগন্যালটি আগে থেকেই ফাংশনটির সাথে জানা থাকতে হবে যা অনুরণন সনাক্তকরণের জন্য স্বাভাবিক ক্ষেত্রে (জিন-পলের মতলব উদাহরণের মতো যেখানে ফ্লাইতে ডেটা পয়েন্ট উত্পন্ন হয়) কাজ করবে না।

function PeakDetect(y,lag,threshold, influence)
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer, dimension(size(y)) :: PeakDetect
    real, dimension(size(y)) :: filteredY, avgFilter, stdFilter
    integer :: lag, ii
    real :: threshold, influence

    ! Executing part
    PeakDetect = 0
    filteredY = 0.0
    filteredY(1:lag+1) = y(1:lag+1)
    avgFilter = 0.0
    avgFilter(lag+1) = mean(y(1:2*lag+1))
    stdFilter = 0.0
    stdFilter(lag+1) = std(y(1:2*lag+1))

    if (stdFilter(lag+1)/avgFilter(lag+1)>0.1) then ! If the coefficient of variation exceeds 10%, the signal is too uneven at the start, possibly because of a peak.
        write(unit=*,fmt=1001)
1001        format(1X,'Warning: Peak detection might have failed, as there may be a peak at the edge of the frequency range.',/)
    end if
    do ii = lag+2, size(y)
        if (abs(y(ii) - avgFilter(ii-1)) > threshold * stdFilter(ii-1)) then
            ! Find only the largest outstanding value which is only the one greater than its predecessor and its successor
            if (y(ii) > avgFilter(ii-1) .AND. y(ii) > y(ii-1) .AND. y(ii) > y(ii+1)) then
                PeakDetect(ii) = 1
            end if
            filteredY(ii) = influence * y(ii) + (1 - influence) * filteredY(ii-1)
        else
            filteredY(ii) = y(ii)
        end if
        ! Modified with respect to the original code. Mean and standard deviation are calculted symmetrically around the current point
        avgFilter(ii) = mean(filteredY(ii-lag:ii+lag))
        stdFilter(ii) = std(filteredY(ii-lag:ii+lag))
    end do
end function PeakDetect

real function mean(y)
    !> @brief Calculates the mean of vector y
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer :: N
    ! Executing part
    N = max(1,size(y))
    mean = sum(y)/N
end function mean

real function std(y)
    !> @brief Calculates the standard deviation of vector y
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer :: N
    ! Executing part
    N = max(1,size(y))
    std = sqrt((N*dot_product(y,y) - sum(y)**2) / (N*(N-1)))
end function std

আমার অ্যাপ্লিকেশনটির জন্য অ্যালগরিদম একটি কবজির মতো কাজ করে! এখানে চিত্র বর্ণনা লিখুন


3

আপনি যদি কোনও ডাটাবেস সারণীতে আপনার ডেটা পেয়ে থাকেন তবে এখানে একটি সাধারণ জেড স্কোর অ্যালগরিদমের একটি এসকিউএল সংস্করণ রয়েছে:

with data_with_zscore as (
    select
        date_time,
        value,
        value / (avg(value) over ()) as pct_of_mean,
        (value - avg(value) over ()) / (stdev(value) over ()) as z_score
    from {{tablename}}  where datetime > '2018-11-26' and datetime < '2018-12-03'
)


-- select all
select * from data_with_zscore 

-- select only points greater than a certain threshold
select * from data_with_zscore where z_score > abs(2)

আপনার কোডটি আমি প্রস্তাবিত অ্যালগরিদম বাদে অন্য কিছু করে। আপনার ক্যোয়ারীটি কেবল জেড-স্কোরগুলি গণনা করে ([ডেটা পয়েন্ট - গড়] / স্টাডি), তবে আমার সিগেরীর যুক্তি যুক্ত করে না যা নতুন সিগন্যাল প্রান্তিক গণনা করার সময় অতীত সংকেতগুলিকে উপেক্ষা করে। আপনি তিনটি পরামিতি (পিছিয়ে, প্রভাব, প্রান্তিক) উপেক্ষা করুন। আপনি কি আসল যুক্তি যুক্ত করতে আপনার উত্তরটি সংশোধন করতে পারেন?
জিন পল

1
হ্যাঁ তুমি সঠিক. প্রথমে আমি ভেবেছিলাম উপরের সরলীকৃত সংস্করণটি দিয়ে আমি পালিয়ে যেতে পারি .. তখন থেকে আমি আপনার সম্পূর্ণ সমাধানটি নিয়েছি এবং এটি সি # তে পোর্ট করেছি। আমার উত্তর নীচে দেখুন। আমার আরও সময় পেলে আমি এই এসকিউএল সংস্করণটি আবার দেখতে এবং আপনার অ্যালগরিদম সংযুক্ত করব। যাইহোক, এমন দুর্দান্ত উত্তর এবং চাক্ষুষ ব্যাখ্যার জন্য আপনাকে ধন্যবাদ।
ওশান এয়ারড্রপ

কোনও সমস্যা এবং আনন্দিত না যে অ্যালগোরিদম আপনাকে সাহায্য করতে পারে! আপনার সি # জমা দেওয়ার জন্য আপনাকে ধন্যবাদ, এটি এখনও নিখোঁজ ছিল। আমি এটি অনুবাদ তালিকায় যুক্ত করব!
জিন-পল

3

পাইথন সংস্করণ যা রিয়েল-টাইম স্ট্রিমগুলির সাথে কাজ করে (প্রতিটি নতুন ডাটা পয়েন্ট আগমনের সময় সমস্ত ডেটা পয়েন্ট পুনরায় গণনা করে না)। ক্লাস ফাংশনটি কী ফিরিয়ে দেয় তা আপনি টুইট করতে চাইতে পারেন - আমার প্রয়োজনের জন্য আমার কেবল সংকেতের দরকার ছিল।

import numpy as np

class real_time_peak_detection():
    def __init__(self, array, lag, threshold, influence):
        self.y = list(array)
        self.length = len(self.y)
        self.lag = lag
        self.threshold = threshold
        self.influence = influence
        self.signals = [0] * len(self.y)
        self.filteredY = np.array(self.y).tolist()
        self.avgFilter = [0] * len(self.y)
        self.stdFilter = [0] * len(self.y)
        self.avgFilter[self.lag - 1] = np.mean(self.y[0:self.lag]).tolist()
        self.stdFilter[self.lag - 1] = np.std(self.y[0:self.lag]).tolist()

    def thresholding_algo(self, new_value):
        self.y.append(new_value)
        i = len(self.y) - 1
        self.length = len(self.y)
        if i < self.lag:
            return 0
        elif i == self.lag:
            self.signals = [0] * len(self.y)
            self.filteredY = np.array(self.y).tolist()
            self.avgFilter = [0] * len(self.y)
            self.stdFilter = [0] * len(self.y)
            self.avgFilter[self.lag - 1] = np.mean(self.y[0:self.lag]).tolist()
            self.stdFilter[self.lag - 1] = np.std(self.y[0:self.lag]).tolist()
            return 0

        self.signals += [0]
        self.filteredY += [0]
        self.avgFilter += [0]
        self.stdFilter += [0]

        if abs(self.y[i] - self.avgFilter[i - 1]) > self.threshold * self.stdFilter[i - 1]:
            if self.y[i] > self.avgFilter[i - 1]:
                self.signals[i] = 1
            else:
                self.signals[i] = -1

            self.filteredY[i] = self.influence * self.y[i] + (1 - self.influence) * self.filteredY[i - 1]
            self.avgFilter[i] = np.mean(self.filteredY[(i - self.lag):i])
            self.stdFilter[i] = np.std(self.filteredY[(i - self.lag):i])
        else:
            self.signals[i] = 0
            self.filteredY[i] = self.y[i]
            self.avgFilter[i] = np.mean(self.filteredY[(i - self.lag):i])
            self.stdFilter[i] = np.std(self.filteredY[(i - self.lag):i])

        return self.signals[i]

পোস্ট করার জন্য ধন্যবাদ, আমি আপনার অনুবাদটি তালিকায় যুক্ত করেছি।
জিন পল

3

আমি নিজেকে এর জাভাস্ক্রিপ্ট সংস্করণ তৈরি করার অনুমতি দিয়েছি। এটি সহায়ক হতে পারে। জাভাস্ক্রিপ্ট উপরের সিউডোকোডের সরাসরি প্রতিলিপি হওয়া উচিত। এনপিএম প্যাকেজ এবং গিথুব রেপো হিসাবে উপলব্ধ:

জাভাস্ক্রিপ্ট অনুবাদ:

// javascript port of: /programming/22583391/peak-signal-detection-in-realtime-timeseries-data/48895639#48895639

function sum(a) {
    return a.reduce((acc, val) => acc + val)
}

function mean(a) {
    return sum(a) / a.length
}

function stddev(arr) {
    const arr_mean = mean(arr)
    const r = function(acc, val) {
        return acc + ((val - arr_mean) * (val - arr_mean))
    }
    return Math.sqrt(arr.reduce(r, 0.0) / arr.length)
}

function smoothed_z_score(y, params) {
    var p = params || {}
    // init cooefficients
    const lag = p.lag || 5
    const threshold = p.threshold || 3.5
    const influence = p.influece || 0.5

    if (y === undefined || y.length < lag + 2) {
        throw ` ## y data array to short(${y.length}) for given lag of ${lag}`
    }
    //console.log(`lag, threshold, influence: ${lag}, ${threshold}, ${influence}`)

    // init variables
    var signals = Array(y.length).fill(0)
    var filteredY = y.slice(0)
    const lead_in = y.slice(0, lag)
    //console.log("1: " + lead_in.toString())

    var avgFilter = []
    avgFilter[lag - 1] = mean(lead_in)
    var stdFilter = []
    stdFilter[lag - 1] = stddev(lead_in)
    //console.log("2: " + stdFilter.toString())

    for (var i = lag; i < y.length; i++) {
        //console.log(`${y[i]}, ${avgFilter[i-1]}, ${threshold}, ${stdFilter[i-1]}`)
        if (Math.abs(y[i] - avgFilter[i - 1]) > (threshold * stdFilter[i - 1])) {
            if (y[i] > avgFilter[i - 1]) {
                signals[i] = +1 // positive signal
            } else {
                signals[i] = -1 // negative signal
            }
            // make influence lower
            filteredY[i] = influence * y[i] + (1 - influence) * filteredY[i - 1]
        } else {
            signals[i] = 0 // no signal
            filteredY[i] = y[i]
        }

        // adjust the filters
        const y_lag = filteredY.slice(i - lag, i)
        avgFilter[i] = mean(y_lag)
        stdFilter[i] = stddev(y_lag)
    }

    return signals
}

module.exports = smoothed_z_score

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

এতক্ষণে আমি জাভাস্ক্রিপ্টে কিছু অন্যান্য অ্যালগরিদম পোর্ট করেছি। এবার সংখ্যাসূচক পাইহন থেকে, যা আমাকে আরও নিয়ন্ত্রণ দেয় এবং আমার জন্য আরও ভাল কাজ করে। এছাড়াও এনপিএম-এ প্যাকেজ করা হয়েছে এবং আপনি ওয়াশিংটন স্টেট ইউনিভার্সিটি থেকে আলগো সম্পর্কিত আরও তথ্য তাদের জুপিটার পৃষ্ঠায় পেতে পারেন for npmjs.com/package/@joe_six/duarte-watanabe-peak-detection
Dirk Lüsebrink

2

যদি সীমানা মান বা অন্যান্য মানদণ্ড ভবিষ্যতের মানগুলির উপর নির্ভর করে, তবে একমাত্র সমাধান (সময়-মেশিন ছাড়াই বা ভবিষ্যতের মূল্যবোধগুলির অন্যান্য জ্ঞান ছাড়াই) যে কোনও সিদ্ধান্তের ভবিষ্যতের মান না হওয়া পর্যন্ত কোনও সিদ্ধান্তকে বিলম্ব করা। যদি আপনি কোনও গড়ের উপরে একটি স্তর চান, উদাহরণস্বরূপ, 20 পয়েন্ট, তবে আপনাকে যে কোনও শীর্ষ সিদ্ধান্তের আগে কমপক্ষে 19 পয়েন্ট থাকা অবধি অপেক্ষা করতে হবে, নাহলে পরের নতুন পয়েন্টটি 19 পয়েন্ট পূর্বে আপনার দোরগোড়াকে পুরোপুরি ফেলে দিতে পারে ।

আপনার বর্তমান প্লটটির কোনও শিখর নেই ... যদি না আপনি আগেই জানতে না পারেন যে পরবর্তী পয়েন্টটি 1e99 নয়, যা আপনার প্লটের ওয়াই ডাইমেনশনটি উদ্ধার করার পরে, সেই বিন্দু পর্যন্ত সমতল হবে।


যেমনটি আমি আগে বলেছি, আমরা ধরে নিতে পারি যে যদি একটি শীর্ষগুলি ঘটে তবে এটি চিত্রের চূড়াগুলির মতো বড় এবং 'স্বাভাবিক' মানগুলি থেকে উল্লেখযোগ্যভাবে বিচ্যুত হয়।
জিন-পল

আপনি যদি জানেন যে শীর্ষগুলি কতটা আগে থেকে হবে, তবে আপনার গড় এবং / অথবা প্রান্তকে ঠিক সেই মানটির নিচে সেট করুন।
হটপাউ 2

1
এবং ঠিক এটাই আমি আগে থেকে জানি না।
জিন-পল

1
আপনি কেবল নিজের সাথে বিরোধিতা করেছেন এবং লিখেছেন যে ছবিতে শৃঙ্গগুলি আকার হিসাবে পরিচিত। হয় আপনি তা জানেন বা আপনি জানেন না।
হটপাউ 2

2
আমি আপনাকে এটি ব্যাখ্যা করার চেষ্টা করছি। আপনি এখনই ধারণা পেতে? 'কীভাবে উল্লেখযোগ্যভাবে বড় চূড়াগুলি সনাক্ত করা যায়'। আপনি পরিসংখ্যানগতভাবে বা স্মার্ট অ্যালগরিদম দিয়ে সমস্যার কাছে যেতে পারেন। সঙ্গে .. As large as in the pictureআমি বোঝানো: অনুরূপ পরিস্থিতিতে যেখানে উল্লেখযোগ্য পীক এবং মৌলিক গোলমাল আছে জন্য।
জিন-পল

2

এবং এখানে ZSCORE আলোর পিএইচপি বাস্তবায়ন আসে :

<?php
$y = array(1,7,1.1,1,0.9,1,1,1.1,1,0.9,1,1.1,1,1,0.9,1,1,1.1,1,1,1,1,1.1,0.9,1,1.1,1,1,0.9,
       1,1.1,1,1,1.1,1,0.8,0.9,1,1.2,0.9,1,1,1.1,1.2,1,1.5,10,3,2,5,3,2,1,1,1,0.9,1,1,3,
       2.6,4,3,3.2,2,1,1,0.8,4,4,2,2.5,1,1,1);

function mean($data, $start, $len) {
    $avg = 0;
    for ($i = $start; $i < $start+ $len; $i ++)
        $avg += $data[$i];
    return $avg / $len;
}

function stddev($data, $start,$len) {
    $mean = mean($data,$start,$len);
    $dev = 0;
    for ($i = $start; $i < $start+$len; $i++) 
        $dev += (($data[$i] - $mean) * ($data[$i] - $mean));
    return sqrt($dev / $len);
}

function zscore($data, $len, $lag= 20, $threshold = 1, $influence = 1) {

    $signals = array();
    $avgFilter = array();
    $stdFilter = array();
    $filteredY = array();
    $avgFilter[$lag - 1] = mean($data, 0, $lag);
    $stdFilter[$lag - 1] = stddev($data, 0, $lag);

    for ($i = 0; $i < $len; $i++) {
        $filteredY[$i] = $data[$i];
        $signals[$i] = 0;
    }


    for ($i=$lag; $i < $len; $i++) {
        if (abs($data[$i] - $avgFilter[$i-1]) > $threshold * $stdFilter[$lag - 1]) {
            if ($data[$i] > $avgFilter[$i-1]) {
                $signals[$i] = 1;
            }
            else {
                $signals[$i] = -1;
            }
            $filteredY[$i] = $influence * $data[$i] + (1 - $influence) * $filteredY[$i-1];
        } 
        else {
            $signals[$i] = 0;
            $filteredY[$i] = $data[$i];
        }

        $avgFilter[$i] = mean($filteredY, $i - $lag, $lag);
        $stdFilter[$i] = stddev($filteredY, $i - $lag, $lag);
    }
    return $signals;
}

$sig = zscore($y, count($y));

print_r($y); echo "<br><br>";
print_r($sig); echo "<br><br>";

for ($i = 0; $i < count($y); $i++) echo $i. " " . $y[$i]. " ". $sig[$i]."<br>";

?>

পোস্ট করার জন্য আপনাকে ধন্যবাদ, আমি তালিকায় আপনার অনুবাদ যোগ করেছি।
জিন-পল

1
একটি মন্তব্য: প্রদত্ত যে এই অ্যালগরিদম বেশিরভাগই নমুনা ডেটা ব্যবহার করা হবে, আমি আপনাকে বাস্তবায়ন নমুনা স্ট্যানডার্ড ডেভিয়েশন দ্বারা ভাগ ($len - 1)পরিবর্তে $lenমধ্যেstddev()
জাঁ পল

1

কোনও ম্যাক্সিমাকে গড়ের সাথে তুলনা করার পরিবর্তে, আপনি ম্যাক্সিমাকে সংলগ্ন মিনিমাতেও তুলনা করতে পারেন যেখানে মিনিমা কেবলমাত্র একটি শব্দ মাত্রার উপরে সংজ্ঞায়িত করা হয়। যদি স্থানীয় সর্বাধিক হয়> 3 বার (বা অন্যান্য আত্মবিশ্বাসের উপাদান) হয় সংলগ্ন মিনিমা, তবে সেই ম্যাক্সিমাটি একটি শীর্ষে। চূড়ান্ত সংকল্প বৃহত্তর চলমান উইন্ডোগুলির সাথে আরও সঠিক। উপরেরটি উইন্ডোটির শেষে (== লেগ) গণনার চেয়ে উইন্ডোটির মাঝখানে কেন্দ্রীভূত ব্যবহার করে।

নোট করুন যে একটি ম্যাক্সিমাকে আগে সংকেত বৃদ্ধি এবং পরে হ্রাস হিসাবে দেখা উচিত।


1

ফাংশন scipy.signal.find_peaks, এর নাম হিসাবে এটি এর জন্য দরকারী। কিন্তু এটা ভাল বুঝতে তার পরামিতি গুরুত্বপূর্ণ width, threshold, distance এবং সর্বোপরিprominence একটি ভাল শিখর নিষ্কাশন জন্য।

আমার পরীক্ষাগুলি এবং ডকুমেন্টেশন অনুসারে, উচ্চতর শিখরকে ধরে রাখতে এবং গোলমাল শৃঙ্গগুলি ত্যাগ করার জন্য বিশিষ্টতার ধারণাটি "দরকারী ধারণা"।

কি (স্থান বিবরণ সম্বন্ধীয়) প্রাধান্য ? এটি এখানে দেখা যেতে পারে যে "শীর্ষে চূড়া থেকে কোনও উচ্চতর ভূখণ্ডে পৌঁছতে ন্যূনতম উচ্চতা প্রয়োজন" :

ধারণাটি হ'ল:

শীর্ষস্থানটি যত বেশি, তত বেশি "গুরুত্বপূর্ণ" শীর্ষটি।


1

মোর্ডারন সি +++ ব্যবহার করে জেড-স্কোর অ্যালগরিদমের অবজেক্ট-ওরিয়েন্টেড সংস্করণ

template<typename T>
class FindPeaks{
private:
    std::vector<T> m_input_signal;                      // stores input vector
    std::vector<T> m_array_peak_positive;               
    std::vector<T> m_array_peak_negative;               

public:
    FindPeaks(const std::vector<T>& t_input_signal): m_input_signal{t_input_signal}{ }

    void estimate(){
        int lag{5};
        T threshold{ 5 };                                                                                       // set a threshold
        T influence{ 0.5 };                                                                                    // value between 0 to 1, 1 is normal influence and 0.5 is half the influence

        std::vector<T> filtered_signal(m_input_signal.size(), 0.0);                                             // placeholdered for smooth signal, initialie with all zeros
        std::vector<int> signal(m_input_signal.size(), 0);                                                          // vector that stores where the negative and positive located
        std::vector<T> avg_filtered(m_input_signal.size(), 0.0);                                                // moving averages
        std::vector<T> std_filtered(m_input_signal.size(), 0.0);                                                // moving standard deviation

        avg_filtered[lag] = findMean(m_input_signal.begin(), m_input_signal.begin() + lag);                         // pass the iteartor to vector
        std_filtered[lag] = findStandardDeviation(m_input_signal.begin(), m_input_signal.begin() + lag);

        for (size_t iLag = lag + 1; iLag < m_input_signal.size(); ++iLag) {                                         // start index frm 
            if (std::abs(m_input_signal[iLag] - avg_filtered[iLag - 1]) > threshold * std_filtered[iLag - 1]) {     // check if value is above threhold             
                if ((m_input_signal[iLag]) > avg_filtered[iLag - 1]) {
                    signal[iLag] = 1;                                                                               // assign positive signal
                }
                else {
                    signal[iLag] = -1;                                                                                  // assign negative signal
                }
                filtered_signal[iLag] = influence * m_input_signal[iLag] + (1 - influence) * filtered_signal[iLag - 1];        // exponential smoothing
            }
            else {
                signal[iLag] = 0;                                                                                         // no signal
                filtered_signal[iLag] = m_input_signal[iLag];
            }

            avg_filtered[iLag] = findMean(filtered_signal.begin() + (iLag - lag), filtered_signal.begin() + iLag);
            std_filtered[iLag] = findStandardDeviation(filtered_signal.begin() + (iLag - lag), filtered_signal.begin() + iLag);

        }

        for (size_t iSignal = 0; iSignal < m_input_signal.size(); ++iSignal) {
            if (signal[iSignal] == 1) {
                m_array_peak_positive.emplace_back(m_input_signal[iSignal]);                                        // store the positive peaks
            }
            else if (signal[iSignal] == -1) {
                m_array_peak_negative.emplace_back(m_input_signal[iSignal]);                                         // store the negative peaks
            }
        }
        printVoltagePeaks(signal, m_input_signal);

    }

    std::pair< std::vector<T>, std::vector<T> > get_peaks()
    {
        return std::make_pair(m_array_peak_negative, m_array_peak_negative);
    }

};


template<typename T1, typename T2 >
void printVoltagePeaks(std::vector<T1>& m_signal, std::vector<T2>& m_input_signal) {
    std::ofstream output_file("./voltage_peak.csv");
    std::ostream_iterator<T2> output_iterator_voltage(output_file, ",");
    std::ostream_iterator<T1> output_iterator_signal(output_file, ",");
    std::copy(m_input_signal.begin(), m_input_signal.end(), output_iterator_voltage);
    output_file << "\n";
    std::copy(m_signal.begin(), m_signal.end(), output_iterator_signal);
}

template<typename iterator_type>
typename std::iterator_traits<iterator_type>::value_type findMean(iterator_type it, iterator_type end)
{
    /* function that receives iterator to*/
    typename std::iterator_traits<iterator_type>::value_type sum{ 0.0 };
    int counter = 0;
    while (it != end) {
        sum += *(it++);
        counter++;
    }
    return sum / counter;
}

template<typename iterator_type>
typename std::iterator_traits<iterator_type>::value_type findStandardDeviation(iterator_type it, iterator_type end)
{
    auto mean = findMean(it, end);
    typename std::iterator_traits<iterator_type>::value_type sum_squared_error{ 0.0 };
    int counter{ 0 };
    while (it != end) {
        sum_squared_error += std::pow((*(it++) - mean), 2);
        counter++;
    }
    auto standard_deviation = std::sqrt(sum_squared_error / (counter - 1));
    return standard_deviation;
}

2
সুন্দর অনুবাদ। এটা তোলে সামান্য সুন্দর যদি বস্তুর এছাড়াও সংরক্ষণ হবে filtered_signal, signal, avg_filteredএবং std_filteredযেমন ব্যক্তিগত ভেরিয়েবল এবং কেবলমাত্র সেই অ্যারে আপডেট একবার যখন একটি নতুন datapoint হাজির হলে (এখন সব datapoints উপর কোড লুপ Everytime এটা বলা হয়)। এটি আপনার কোডের কার্যকারিতা উন্নত করবে এবং ওওপি কাঠামোর আরও ভাল স্যুট করবে।
জিন-পল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.