Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace Iris
- {
- public class Data
- {
- public double[] Features { get; }
- public string Classifcation { get; }
- public Data(double[] features,string classification)
- {
- Features = features;
- Classifcation = classification;
- }
- }
- public class Classificator
- {
- private int featureCount;
- private string positiveResult;
- private double[] weights;
- private readonly double learningRate;
- public Classificator(int featureCount,string positiveResult,double learningRate=0.5)
- {
- this.featureCount = featureCount;
- this.positiveResult = positiveResult;
- this.learningRate = learningRate;
- InitWeight(featureCount);
- }
- private void InitWeight(int featureCount)
- {
- //+1 for bias weight
- weights = new double[featureCount+1];
- for (int i=0;i<weights.Length;i++)
- {
- //weights[i] = new Random().NextDouble();
- weights[i] = 0.5;
- }
- }
- public void Train(Data[] data,int epoch)
- {
- for (int i = 0; i < epoch; i++)
- {
- BatchGraidentDescent(data);
- }
- }
- private void BatchGraidentDescent(Data[] data)
- {
- double wholeSum = WholeSum(data);
- double[] newWeights = new double[weights.Length];
- double tmp = learningRate * (1.0 / data.Length) * wholeSum;
- for (int i=0;i<weights.Length;i++)
- {
- double[] newFeature = GetNewFeature(data[i].Features);
- newWeights[i] = weights[i] - (tmp * newFeature[i]);
- }
- ChangeWeight(newWeights);
- }
- private double WholeSum(Data[] data)
- {
- double wholeSum = 0;
- for(int i=0;i<data.Length;i++)
- {
- wholeSum = Calculate(data[i].Features)-ToY(data[i].Classifcation);
- }
- return wholeSum;
- }
- public double Cost(Data[] data)
- {
- int m = data.Length;
- double cost = 0;
- for(int i=0;i<m;i++)
- {
- double y = ToY(data[i].Classifcation);
- double hypoSum=Calculate(data[i].Features);
- cost+=(y * Math.Log(hypoSum)) + ((1 - y) * Math.Log(1 - hypoSum));
- }
- return (-1.0*(1.0/m)*cost);
- }
- public double Calculate(double[] features)
- {
- if(features.Length!=featureCount)
- {
- throw new ArgumentException("Invalid feature count");
- }
- double[] newFeature = GetNewFeature(features);
- double sum = 0;
- for(int i=0;i< newFeature.Length;i++)
- {
- sum += newFeature[i] * weights[i];
- }
- return Sigmoid(sum);
- }
- private double Sigmoid(double hypoSum)
- {
- double exponent=Math.Exp(hypoSum * -1.0);
- return (1.0 / (1.0 + exponent));
- }
- private void ChangeWeight(double[] newWeights)
- {
- for(int i=0;i<weights.Length;i++)
- {
- weights[i] = newWeights[i];
- }
- }
- /// <summary>
- /// Change multiclass to the output that logistic regression know
- /// </summary>
- /// <param name="output"></param>
- /// <returns></returns>
- private double ToY(string output)
- {
- if(output==positiveResult)
- {
- return 1.0;
- }
- return 0.0;
- }
- /// <summary>
- /// Add a bias input
- /// </summary>
- /// <param name="features"></param>
- /// <returns></returns>
- private double[] GetNewFeature(double[] features)
- {
- double[] newFeature = new double[features.Length + 1];
- //bias input
- newFeature[0] = 1;
- for (int i = 1; i < newFeature.Length; i++)
- {
- newFeature[i] = features[i - 1];
- }
- return newFeature;
- }
- public string GetPositiveResult()
- {
- return positiveResult;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement