Deeplearning Algorithms tutorial

谷歌的人工智能位于全球前列,在图像识别、语音识别、无人驾驶等技术上都已经落地。而百度实质意义上扛起了国内的人工智能的大旗,覆盖无人驾驶、智能助手、图像识别等许多层面。苹果业已开始全面拥抱机器学习,新产品进军家庭智能音箱并打造工作站级别Mac。另外,腾讯的深度学习平台Mariana已支持了微信语音识别的语音输入法、语音开放平台、长按语音消息转文本等产品,在微信图像识别中开始应用。全球前十大科技公司全部发力人工智能理论研究和应用的实现,虽然入门艰难,但是一旦入门,高手也就在你的不远处! AI的开发离不开算法那我们就接下来开始学习算法吧!

模糊c-均值聚类算法(Fuzzy C-means Algorithm)

模糊c-均值聚类算法,是一种基于目标函数的模糊聚类算法,主要用于数据的聚类分析。理论成熟,应用广泛,是一种优秀的聚类算法。 模糊c-均值聚类算法输入就是一个待聚类的数据集,每一个数据都有p个特征。它的输出是一个c行n列的矩阵U,c刚才提到是聚类数目,n是数据集中元素的个数,用这个矩阵就可以表示分类的结果,因为你看某一列,表示的就是这个元素对各个类的隶属程度,哪一个值最大,就说这个元素属于哪一类。

还有一个输出是各个类的聚类中心向量集合V,一共有c个元素。每个元素也是有p维的。

模糊c-均值聚类算法(Fuzzy C-means Algorithm) - 图1

模糊c-均值聚类算法(Fuzzy C-means Algorithm) - 图2

模糊c-均值聚类算法(Fuzzy C-means Algorithm) - 图3

