Carry.law

一枚最不像数分师的数据分析师

主页 关于 博文馆 - 自然语言处理 - 机器学习算法 - Python技术 - 数据库技术 - 可视化技术 - 产品思维 - 相关资讯 © 2021. All rights reserved.

机器学习算法 分类文章

  • 数分学长

手工编写神经网络实现数字识别

04 Jan 2020
预备知识: 1.手工计算一个神经网络 2.Python手工编写神经网络算法 实验数据: 训练集mnist_train_100 测试集mnist_test_10 · 手工编写一个神经网络 import numpy # scipy.special for the sigmoid function expit() import scipy.special # library for plotting arrays import matplotlib.pyplot # ensure the plots are inside this notebook, not an external window %matplotlib inline # neural network class definition class neuralNetwork: # initialise the neural network def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate): # set number of nodes in each input, hidden, output layer self.inodes = inputnodes self.hnodes = hiddennodes self.onodes = outputnodes # link weight matrices, wih and who # weights inside the arrays are w_i_j, where link is from node i to node j in the next layer # w11 w21 # w12 w22 etc self.wih = numpy.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes)) self.who = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes)) # learning rate self.lr = learningrate # activation function is the sigmoid function self.activation_function = lambda x: scipy.special.expit(x) pass # train the neural network def train(self, inputs_list, targets_list): # convert inputs list to 2d array inputs = numpy.array(inputs_list, ndmin=2).T targets = numpy.array(targets_list, ndmin=2).T # calculate signals into hidden layer hidden_inputs = numpy.dot(self.wih, inputs) # calculate the signals emerging from hidden layer hidden_outputs = self.activation_function(hidden_inputs) # calculate signals into final output layer final_inputs = numpy.dot(self.who, hidden_outputs) # calculate the signals emerging from final output layer final_outputs = self.activation_function(final_inputs) # output layer error is the (target - actual) output_errors = targets - final_outputs # hidden layer error is the output_errors, split by weights, recombined at hidden nodes hidden_errors = numpy.dot(self.who.T, output_errors) # update the weights for the links between the hidden and output layers self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)), numpy.transpose(hidden_outputs)) # update the weights for the links between the input and hidden layers self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), numpy.transpose(inputs)) pass # query the neural network def query(self, inputs_list): # convert inputs list to 2d array inputs = numpy.array(inputs_list, ndmin=2).T # calculate signals into hidden layer hidden_inputs = numpy.dot(self.wih, inputs) # calculate the signals emerging from hidden layer hidden_outputs = self.activation_function(hidden_inputs) # calculate signals into final output layer final_inputs = numpy.dot(self.who, hidden_outputs) # calculate the signals emerging from final output layer final_outputs = self.activation_function(final_inputs) return final_outputs · 训练这个神经网络 # number of input, hidden and output nodes input_nodes = 784 hidden_nodes = 200 output_nodes = 10 # learning rate learning_rate = 0.1 # create instance of neural network n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, learning_rate) # load the mnist training data CSV file into a list training_data_file = open("d:/mnist_train_100.csv", 'r') training_data_list = training_data_file.readlines() training_data_file.close() # train the neural network # epochs is the number of times the training data set is used for training epochs = 5 for e in range(epochs): # go through all records in the training data set for record in training_data_list: # split the record by the ',' commas all_values = record.split(',') # scale and shift the inputs inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # create the target output values (all 0.01, except the desired label which is 0.99) targets = numpy.zeros(output_nodes) + 0.01 # all_values[0] is the target label for this record targets[int(all_values[0])] = 0.99 n.train(inputs, targets) pass pass 测试这个神经网络 # load the mnist test data CSV file into a list test_data_file = open("d:\\mnist_test_10.csv", 'r') test_data_list = test_data_file.readlines() test_data_file.close() # test the neural network # scorecard for how well the network performs, initially empty scorecard = [] # go through all the records in the test data set for record in test_data_list: # split the record by the ',' commas all_values = record.split(',') # correct answer is first value correct_label = int(all_values[0]) # scale and shift the inputs inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # query the network outputs = n.query(inputs) # the index of the highest value corresponds to the label label = numpy.argmax(outputs) # append correct or incorrect to list if (label == correct_label): # network's answer matches correct answer, add 1 to scorecard scorecard.append(1) else: # network's answer doesn't match correct answer, add 0 to scorecard scorecard.append(0) pass pass # calculate the performance score, the fraction of correct answers scorecard_array = numpy.asarray(scorecard) print ("performance = ", scorecard_array.sum() / scorecard_array.size) all_values = test_data_list[0].split(",") print(all_values[0]) n.query((numpy.asfarray(all_values[1:])/255.0*0.99) + 0.01) ## ====输出结果(第7行最大)==== array([[0.09974942], [0.03166885], [0.06538583], [0.0988961 ], [0.09711381], [0.05002152], [0.01467066], [0.73531968], [0.08138323], [0.08918561]])

