数据挖掘—BP神经网络(Java实现)

在这里插入图片描述


public class Test {public static void main(String args[]) throws Exception {ArrayList<ArrayList<Double>> alllist = new ArrayList<ArrayList<Double>>(); // 存放所有数据ArrayList<String> outlist = new ArrayList<String>(); // 存放分类的字符串int in_num = 0, out_num = 0; // 输入输出数据的个数DataUtil dataUtil = new DataUtil(); // 初始化数据dataUtil.NormalizeData("src/bp/train.txt");dataUtil.SetTypeNum(3); // 设置输出类型的数量dataUtil.ReadFile("src/bp/train.txt", ",", 0);in_num = dataUtil.GetInNum(); // 获得输入数据的个数out_num = dataUtil.GetOutNum(); // 获得输出数据的个数(个数代表类型个数)alllist = dataUtil.GetList(); // 获得初始化后的数据outlist = dataUtil.GetOutList();System.out.print("分类的类型:");for(int i =0 ;i<outlist.size();i++)System.out.print(outlist.get(i)+"  ");System.out.println();System.out.println("训练集的数量:"+alllist.size());BPNN bpnn = new BPNN();// 训练System.out.println("Train Start!");System.out.println(".............");bpnn.Train(in_num, out_num, alllist);System.out.println("Train End!");// 测试DataUtil testUtil = new DataUtil();testUtil.NormalizeData("src/bp/test.txt");testUtil.SetTypeNum(3); // 设置输出类型的数量testUtil.ReadFile("src/bp/test.txt", ",", 1);ArrayList<ArrayList<Double>> testList = new ArrayList<ArrayList<Double>>();ArrayList<ArrayList<Double>> resultList = new ArrayList<ArrayList<Double>>();ArrayList<String> normallist = new ArrayList<String>(); // 存放测试集标准的输出字符串ArrayList<String> resultlist = new ArrayList<String>(); // 存放测试集计算后的输出字符串double right = 0; // 分类正确的数量int type_num = 0; // 类型的数量double all_num = 0; //测试集的数量type_num = outlist.size();testList = testUtil.GetList(); // 获取测试数据normallist = testUtil.GetCheckList();int errorcount=0; // 分类错误的数量resultList = bpnn.ForeCast(testList); // 测试all_num=resultList.size();for (int i = 0; i < resultList.size(); i++) {String checkString = "unknow";for (int j = 0; j < type_num; j++) {if(resultList.get(i).get(j)==1.0){checkString = outlist.get(j);resultlist.add(checkString);}/*else{resultlist.add(checkString);}*/}/*if(checkString.equals("unknow"))errorcount++;*/if(checkString.equals(normallist.get(i)))right++;}System.out.println("测试集的数量:"+ (new Double(all_num)).intValue());System.out.println("分类正确的数量:"+(new Double(right)).intValue());System.out.println("算法的分类正确率为:"+right/all_num);System.out.println("分类结果存储在:E:\\BP_data\\result.txt");}
}
package bp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;class DataUtil {private ArrayList<ArrayList<Double>> alllist = new ArrayList<ArrayList<Double>>(); // 存放所有数据private ArrayList<String> outlist = new ArrayList<String>(); // 存放输出数据,索引对应每个everylist的输出private ArrayList<String> checklist = new ArrayList<String>();  //存放测试集的真实输出字符串private int in_num = 0;private int out_num = 0; // 输入输出数据的个数private int type_num = 0; // 输出的类型数量private double[][] nom_data; //归一化输入数据中的最大值和最小值private int in_data_num = 0; //提前获得输入数据的个数// 获取输出类型的个数public int GetTypeNum() {return type_num;}// 设置输出类型的个数public void SetTypeNum(int type_num) {this.type_num = type_num;}// 获取输入数据的个数public int GetInNum() {return in_num;}// 获取输出数据的个数public int GetOutNum() {return out_num;}// 获取所有数据的数组public ArrayList<ArrayList<Double>> GetList() {return alllist;}// 获取输出为字符串形式的数据public ArrayList<String> GetOutList() {return outlist;}// 获取输出为字符串形式的数据public ArrayList<String> GetCheckList() {return checklist;}//返回归一化数据所需最大最小值public double[][] GetMaxMin(){return nom_data;}// 读取文件初始化数据public void ReadFile(String filepath, String sep, int flag)throws Exception {ArrayList<Double> everylist = new ArrayList<Double>(); // 存放每一组输入输出数据int readflag = flag; // flag=0,train;flag=1,testString encoding = "GBK";File file = new File(filepath);if (file.isFile() && file.exists()) { // 判断文件是否存在InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式BufferedReader bufferedReader = new BufferedReader(read);String lineTxt = null;while ((lineTxt = bufferedReader.readLine()) != null) {int in_number = 0;String splits[] = lineTxt.split(sep); // 按','截取字符串if (readflag == 0) {for (int i = 0; i < splits.length; i++)try {everylist.add(Normalize(Double.valueOf(splits[i]),nom_data[i][0],nom_data[i][1]));in_number++;} catch (Exception e) {if (!outlist.contains(splits[i]))outlist.add(splits[i]); // 存放字符串形式的输出数据for (int k = 0; k < type_num; k++) {everylist.add(0.0);}everylist.set(in_number + outlist.indexOf(splits[i]),1.0);}} else if (readflag == 1) {for (int i = 0; i < splits.length; i++)try {everylist.add(Normalize(Double.valueOf(splits[i]),nom_data[i][0],nom_data[i][1]));in_number++;} catch (Exception e) {checklist.add(splits[i]); // 存放字符串形式的输出数据}}alllist.add(everylist); // 存放所有数据in_num = in_number;out_num = type_num;everylist = new ArrayList<Double>();everylist.clear();}bufferedReader.close();}}//向文件写入分类结果public void WriteFile(String filepath, ArrayList<ArrayList<Double>> list, int in_number,  ArrayList<String> resultlist) throws IOException{File file = new File(filepath);FileWriter fw = null;BufferedWriter writer = null;try {fw = new FileWriter(file);writer = new BufferedWriter(fw);System.out.println(resultlist.size());for(int i=0;i<resultlist.size()-1;i++){for(int j=0;j<in_number;j++)writer.write(list.get(i).get(j)+",");writer.write(resultlist.get(i));writer.newLine();}writer.flush();} catch (IOException e) {e.printStackTrace();}finally{writer.close();fw.close();}}//学习样本归一化,找到输入样本数据的最大值和最小值public void NormalizeData(String filepath) throws IOException{//提前获得输入数据的个数GetBeforIn(filepath);int flag=1;nom_data = new double[in_data_num][2];String encoding = "GBK";File file = new File(filepath);if (file.isFile() && file.exists()) { // 判断文件是否存在InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式BufferedReader bufferedReader = new BufferedReader(read);String lineTxt = null;while ((lineTxt = bufferedReader.readLine()) != null) {String splits[] = lineTxt.split(","); // 按','截取字符串for (int i = 0; i < splits.length-1; i++){if(flag==1){nom_data[i][0]=Double.valueOf(splits[i]);nom_data[i][1]=Double.valueOf(splits[i]);}else{if(Double.valueOf(splits[i])>nom_data[i][0])nom_data[i][0]=Double.valueOf(splits[i]);if(Double.valueOf(splits[i])<nom_data[i][1])nom_data[i][1]=Double.valueOf(splits[i]);}}flag=0;}bufferedReader.close();}}//归一化前获得输入数据的个数public void GetBeforIn(String filepath) throws IOException{String encoding = "GBK";File file = new File(filepath);if (file.isFile() && file.exists()) { // 判断文件是否存在InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式//提前获得输入数据的个数BufferedReader beforeReader = new BufferedReader(read);String beforetext = beforeReader.readLine();String splits[] = beforetext.split(",");in_data_num = splits.length-1;beforeReader.close();}}//归一化公式public double Normalize(double x, double max, double min){double y = 0.1+0.8*(x-min)/(max-min);return y;}
}
class BPNN {// private static int LAYER = 3; // 三层神经网络private static int NodeNum = 10; // 每层的最多节点数private static final int ADJUST = 5; // 隐层节点数调节常数private static final int MaxTrain = 2000; // 最大训练次数private static final double ACCU = 0.015; // 每次迭代允许的误差private double ETA_W = 0.5; // 权值学习效率0.5private double ETA_T = 0.5; // 阈值学习效率private double accu;// 附加动量项//private static final double ETA_A = 0.3; // 动量常数0.1//private double[][] in_hd_last; // 上一次的权值调整量//private double[][] hd_out_last;private int in_num; // 输入层节点数private int hd_num; // 隐层节点数private int out_num; // 输入出节点数private ArrayList<ArrayList<Double>> list = new ArrayList<>(); // 输入输出数据private double[][] in_hd_weight; // BP网络in-hidden突触权值private double[][] hd_out_weight; // BP网络hidden_out突触权值private double[] in_hd_th; // BP网络in-hidden阈值private double[] hd_out_th; // BP网络hidden-out阈值private double[][] out; // 每个神经元的值经S型函数转化后的输出值,输入层就为原值private double[][] delta; // delta学习规则中的值// 获得网络三层中神经元最多的数量public int GetMaxNum() {return Math.max(Math.max(in_num, hd_num), out_num);}// 设置权值学习率public void SetEtaW() {ETA_W = 0.5;}// 设置阈值学习率public void SetEtaT() {ETA_T = 0.5;}// BPNN训练public void Train(int in_number, int out_number,ArrayList<ArrayList<Double>> arraylist) throws IOException {list = arraylist;in_num = in_number;out_num = out_number;GetNums(in_num, out_num); // 获取输入层、隐层、输出层的节点数// SetEtaW(); // 设置学习率// SetEtaT();InitNetWork(); // 初始化网络的权值和阈值int datanum = list.size(); // 训练数据的组数int createsize = GetMaxNum(); // 比较创建存储每一层输出数据的数组out = new double[3][createsize];for (int iter = 0; iter < MaxTrain; iter++) {for (int cnd = 0; cnd < datanum; cnd++) {// 第一层输入节点赋值for (int i = 0; i < in_num; i++) {out[0][i] = list.get(cnd).get(i); // 为输入层节点赋值,其输入与输出相同}Forward(); // 前向传播Backward(cnd); // 误差反向传播}System.out.println("This is the " + (iter + 1)+ " th trainning NetWork !");accu = GetAccu();System.out.println("All Samples Accuracy is " + accu);if (accu < ACCU)break;}}// 获取输入层、隐层、输出层的节点数,in_number、out_number分别为输入层节点数和输出层节点数public void GetNums(int in_number, int out_number) {in_num = in_number;out_num = out_number;hd_num = (int) Math.sqrt(in_num + out_num) + ADJUST;if (hd_num > NodeNum)hd_num = NodeNum; // 隐层节点数不能大于最大节点数}// 初始化网络的权值和阈值public void InitNetWork() {// 初始化上一次权值量,范围为-0.5-0.5之间//in_hd_last = new double[in_num][hd_num];//hd_out_last = new double[hd_num][out_num];in_hd_weight = new double[in_num][hd_num];for (int i = 0; i < in_num; i++)for (int j = 0; j < hd_num; j++) {int flag = 1; // 符号标志位(-1或者1)if ((new Random().nextInt(2)) == 1)flag = 1;elseflag = -1;in_hd_weight[i][j] = (new Random().nextDouble() / 2) * flag; // 初始化in-hidden的权值//in_hd_last[i][j] = 0;}hd_out_weight = new double[hd_num][out_num];for (int i = 0; i < hd_num; i++)for (int j = 0; j < out_num; j++) {int flag = 1; // 符号标志位(-1或者1)if ((new Random().nextInt(2)) == 1)flag = 1;elseflag = -1;hd_out_weight[i][j] = (new Random().nextDouble() / 2) * flag; // 初始化hidden-out的权值//hd_out_last[i][j] = 0;}// 阈值均初始化为0in_hd_th = new double[hd_num];for (int k = 0; k < hd_num; k++)in_hd_th[k] = 0;hd_out_th = new double[out_num];for (int k = 0; k < out_num; k++)hd_out_th[k] = 0;}// 计算单个样本的误差public double GetError(int cnd) {double ans = 0;for (int i = 0; i < out_num; i++)ans += 0.5 * (out[2][i] - list.get(cnd).get(in_num + i))* (out[2][i] - list.get(cnd).get(in_num + i));return ans;}// 计算所有样本的平均精度public double GetAccu() {double ans = 0;int num = list.size();for (int i = 0; i < num; i++) {int m = in_num;for (int j = 0; j < m; j++)out[0][j] = list.get(i).get(j);Forward();int n = out_num;for (int k = 0; k < n; k++)ans += 0.5 * (list.get(i).get(in_num + k) - out[2][k])* (list.get(i).get(in_num + k) - out[2][k]);}return ans / num;}// 前向传播public void Forward() {// 计算隐层节点的输出值for (int j = 0; j < hd_num; j++) {double v = 0;for (int i = 0; i < in_num; i++)v += in_hd_weight[i][j] * out[0][i];v += in_hd_th[j];out[1][j] = Sigmoid(v);}// 计算输出层节点的输出值for (int j = 0; j < out_num; j++) {double v = 0;for (int i = 0; i < hd_num; i++)v += hd_out_weight[i][j] * out[1][i];v += hd_out_th[j];out[2][j] = Sigmoid(v);}}// 误差反向传播public void Backward(int cnd) {CalcDelta(cnd); // 计算权值调整量UpdateNetWork(); // 更新BP神经网络的权值和阈值}// 计算delta调整量public void CalcDelta(int cnd) {int createsize = GetMaxNum(); // 比较创建数组delta = new double[3][createsize];// 计算输出层的delta值for (int i = 0; i < out_num; i++) {delta[2][i] = (list.get(cnd).get(in_num + i) - out[2][i])* SigmoidDerivative(out[2][i]);}// 计算隐层的delta值for (int i = 0; i < hd_num; i++) {double t = 0;for (int j = 0; j < out_num; j++)t += hd_out_weight[i][j] * delta[2][j];delta[1][i] = t * SigmoidDerivative(out[1][i]);}}// 更新BP神经网络的权值和阈值public void UpdateNetWork() {// 隐含层和输出层之间权值和阀值调整for (int i = 0; i < hd_num; i++) {for (int j = 0; j < out_num; j++) {hd_out_weight[i][j] += ETA_W * delta[2][j] * out[1][i]; // 未加权值动量项/* 动量项* hd_out_weight[i][j] += (ETA_A * hd_out_last[i][j] + ETA_W* delta[2][j] * out[1][i]); hd_out_last[i][j] = ETA_A ** hd_out_last[i][j] + ETA_W delta[2][j] * out[1][i];*/}}for (int i = 0; i < out_num; i++)hd_out_th[i] += ETA_T * delta[2][i];// 输入层和隐含层之间权值和阀值调整for (int i = 0; i < in_num; i++) {for (int j = 0; j < hd_num; j++) {in_hd_weight[i][j] += ETA_W * delta[1][j] * out[0][i]; // 未加权值动量项/* 动量项* in_hd_weight[i][j] += (ETA_A * in_hd_last[i][j] + ETA_W* delta[1][j] * out[0][i]); in_hd_last[i][j] = ETA_A ** in_hd_last[i][j] + ETA_W delta[1][j] * out[0][i];*/}}for (int i = 0; i < hd_num; i++)in_hd_th[i] += ETA_T * delta[1][i];}// 符号函数signpublic int Sign(double x) {if (x > 0)return 1;else if (x < 0)return -1;elsereturn 0;}// 返回最大值public double Maximum(double x, double y) {if (x >= y)return x;elsereturn y;}// 返回最小值public double Minimum(double x, double y) {if (x <= y)return x;elsereturn y;}// log-sigmoid函数public double Sigmoid(double x) {return (double) (1 / (1 + Math.exp(-x)));}// log-sigmoid函数的倒数public double SigmoidDerivative(double y) {return (double) (y * (1 - y));}// tan-sigmoid函数public double TSigmoid(double x) {return (double) ((1 - Math.exp(-x)) / (1 + Math.exp(-x)));}// tan-sigmoid函数的倒数public double TSigmoidDerivative(double y) {return (double) (1 - (y * y));}// 分类预测函数public ArrayList<ArrayList<Double>> ForeCast(ArrayList<ArrayList<Double>> arraylist) {ArrayList<ArrayList<Double>> alloutlist = new ArrayList<>();ArrayList<Double> outlist = new ArrayList<Double>();int datanum = arraylist.size();for (int cnd = 0; cnd < datanum; cnd++) {for (int i = 0; i < in_num; i++)out[0][i] = arraylist.get(cnd).get(i); // 为输入节点赋值Forward();for (int i = 0; i < out_num; i++) {if (out[2][i] > 0 && out[2][i] < 0.5)out[2][i] = 0;else if (out[2][i] > 0.5 && out[2][i] < 1) {out[2][i] = 1;}outlist.add(out[2][i]);}alloutlist.add(outlist);outlist = new ArrayList<Double>();outlist.clear();}return alloutlist;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

特征工程tf-idf_特征工程-保留和删除的内容

特征工程tf-idfThe next step after exploring the patterns in data is feature engineering. Any operation performed on the features/columns which could help us in making a prediction from the data could be termed as Feature Engineering. This would include the…

monkey测试===通过monkey测试检查app内存泄漏和cpu占用

最近一直在研究monkey测试。网上资料很多&#xff0c;但都是一个抄一个的。原创的很少 我把检查app内存泄漏的情况梳理一下&#xff1a; 参考资料&#xff1a; Monkey测试策略&#xff1a;https://testerhome.com/topics/597 Android Monkey测试详细介绍&#xff1a;http://www…

三维空间两直线/线段最短距离、线段计算算法 【转】

https://segmentfault.com/a/1190000006111226d(ls,lt)|sj−tj||s0−t0(be−cd)u⃗ −(ae−bd)v⃗ ac−bd(ls,lt)|sj−tj||s0−t0(be−cd)u⃗ −(ae−bd)v⃗ ac−b2|具体实现代码如下&#xff08;C#实现&#xff09;&#xff1a; public bool IsEqual(double d1, double d2) { …

iOS绘圆形图-CGContextAddArc各参数说明

2019独角兽企业重金招聘Python工程师标准>>> 1.使用 UIGraphicsGetCurrentContext() 画圆 CGContextAddArc(<#CGContextRef _Nullable c#>, <#CGFloat x#>, <#CGFloat y#>, <#CGFloat radius#>, <#CGFloat startAngle#>, <#CGFlo…

[收藏转载]C# GDI+ 简单绘图(一)

最近对GDI这个东西接触的比较多&#xff0c;也做了些简单的实例&#xff0c;比如绘图板&#xff0c;仿QQ截图等&#xff0e; 废话不多说了&#xff0c;我们先来认识一下这个GDI&#xff0c;看看它到底长什么样. GDI&#xff1a;Graphics Device Interface Plus也就是图形设备接…

mybaties总结+hibernate总结

一、对原生态jdbc程序中问题总结 1.1 jdbc程序 需求&#xff1a;使用jdbc查询mysql数据库中用户表的记录 statement:向数据库中发送一个sql语句 预编译statement&#xff1a;好处&#xff1a;提高数据库性能。 预编译statement向数据库中发送一个sql语句&#xff0c;数据库编译…

Python14 函数

函数 面向对象编程&#xff1a; 类----class 面向过程编程&#xff1a;过程---def 函数式编程&#xff1a;函数---def def test(x):描述x 1return x#def是定义函数的关键字#test是函数名称#&#xff08;x&#xff09;是参数#x1是 函数体&#xff0c;是一段逻辑代码#return 定义…

pandas之数值计算与统计

数值计算与统计 对于DataFrame来说&#xff0c;求和、最大、最小、平均等统计方法&#xff0c;默认是按列进行统计&#xff0c;即axis 0&#xff0c;如果添加参数axis 1则会按照行进行统计。 如果存在空值&#xff0c;在统计时默认会忽略空值&#xff0c;如果添加参数skipna …

python自动化数据报告_如何:使用Python将实时数据自动化到您的网站

python自动化数据报告This tutorial will be helpful for people who have a website that hosts live data on a cloud service but are unsure how to completely automate the updating of the live data so the website becomes hassle free. For example: I host a websit…

android intent参数是上次的结果,【Android】7.0 Intent向下一个活动传递数据、返回数据给上一个活动...

1.0 可以利用Intent吧数据传递给上一个活动&#xff0c;新建一个叫“hellotest01”的项目。新建活动FirstActivity&#xff0c;勾选“Generate Layout File”和“Launcher Activity”。image修改AndroidMainifest.xml中的内容&#xff1a;android:name".FirstActivity&quo…

学习深度学习需要哪些知识_您想了解的有关深度学习的所有知识

学习深度学习需要哪些知识有关深层学习的FAU讲义 (FAU LECTURE NOTES ON DEEP LEARNING) Corona was a huge challenge for many of us and affected our lives in a variety of ways. I have been teaching a class on Deep Learning at Friedrich-Alexander-University Erlan…

html5--3.16 button元素

html5--3.16 button元素 学习要点 掌握button元素的使用button元素 用来建立一个按钮从功能上来说&#xff0c;与input元素建立的按钮相同button元素是双标签&#xff0c;其内部可以配置图片与文字&#xff0c;进行更复杂的样式设计不仅可以在表单中使用&#xff0c;还可以在其…

如何注册鸿蒙id,鸿蒙系统真机调试证书 和 设备ID获取

鸿蒙系统真机调试创建项目创建项目创建应用创建鸿蒙应用(注意&#xff0c;测试阶段需要发邮件申请即可)关联应用项目进入关联 添加引用准备调试使用的 p12 和证书请求 csr使用以下命令// 别名"test"可以修改&#xff0c;但必须前后一致&#xff0c;密码请自行修改key…

读zepto核心源码学习JS笔记(3)--zepto.init()

上篇已经讲解了zepto.init()的几种情况,这篇就继续记录这几种情况下的具体分析. 1. 首先是第一种情况,selector为空 既然是反向分析,那我们先看看这句话的代码; if (!selector) return zepto.Z() 这里的返回值为zepto.Z();那我们继续往上找zepto.Z()函数 zepto.Z function(dom…

置信区间估计 预测区间估计_估计,预测和预测

置信区间估计 预测区间估计Estimation implies finding the optimal parameter using historical data whereas prediction uses the data to compute the random value of the unseen data.估计意味着使用历史数据找到最佳参数&#xff0c;而预测则使用该数据来计算未见数据的…

鸿蒙系统还会推出吗,华为明年所有自研设备都升级鸿蒙系统,还会推出基于鸿蒙系统的新机...

不负期许&#xff0c;华为鸿蒙OS手机版如期而至。今日(12月15日)&#xff0c;鸿蒙OS 2.0手机开发者Beta版本正式上线&#xff0c;支持运行安卓应用&#xff0c;P40、Mate 30系列可申请公测。国内媒体报道称&#xff0c;华为消费者业务软件部副总裁杨海松表示&#xff0c;按照目…

C#中将DLL文件打包到EXE文件

1&#xff1a;在工程目录增加dll目录&#xff0c;然后将dll文件复制到此目录&#xff0c;例如&#xff1a; 2&#xff1a;增加引用&#xff0c;定位到工程的dll目录&#xff0c;选中要增加的dll文件 3&#xff1a;修改dll文件夹下面的dll文件属性 选中嵌入式资源&#xff0c;不…

Oracle VM Virtual Box的安装

安装Oracle VM Virtual Box安装扩展插件 选择"管理""全局设定" 在设置对话框中&#xff0c;选择"扩展" 选择"添加包" 找到"Oracle_VM_VirtualBox_Extension_Pack-4.1.18-78361"&#xff0c;点击"打开" 5&#x…

python 移动平均线_Python中的SMA(短期移动平均线)

python 移动平均线With the evolution of technology rapidly evolving, so do strategies in the stock market. In this post, I’ll go over how I created a SMA(Short Moving Average) strategy.随着技术的飞速发展&#xff0c;股票市场的策略也在不断发展。 在本文中&…

angular中的href=unsafe:我该怎么摆脱你的溺爱!!

解决方法&#xff1a;angular.module加入下面这行&#xff1a;&#xff08;依据Angular changes urls to “unsafe:” in extension page&#xff09; .config(function($compileProvider){//注:有些版本的angularjs为$compileProvider.urlSanitizationWhitelist(/^\s*(https?…