应用示例

  1. typedef struct{
  2. double x;
  3. double y;
  4. } Position;
  5. //len:节点数量
  6. //range:节点xy值的范围
  7. Position *randomPosition(int len, int range){
  8. srand((unsigned)time(NULL));
  9. Position *allPos = (Position *)malloc(len * sizeof(Position));
  10. short a = 1;
  11. for (int i = 0; i < len; ++i)
  12. {
  13. if (a)
  14. {
  15. allPos[i].x = (double)rand() / 2147483647 * range;
  16. allPos[i].y = (double)rand() / 2147483647 * range;
  17. a = 0;
  18. }
  19. else if (!a)
  20. {
  21. allPos[i].x = (double)rand() / 2147483647 * range+50;
  22. allPos[i].y = (double)rand() / 2147483647 * range+50;
  23. a = 1;
  24. }
  25. }
  26. return allPos;
  27. }
  28. //posNum:节点数量
  29. //clusterNum:聚类中心数量
  30. double **init(int posNum, int clusterNum){
  31. double **u = (double **)malloc(sizeof(double *) * clusterNum);
  32. for (int i = 0; i <clusterNum; ++i)
  33. {
  34. u[i] = (double *)malloc(sizeof(double) * posNum);
  35. }
  36. srand((unsigned)time(NULL));
  37. double sum;
  38. //初始化usigmaU[i]=1
  39. for (int i = 0; i < posNum; ++i)
  40. {
  41. sum=1;
  42. for (int x = 0; x < clusterNum - 1; ++x)
  43. {
  44. u[x][i] = ((double)rand() / 2147483647) * sum;
  45. sum -= u[x][i];
  46. printf("u[%d][%d]:%f ",x,i,u[x][i]);
  47. }
  48. u[clusterNum-1][i]=sum;
  49. printf("u[%d][%d]:%f\n",clusterNum-1,i,u[clusterNum-1][i]);
  50. }
  51. return u;
  52. }
  53. //allPos:节点数组
  54. //len:节点数量
  55. void outputPos(Position *allPos, int len){
  56. for (int i = 0; i < len; ++i)
  57. printf("position %d:(%f,%f)\n", i, allPos[i].x, allPos[i].y);
  58. return;
  59. }
  60. //u:隶属度矩阵
  61. //posNum:节点数量
  62. //i:第i个聚类中心
  63. //m:隶属度因子
  64. double sumUi(double** u,int posNum,int i,int m){
  65. double res=0;
  66. for(int x=0;x<posNum;++x)
  67. res+=pow(u[i][x],m);
  68. return res;
  69. }
  70. //u:隶属度矩阵
  71. //allPos:节点数组
  72. //posNum:节点数量
  73. //i:第i个聚类中心
  74. //m:隶属度因子
  75. double sumXi(double** u,Position* allPos,int posNum,int i,int m){
  76. double res=0;
  77. for(int x=0;x<posNum;++x)
  78. res+=allPos[x].x*pow(u[i][x],m);
  79. return res;
  80. }
  81. //u:隶属度矩阵
  82. //posNum:节点数量
  83. //i:第i个聚类中心
  84. //m:隶属度因子
  85. double sumYi(double** u,Position* allPos,int posNum,int i,int m){
  86. double res=0;
  87. for(int x=0;x<posNum;++x)
  88. res+=allPos[x].y*pow(u[i][x],m);
  89. return res;
  90. }
  91. //pos:第j个节点
  92. //cluster:聚类中心数组
  93. //clusterNum:聚类中心数量
  94. //m:隶属度因子
  95. double sumDis(Position pos,Position* cluster,int clusterNum,int m){
  96. double res=0;
  97. for(int i=0;i<clusterNum;++i)
  98. res+=(double)1/pow(pow(pos.x-cluster[i].x,2)+pow(pos.y-cluster[i].y,2),(double)1/(m-1));
  99. return res;
  100. }
  101. //allPos:节点数组
  102. //cluster:聚类中心数组
  103. //u:隶属度矩阵
  104. //posNum:节点数量
  105. //clusterNum:聚类中心数量
  106. //m:隶属度因子
  107. void updateCluster(Position* allPos,Position* cluster,double** u,int posNum,int clusterNum,int m){
  108. for(int i=0;i<clusterNum;++i){
  109. cluster[i].x=sumXi(u,allPos,posNum,i,m)/sumUi(u,posNum,i,m);
  110. cluster[i].y=sumYi(u,allPos,posNum,i,m)/sumUi(u,posNum,i,m);
  111. }
  112. }
  113. //allPos:节点数组
  114. //cluster:聚类中心数组
  115. //u:隶属度矩阵
  116. //posNum:节点数量
  117. //clusterNum:聚类中心数量
  118. //m:隶属度因子
  119. void updateU(Position* allPos,Position* cluster,double** u,int posNum,int clusterNum,int m){
  120. double disXI;
  121. for(int i=0;i<clusterNum;++i)
  122. for(int x=0;x<posNum;++x){
  123. disXI=pow(pow(allPos[x].x-cluster[i].x,2)+pow(allPos[x].y-cluster[i].y,2),(double)1/(m-1));
  124. u[i][x]=(double)1/(disXI*sumDis(allPos[x],cluster,clusterNum,m));
  125. }
  126. }
  127. //allPos:节点数组
  128. //cluster:聚类中心数组
  129. //u:隶属度矩阵
  130. //posNum:节点数量
  131. //clusterNum:聚类中心数量
  132. //m:隶属度因子
  133. void outpuCost_fun(Position* allPos,Position* cluster,double** u,int posNum,int clusterNum,int m){
  134. double res=0;
  135. for(int i=0;i<clusterNum;++i)
  136. for(int x=0;x<posNum;++x)
  137. res+=(pow(u[i][x],m)*(pow(allPos[x].x-cluster[i].x,2)+pow(allPos[x].y-cluster[i].y,2)));
  138. printf("costFun:%f\n",res);
  139. }
  140. void outputU(double** u,int posNum,int clusterNum){
  141. for(int i=0;i<posNum;++i){
  142. for(int x=0;x<clusterNum;++x)
  143. printf("u[%d][%d]:%f ",x,i,u[x][i]);
  144. printf("\n");
  145. }
  146. }
  147. void fuzzy_Cmeans(int posNum,int clusterNum, int m, int iterTime,int range)
  148. {
  149. Position* allPos=randomPosition(posNum,range);
  150. Position* cluster=(Position*)malloc(sizeof(Position)*clusterNum);
  151. double** u=init(posNum,clusterNum);
  152. for (int i = 0; i < iterTime; ++i)
  153. {
  154. updateCluster(allPos,cluster,u,posNum,clusterNum,m);
  155. updateU(allPos,cluster,u,posNum,clusterNum,m);
  156. outpuCost_fun(allPos,cluster,u,posNum,clusterNum,m);
  157. //outputU(u,posNum,clusterNum);
  158. }
  159. }
  160. int main(){
  161. fuzzy_Cmeans(100,10,3,500,500);
  162. return 0;
  163. }