Python手工编写神经网络算法

04 Jan 2020
  之前写过手工计算一个神经网络,那么如何用python编写一个神经网络呢?接下来便试着一步步实现。神经网络一共分为三块,初始网络、训练网络、查询网络,由此所编写的代码框架如下: # 神经网络框架 class neuralNetwork: # 初始网络 def __int__(): pass # 训练网络 def train(): pass # 查询网络 def query(): pass · 完整的神经网络代码 import scipy.special import numpy class neuralNetwork: # 初始网络 def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate): # 设置输入、输出、隐藏层 self.inodes = inputnodes self.hnodes = hiddennodes self.onodes = outputnodes # 设置权重 self.wih = numpy.random.normal(0.0, pow(self.hnodes, -0.5),(self.hnodes,self.inodes)) self.who = numpy.random.normal(0.0, pow(self.onodes, -0.5),(self.onodes,self.hnodes)) # 设置学习率 self.lr = learningrate # 构建sigmiod函数 self.activation_function = lambda x: scipy.special.expit(x) pass # 训练网络 def train(self, inputs_list, targets_list): # 第一层输入 inputs = numpy.array(inputs_list,ndmin=2).T targets= numpy.array(targets_list,ndmin=2).T # 隐藏层输入 # X隐含 = W权重 * I输入 hidden_inputs = numpy.dot(self.wih, inputs) # 隐藏层输出 hidden_outputs = self.activation_function(hidden_inputs) # 最终层输入 final_inputs = numpy.dot(self.wih, hidden_outputs) # 最终层输出 final_outputs = self.activation_function(final_inputs) # 误差值 output_errors = targets- final_outputs # 反向传播 error隐藏 = WT隐藏 * error输出 hidden_errors = numpy.dot(self.who.T,output_errors) # 传播隐藏到输出 self.who = self.who + self.lr* numpy.dot((output_errors*final_outputs*(1.0-final_outputs)),numpy.transpose(hidden_outputs)) # 传播输入到隐藏 self.wih = self.wih + self.lr* numpy.dot((output_errors*hidden_outputs*(1.0-hidden_outputs)),numpy.transpose(inputs)) pass # 输出网络 def query(self, inputs_list): # 第一层输入 inputs = numpy.array(inputs_list,ndmin=2).T # 隐藏层输入 # X隐含 = W权重 * I输入 hidden_inputs = numpy.dot(self.wih, inputs) # 隐藏层输出 hidden_outputs = self.activation_function(hidden_inputs) # 最终层输入 final_inputs = numpy.dot(self.wih, hidden_outputs) # 最终层输出 final_outputs = self.activation_function(final_inputs) return final_outputs · 训练这个神经网络,并输出相应结果 # 输入层、隐含层、输出层节点数 input_nodes =3 hidden_nodes =3 output_nodes =3 # 学习率 learningrate = 0.3 # 训练一个神经网络 n = neuralNetwork(input_nodes,hidden_nodes,output_nodes,learningrate) # 查询网络 n.query([1,0.5,-1.5]) # ====最终输出结果(数值可能不相同)==== array([[0.40511455], [0.40580834], [0.50113563]])

手工计算一个神经网络

