#pragma once
namespace _datum_analysis
{
/* gaussian kernel */
template <typename _Ty>
class gaussian_kernel
{
public:
double operator () (_Ty _distance, const double _lambda = 0.2)
{
double m_t = _distance / _lambda;
return (exp(-0.5 * m_t * m_t));
}
};
/* 二次方 Epanechnikov kernel */
template <typename _Ty>
class epanechnikov_kernel
{
public:
double operator () (_Ty _distance, const double _lambda = 0.2)
{
double m_t = _distance / _lambda;
if (abs(m_t) < 1.0)
return (0.75 * (1 - m_t * m_t));
else
return 0;
}
};
/* 三次方 Epanechnikov kernel */
template <typename _Ty>
class epanechnikov_pan_kernel
{
public:
double operator () (_Ty _distance, const double _lambda = 0.2)
{
double m_t = _distance / _lambda;
if (abs(m_t) < 1.0)
{
double m_meta = 1 - m_t * m_t * m_t;
return (m_meta * m_meta * m_meta);
}
else
return 0;
}
};
/* Nadaraya - Watson - kernel 加权平均 */
template <class _Mat_Type, class _mean = epanechnikov_pan_kernel<double> >
class kernel_mean_probability
{
typedef typename _Mat_Type::value_type value_type;
typedef typename _Mat_Type::const_reference const_reference;
typedef typename _Mat_Type::const_iterator const_iterator;
public:
double operator () (const _Mat_Type& _matt, const int _main_class, const double _lambda = 0.2)
{
double m_predict_count = 0;
double m_predict_sum = 0;
/* epanechnikov_pan_kernel 更加紧致核 */
std::for_each(_matt.begin(), _matt.end(), [&](const_reference _meta) -> void
{
double weight = _mean()(_meta.m_distance, _lambda);
if (_meta.m_instance._class_type == _main_class)
m_predict_count += weight;
m_predict_sum += weight;
});
if (abs(m_predict_sum) < equate_zero) return 0;
return (100.0 * m_predict_count / m_predict_sum);
}
};
/* Nadaraya - Watson - kernel 加权平均 */
template <class _Mat_Type, class _mean = epanechnikov_pan_kernel<double> >
class kernel_mean_regression
{
typedef typename _Mat_Type::value_type value_type;
typedef typename _Mat_Type::const_reference const_reference;
typedef typename _Mat_Type::const_iterator const_iterator;
public:
double operator () (const _Mat_Type& _matt, const double _lambda = 0.2)
{
double m_predict_rise = 0;
double m_predict_sum = 0;
/* epanechnikov_pan_kernel 更加紧致核 */
std::for_each(_matt.begin(), _matt.end(), [&](const_reference _meta) -> void
{
double weight = _mean()(_meta.m_distance, _lambda);
m_predict_rise += weight * _meta.m_instance._actual_rise;
m_predict_sum += weight;
});
if (abs(m_predict_sum) < equate_zero) return 0;
return (m_predict_rise / m_predict_sum);
}
};
}
参考:
范明 柴玉梅 昝红英 等译(2003) 统计学习基础—数据挖掘、推理与预测 电子工业出版社 115~133