26 Nov 2019
  神经网络算法作为深度学习的基础,其重要性不言而喻。然而大部分同学,在实际学习过程中却总不得其门而入。某天受高人指点尝试去手工计算一个三层神经网络,于是一通百通,不仅了解了神经网络工作原理的本质、调优的方法,还用python自写了一套基础版的神经网络算法。本篇博文便一步步的将整个推导过程重现一遍。 1. 了解Sigmoid函数   Sigmoid函数(简称S函数) 对于大家来说并不陌生,其公式为:y = 1/1+E(-x)。当x趋近无穷大时,y趋近于1;当x趋近无穷小时,y趋近于0。因此S函数的输入x可以为任意数,而输出y必介于0到1之间。   那么S函数在神经网络中起什么作用呢,大家可以想象一下神经网络是由多个神经元共同作用而成,而神经元的工作方式是在接受输入到达一定量级的时候,才产生相应的输出。因此我们用S函数模拟神经元的工作方式,即当输入x到达一定界值时,S函数(神经元)就激发了。 我们举个例子计算一个神经元的输入及输出 例:假设x1=0.05,x2=0.25,x3=0.75求S函数的解 x = x1+x2+x3 = 0.05+0.25+0.75 = 1.05 y = 1/1+E(-x) = 1/1+E(-1.05) = 0.7488 2. 了解W权重   图1中可以看到,神经网络每个神经元之间都会有连接,而每个连接上都会有相应的权重W,那么神经网络前后层之间为什么要相互连接呢?第一,这种完全连接的方式可以相对容易编辑成计算机指令,第二,神经网络在迭代学习过程中自身会弱化不需要的链接,即权重趋近于0。在这里我们需要注意初始权重是随机值,神经网络需要做的就是不断调整权重以最大降低预测值与真实值之间的误差。加入权重后,单个神经元的计算方式如下图: # 第2层第1个神经元输入x x = (x1*w1,1)+(x2*w1,2)+(x3*w1,3) = 1*0.9+0.5*0.2+0.5*0.1 = 1.05 # 第2层第1个神经元输出y y = 1/1+E(-x) = 1/1+E(-1.05) = 0.7488 3. 计算一个三层神经网络   这里我们先用最基础的方法去计算三层神经网络的输出结果,由于第三层(输出层)每个神经元的计算方式不尽相同,因此我们只计算第三层第一个神经元的输出,如下图: 这样我们就成功计算了一个三层神经网络的输出结果,是不是挺容易的?! 4. 借助矩阵计算神经网络   这里我们借助矩阵的方式去实现3中三层神经网络的计算,如下图: 这里我们极大的简化了神经网络的计算方式,并获得了相同的输出结果。后续用Python实现神经网络算法, 5. 如何计算反向传播误差   误差代表的是我们实际值与预测值之间的差异,即误差e=实际值t-预测值o。在误差反向传播的过程中,我们按照W权重来分配每个神经元的误差,如下图: 这里我们也可以借助矩阵来计算误差,图中e(hidden)=W(hidden_output)的转置矩阵*e(output) 6. 如何使用误差来调整权重   计算误差的目的,就是告诉神经网络如何去调整矩阵权重,以使得迭代计算出的预测值不断趋近于真实值。这里直接给出权重计算的公式,如下图: 这样我们整个神经网络的已经计算完成,最后强烈推荐一本书《Python神经网络编程》塔里克·拉希德著,接下来我们再试着用Python来实现一遍。

Python机器学习之协同过滤

17 Oct 2018
  协同过滤指的是关联推荐的一种思路,而不是指的某种特定的算法。它的思路非常简单,首先我将具有相同特征的客户放到一个类中,例如客户A与B相似,然后将客户A所购买过的产品直接推荐给客户B,反之亦然。   本文抛砖引玉,主要实现一个基于用户的协同过滤模型,若有兴趣的同学,后续可以从以下几个方面进行延伸:   1.如何用相同的方法实现基于产品的协同过滤模型;   2.如何利用其他相似度计算方法(余弦距离、聚类等)改进协同过滤模型;   协同过滤需要两份数据,包括用户特征信息表UserandFeature和用户产品关联表UserandLabel · 基于用户协同过滤python程序 import csv import math import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler # ==== 1.数据预处理 ==== data = pd.read_csv('d:\\UserandFeature.csv',sep=',',encoding='gbk') # fillna()是pandas函数,用于数据填充(向前填充) data = data.fillna(method = 'ffill', axis = 1).values # MinMaxScaler最大最小标准化公式:X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0)) scaler = MinMaxScaler(feature_range=(0,1)) dataset = scaler.fit_transform(data) # DataFrame是pandas表格框架,目的是为了打出UserandFeature表格 # dataset1 = pd.DataFrame(dataset) # dataset1.to_csv('d:\\UserandFeature1.csv', mode='w', header=False) # ==== 2.相似度计算 ==== def Pearson(vec1, vec2): vec1_ = vec1 - np.mean(vec1) vec2_ = vec2 - np.mean(vec2) sum = np.dot(vec1_, vec2_) / (np.linalg.norm(vec1_) * np.linalg.norm(vec2_)) return sum # dataset.shape[0]表示array的行数 for i in range(dataset.shape[0]): vec1 = dataset[i-1] corr=[] for j in range(dataset.shape[0]): vec2 = dataset[j-1] corr.append(Pearson(vec1, vec2)) # 将结果打印到SimilarityofUsers表中 with open('d:\\SimilarityofUsers.csv','a',newline='') as csvfile: writer = csv.writer(csvfile) writer.writerow(corr) # ==== 3.基于用户的推荐 ==== similarity = pd.read_csv('d:\\SimilarityofUsers.csv').values # 导入用户产品关联列表,第一列表示用户,第二列表示产品(无表头) label = pd.read_csv('d:\\UserandLabel.csv').values.tolist() # 读取相似度列表 for m in range(similarity.shape[0]): a=[m+1] for n in range(similarity.shape[0]): if similarity[m,n] > 0.85: a.append(label[n-1]) else: continue # 将结果打印到recommend表中 with open('d:\\recommend.csv','a',newline='') as csvfile: writer = csv.writer(csvfile) writer.writerow(a)

Python机器学习之因子分析

24 May 2018
  最近分析客户偏好的时候用到了因子分析,感觉是NLP与机器学习一个不错的结合点,遂在此记录一下。   因子分析的主要目的就是为了降维,意思是将多个字段的值按照不同的权重合为一个字段,其前提条件是需要合并的几个字段具有相关性,百度上有很多关于因子分析的计算公式,大家可以自行搜索一下,本文只给出因子分析的python计算程序。   这是借助因子分子做的客户偏好雷达图:   原始数据集下载地址:yinzifenxi.csv · 因子分析python程序 import csv import numpy as np from sklearn.decomposition import FactorAnalysis # ==== 读取原始数据集 ==== with open("d:\\yinzifenxi.csv","r") as f: # 读取原始CSV文件路径 data1 = np.loadtxt(f,delimiter=",",skiprows=1) f = open("d:\\yinzifenxi.csv","r") rows_dict = csv.DictReader(f) # print(data1) # 打印原文件数据 # ==== 创建空白的CSV文件 ==== fieldnames = ['frequency','avg','coverage','yinzifenxi'] f1 = open("d:\\yinzifenxi1.csv","w",newline='') # 创建一个空白新的CSV文件 writer = csv.DictWriter(f1,fieldnames=fieldnames) # ==== 因子分析 ==== data = np.array(data1[1:], dtype = np.float64) # 从第二行开始 fa = FactorAnalysis(n_components = 1) # 因子分析参数设置 1表示一维 fa.fit(data) # 因子分子数据输入 tran_data = fa.transform(data) tran_data1=tran_data[:,0] # print (tran_data1) # 打印因子分析结果 # ==== 将结果输入到CSV文件 ==== writer.writeheader() for i,row in enumerate(rows_dict): # 将结果写入CSV row['yinzifenxi'] = tran_data1[i-1] writer.writerow(row) · 因子分析结果

机器学习之聚类评估指标(轮廓系数)

28 Apr 2018
  最近在整理聚类算法的时候偶然发现一个指标——轮廓系数,仔细研究之后发现是一个易于理解的用来评估聚类效果好坏的指标,因此在这里和大家分享一样。轮廓系数的值介于[-1,1]之间,越趋于1代表聚类效果越好,具体计算方法如下: 1. 计算样本i到同簇其他所有样本的平均距离,记为a(i)。a(i)越接近0则表示样本i聚类效果越好。 2. 计算样本i到其他每个簇中所有样本的平均距离,选取平均距离最小的值记为b(i)。b(i)越大则表示样本i聚类效果越好。 3. 计算b(i)与a(i)的极差,除以max{a(i),b(i)},这时就会出现以下3种场景: 4. 判别结果: 若s(i)接近1,则说明样本i聚类合理; 若s(i)接近-1,则样本i更应该分类到另外的簇; 若s(i)接近0,则说明样本i在两个簇的边界上; 注意:轮廓系数相关程序已在Python之 文本聚类中给出,大家可自行研究。

机器学习之模型评估(ROC曲线)

23 Jan 2018
  模型评估一直是数据建模中不可或缺的一环,评估指标的好坏直接关系到模型上线运用的情况。本文期望以最直观的方式告诉大家模型评估的相关指标,并手动绘制令诸多同学疑惑的ROC曲线。在此希望大家注意:模型评估指标只能作为参考依据,在真正的项目实施过程中,还是需要针对具体业务具体分析。 分类模型(贝叶斯、决策树、SVM等)评估指标: 评估指标 具体描述 sklearn对应函数 Precision 精准度 from sklearn.metrics import precision_score Recall 召回率 from sklearn.metrics import recall_score F1 F1值 from sklearn.metrics import f1_score Confusion Matrix 混淆矩阵 from sklearn.metrics import confusion_matrix ROC ROC曲线 from sklearn.metrics import roc AUC ROC曲线下的面积 from sklearn.metrics import auc 回归模型(线性回归、非线性回归等)评估指标: 评估指标 具体描述 sklearn对应函数 Mean Square Error(MSE/RMSE) 平均方差 from sklearn.metrics import mean_squared_error Absolute Error(MAE/RAE) 绝对误差 from sklearn.metrics import mean_absolute_error, median_absolute_error R-Squared(R^2) R平方值 from sklearn.metrics import r2_score · 混淆矩阵、ROC曲线与AUC面积 问题1:混淆矩阵是什么? 回答1:混淆矩阵说简单一点就是预测的正例/反例与真实值之间的比例关系,该矩阵包括4个方面: 预测值 真实值 对应指标 正例 正例 True Positive(TP) 正例 反例 False Positive(FP) 反例 正例 True Negative(TN) 反例 反例 False Negative(FN) 混淆矩阵图如下: 由此计算: True Positive Rate真实的正例中,被预测正确的比例:TPR = TP/(TP+FN) False Positive Rate真实的反例中,被预测正确的比例:FPR = FP/(FP+TN) 问题2:混淆矩阵、ROC曲线与AUC面积之间的关系? 回答2:ROC曲线(Receiver Operating Characteristic)主要用于评估二分类模型的优劣,其绘图时X轴和Y轴分别对应混淆矩阵中FPR和TPR,其下方包围的面积为AUC(Area Under the Curve)。 问题3:ROC曲线如何绘制? 回答3:一条曲线的绘制必须是多个点的连线,那么我们就需要在坐标轴上描出多个点,以此来绘制ROC曲线,具体步骤如下: (1)假设我们有一个100行的数据集,按照9:1划分为训练集和测试集; (2)接下来我们建立二分类模型并预测结果,这时10行的测试集中每个观测都应该有一个对应的原始分类和预测概率; 测试集 原始分类 预测概率 测试集 原始分类 预测概率 1 P 0.9 6 P 0.49 2 P 0.8 7 N 0.38 3 N 0.7 8 N 0.31 4 P 0.6 9 P 0.3 5 P 0.54 10 N 0.1 (4)这时我们依次将10个预测概率作为阈值threshold,当准确度大于或等于这个值的时候,预测结果为P,否则为N,例如,预测概率值为0.6,那么测试集结果为: 测试集 原始分类 预测分类 测试集 原始分类 预测分类 1 P P 6 P N 2 P P 7 N N 3 N P 8 N N 4 P P 9 P N 5 P N 10 N N 由此绘制混淆矩阵: 计算TPR与FPR: TPR = TP/(TP+FN) = 0.3/(0.3+0.3) = 0.5 FPR = FP/(FP+TN) = 0.3/(0.1+0.3) = 0.75 据此,我们每更换一次阈值threshold,就能计算出一组TPR与FPR,那么这个数据集就应该能计算出10组TPR与FPR(其余9组请同学自行推算,不再写出具体计算过程) (5)由此,我们以FPR为横坐标,TPR为纵坐标,描出所有的坐标点并连线,最终汇出ROC曲线,这里给出ROC曲线样例如下:

Python机器学习之非线性回归

13 Oct 2017
  非线性回归相较于线性回归而言,总带有一丢丢复杂的神秘感。关于线性回归模型相信各位已耳熟能详,因此这里主要讨论非线性回归模型。其实非线性回归中很大一部分是基于多项式的回归模型,即利用曲线方程代替直线方程拟合坐标图上各点,使得各点到曲线的距离总和最短。   一元m次多项式回归方程为:   二元二次多项式回归方程为:   多项式回归的最大优点就是可以通过增加x的高次项对实测点进行逼近,直至满意为止。事实上,多项式回归可以处理很大一类非线性问题,它在分析中占有重要的地位,因为任何一个函数都可以分段用多项式来逼近。   举一个房屋价格与房屋尺寸非线性拟合的实例,数据集下载地址:prices.txt · 算法构建代码 # python -version 3.5+ import matplotlib.pyplot as plt import numpy as np from sklearn import linear_model from sklearn.preprocessing import PolynomialFeatures # 读取数据集 datasets_X = [] #建立datasets_X储存房屋尺寸数据 datasets_Y = [] #建立datasets_Y储存房屋成交价格数据 fr = open('E:\\prices.txt', 'r', encoding='utf-8') #指定prices.txt数据集所在路径 lines = fr.readlines() #读取一整个文件夹 for line in lines: #逐行读取,循环遍历所有数据 items = line.strip().split(",") #变量之间按逗号进行分隔 datasets_X.append(int(items[0])) #读取的数据转换为int型 datasets_Y.append(int(items[1])) # 数据预处理 length = len(datasets_X) datasets_X = np.array(datasets_X).reshape([length, 1]) #将datasets_X转化为数组 datasets_Y = np.array(datasets_Y) minX = min(datasets_X) #以数据datasets_X的最大值和最小值为范围,建立等差数列,方便后续画图 maxX = max(datasets_X) X = np.arange(minX, maxX).reshape([-1, 1]) # 数据建模 poly_reg = PolynomialFeatures(degree=2) #degree=2表示二次多项式 X_poly = poly_reg.fit_transform(datasets_X) #构造datasets_X二次多项式特征X_poly lin_reg_2 = linear_model.LinearRegression() #创建线性回归模型 lin_reg_2.fit(X_poly, datasets_Y) #使用线性回归模型学习X_poly和datasets_Y之间的映射关系 · 测试结果代码 # 查看回归系数 print('Coefficients:',lin_reg_2.coef_) # 查看截距项 print('intercept:',lin_reg_2.intercept_) # 数据可视化 plt.scatter(datasets_X, datasets_Y, color='orange') plt.plot(X, lin_reg_2.predict(poly_reg.fit_transform(X)), color='blue') plt.xlabel('Area') plt.ylabel('Price') plt.show() · 部分结果展示 相关系数Coefficients: [ 0.00000000e+00 4.93982848e-02 1.89186822e-05] 截距项intercept: 151.846967505 非线性回归公式:Y = 151.8470 + 4.9398e-02*x + 1.8919e-05*x^2 非线性拟合图:

Python机器学习之逻辑回归

30 Aug 2017
  逻辑回归(Logistic Regression)是比较常见的机器学习算法之一,与SVM支持向量机类似,属于典型的 二分类算法。但逻辑回归相较于SVM的优点在于,前者不仅能够预测某事件是否将会发生,还包含该事件发生的可能性。例如想要知道张三是否会购买产品A,SVM所预测的结果只能告诉你,张三会购买或者不会购买,但逻辑回归能告诉你,张三有70%的概率购买产品A,从而你可以根据自己的业务设置风险率阀值。   关于逻辑回归的数学公式百度、Google已经有很好的解答,遂不再赘述。本博文主要介绍如何利用Python实现逻辑回归算法,该算法并没有引用sklearn包,因此具有一定的复杂度,但所实现的算法具有相当高的灵活性,适用于大规模数据分析系统的开发。   偏好使用sklearn的朋友,请跳转:sklearn主要模块和基本使用   输入数据集下载地址:训练集train,测试集test,预测集predict.txt · 算法构建代码 # python -version 3.5+ import numpy as np from numpy import * ## 构建sigmoid函数 def sigmoid(x): return .5 * (1 + np.tanh(.5 * x)) ## 训练逻辑回归模型 def trainLogRegres(train_x, train_y, opts): # 构建训练样本 numSamples, numFeatures = shape(train_x) alpha = opts['alpha'] maxIter = opts['maxIter'] weights = ones((numFeatures, 1)) # 选择最优的梯度下降法 for k in range(maxIter): if opts['optimizeType'] == 'gradDescent': # 梯度下降法 output = sigmoid(train_x * weights) error = train_y - output weights = weights + alpha * train_x.transpose() * error elif opts['optimizeType'] == 'stocGradDescent': # 随机梯度下降法 for i in range(numSamples): output = sigmoid(train_x[i, :] * weights) error = train_y[i, 0] - output weights = weights + alpha * train_x[i, :].transpose() * error elif opts['optimizeType'] == 'smoothStocGradDescent': # 平稳随机梯度下降法 dataIndex = list(range(numSamples)) for i in range(numSamples): alpha = 4.0 / (1.0 + k + i) + 0.01 randIndex = int(random.uniform(0, len(dataIndex))) output = sigmoid(train_x[randIndex, :] * weights) error = train_y[randIndex, 0] - output weights = weights + alpha * train_x[randIndex, :].transpose() * error del (dataIndex[randIndex]) else: raise NameError('Not support optimize method type!') return weights ## 检验逻辑回归模型 def testLogRegres(weights, test_x, test_y): numSamples, numFeatures = shape(test_x) matchCount = 0 for i in range(numSamples): predict = sigmoid(test_x[i, :] * weights)[0, 0] > 0.5 #设置阀值为0.5 if predict == bool(test_y[i, 0]): matchCount += 1 accuracy = float(matchCount) / numSamples return accuracy ## 预测逻辑回归模型 def preLogRegres(weights ,pre_x): numSamples, numFeatures = shape(pre_x) outfile = open('D://predict_result.txt', 'w') # 将概率值输出到文件 for i in range(numSamples): predict = sigmoid(pre_x[i, :] * weights)[0, 0] predict_m = sigmoid(pre_x[i, :] * weights)[0, 0] > 0.5 #是否阀值定为0.5 outfile.write(str(predict)+'\n') print(str(predict_m) + ' ' + str(predict)) #同时输出是否及概率值 outfile.close() · 测试结果代码 ## step 1: 模型训练 def loadData(): # 载入训练集 train_x = [] train_y = [] fileIn = open('D://train.txt') for line in fileIn.readlines(): lineArr = line.split() #设置分隔符 train_x.append([1.0, float(lineArr[0]), float(lineArr[1])]) train_y.append(float(lineArr[-1])) return mat(train_x), mat(train_y).transpose() fileIn.close() train_x, train_y = loadData() opts = {'alpha': 0.01, 'maxIter': 20, 'optimizeType': 'smoothStocGradDescent'} # 参数设置 optimalWeights = trainLogRegres(train_x, train_y, opts) ## step 2: 模型检验 def loadData1(): test_x = [] test_y = [] fileIn = open('D://test.txt') for line in fileIn.readlines(): lineArr = line.split() test_x.append([1.0, float(lineArr[0]), float(lineArr[1])]) test_y.append(float(lineArr[-1])) return mat(test_x), mat(test_y).transpose() fileIn.close() test_x, test_y = loadData1() accuracy = testLogRegres(optimalWeights, test_x, test_y) print('模型预测精度:' + str(accuracy)) print('================================') ## step 3: 模型预测 def loadData2(): pre_x = [] fileIn = open('D://predict.txt') for line in fileIn.readlines(): lineArr = line.split() pre_x.append([1.0, float(lineArr[0]), float(lineArr[1])]) return mat(pre_x) fileIn.close() pre_x = loadData2() print('模型预测结果:') predict = preLogRegres(optimalWeights, pre_x) · 部分结果展示 模型预测精度:0.9215686274509803 ================================ 模型预测结果: True 0.969439134428 False 0.0121320687856 True 0.999891075052 False 0.0276136702724 True 0.948171859849 True 0.999981963204 True 0.960074174269 True 0.999639571954 True 0.999979133078 True 0.99509838304 True 0.999965399666 True 0.999948401765 False 0.00443630610109 ···